From 62acbeca0a60b1504ab55f205b46b832c7d265dd Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Wed, 27 Dec 2023 11:46:31 +0530 Subject: [PATCH 001/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index d3bd1f1377..4dadb98d8f 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -70,7 +70,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20231221.053718" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From f0c9aa1ea80850f1f989cbb9da9d84868990b977 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Fri, 29 Dec 2023 11:21:41 +0600 Subject: [PATCH 002/261] CU-665: Delete temp file when video compression failed --- .../mega/privacy/android/data/facade/VideoCompressionFacade.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/src/main/java/mega/privacy/android/data/facade/VideoCompressionFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/VideoCompressionFacade.kt index bdb46bbea8..f40a00d95f 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/VideoCompressionFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/VideoCompressionFacade.kt @@ -109,6 +109,9 @@ internal class VideoCompressionFacade @Inject constructor(private val fileGatewa send(VideoCompressionState.Successful(attachment?.id)) }.onFailure { Timber.d("Video Compression Failed $it") + attachment?.let { videoAttachment -> + File(videoAttachment.newPath).takeIf { file -> file.exists() }?.delete() + } send(VideoCompressionState.Failed(attachment?.id)) } } From 6c87ef2cf1ebc4420717b2a49a0aaf61876814ea Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Fri, 29 Dec 2023 12:34:32 +0530 Subject: [PATCH 003/261] update translations --- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0b5da91781..1342a9df57 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -2510,7 +2510,7 @@ Préparation des fichiers - A été envoyé en tant que message. + A été envoyé sous forme de message. Supprimer les versions précédentes diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index eb4fadee1f..7d25f129ab 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4994,5 +4994,5 @@ 同步 - • Ad free + • 無廣告 \ No newline at end of file From d2bd997511499313ab9a1a2a579264e6b08f7521 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 2 Jan 2024 15:38:00 +1300 Subject: [PATCH 004/261] AND-17942: Fix crash secure database (cherry picked from commit a56aa5bda36e04ff71d99d272f2d9b981caaff54) --- .../android/data/database/MegaDatabase.kt | 28 +++++++++++ .../android/data/database/SQLCipherManager.kt | 40 +++++++++++++++- .../android/data/di/RoomDatabaseModule.kt | 48 ++++++++----------- .../data/repository/SyncRepositoryImplTest.kt | 10 +++- 4 files changed, 95 insertions(+), 31 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt index 120b62a6d1..dee84760cc 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt @@ -1,10 +1,13 @@ package mega.privacy.android.data.database +import android.content.Context import androidx.room.AutoMigration import androidx.room.Database +import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase +import androidx.sqlite.db.SupportSQLiteOpenHelper import mega.privacy.android.data.database.dao.ActiveTransferDao import mega.privacy.android.data.database.dao.BackupDao import mega.privacy.android.data.database.dao.CameraUploadsRecordDao @@ -72,6 +75,31 @@ internal abstract class MegaDatabase : RoomDatabase() { companion object { + /** + * Init MegaDatabase + * + * @param context Context + * @param factory SupportSQLiteOpenHelper.Factory + * @param legacyDatabaseMigration LegacyDatabaseMigration + */ + fun init( + context: Context, + factory: SupportSQLiteOpenHelper.Factory, + legacyDatabaseMigration: LegacyDatabaseMigration, + ): MegaDatabase = Room.databaseBuilder( + context, + MegaDatabase::class.java, MegaDatabaseConstant.DATABASE_NAME + ).fallbackToDestructiveMigrationFrom( + *(1..66).toList().toIntArray() // allow destructive migration for version 1 to 66 + ).addMigrations(*MIGRATIONS) + .openHelperFactory( + MegaOpenHelperFactor( + factory, + legacyDatabaseMigration + ) + ) + .build() + private val MIGRATION_67_68 = object : Migration(67, 68) { override fun migrate(database: SupportSQLiteDatabase) { } diff --git a/data/src/main/java/mega/privacy/android/data/database/SQLCipherManager.kt b/data/src/main/java/mega/privacy/android/data/database/SQLCipherManager.kt index 46a37684c7..c264cabc3f 100644 --- a/data/src/main/java/mega/privacy/android/data/database/SQLCipherManager.kt +++ b/data/src/main/java/mega/privacy/android/data/database/SQLCipherManager.kt @@ -49,6 +49,36 @@ internal data class SQLCipherManager @Inject constructor( dbTemp.delete() throw IOException("Could not rename $dbFile to $dbBackup") } + } else if (state == DatabaseState.ENCRYPTED) { + // ensure passphrase is correct + var db: SQLiteDatabase? = null + try { + db = SQLiteDatabase.openOrCreateDatabase( + dbFile.absolutePath, + passphrase, + null, + ) + db.version + } finally { + db?.close() + } + } + } + + /** + * Destruct secure database if it's encrypted. + * + * @param name + */ + fun destructSecureDatabase(name: String) { + runCatching { + val dbFile = context.getDatabasePath(name) + val state = getDatabaseState(context, dbFile) + if (state != DatabaseState.UNENCRYPTED) { + dbFile.delete() + } + }.onFailure { + Timber.e(it, "Failed to destruct secure database") } } @@ -142,10 +172,16 @@ internal data class SQLCipherManager @Inject constructor( Timber.d("Passphrase file does not exist") passphraseEncryptedFile?.let { encryptedFile -> Timber.d("Writing passphrase to encrypted file") - encryptedFile.openFileOutput().use { it.write(result) } + encryptedFile.openFileOutput().use { + it.write(result) + it.flush() + } } ?: run { Timber.d("Writing passphrase to file") - passphraseFile.writeBytes(result) + passphraseFile.outputStream().use { + it.write(result) + it.flush() + } } result } diff --git a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt index a2c7621656..1c5266db07 100644 --- a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt @@ -2,9 +2,8 @@ package mega.privacy.android.data.di import android.content.Context import android.provider.Settings -import androidx.room.Room import androidx.security.crypto.EncryptedFile -import androidx.security.crypto.MasterKeys +import androidx.security.crypto.MasterKey import androidx.sqlite.db.SupportSQLiteOpenHelper import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import dagger.Module @@ -15,7 +14,6 @@ import dagger.hilt.components.SingletonComponent import mega.privacy.android.data.database.LegacyDatabaseMigration import mega.privacy.android.data.database.MegaDatabase import mega.privacy.android.data.database.MegaDatabaseConstant -import mega.privacy.android.data.database.MegaOpenHelperFactor import mega.privacy.android.data.database.SQLCipherManager import mega.privacy.android.data.database.dao.ActiveTransferDao import mega.privacy.android.data.database.dao.BackupDao @@ -42,30 +40,23 @@ internal object RoomDatabaseModule { legacyDatabaseMigration: LegacyDatabaseMigration, sqlCipherManager: SQLCipherManager, ): MegaDatabase { - val passphrase = sqlCipherManager.getPassphrase() - val isMigrateSuccess = runCatching { + return try { + val passphrase = sqlCipherManager.getPassphrase() sqlCipherManager.migrateToSecureDatabase(MegaDatabaseConstant.DATABASE_NAME, passphrase) - }.onFailure { - Timber.e(it) - }.isSuccess - val factory = if (isMigrateSuccess) { - SupportFactory(passphrase) - } else { - FrameworkSQLiteOpenHelperFactory() - } - return Room.databaseBuilder( - applicationContext, - MegaDatabase::class.java, MegaDatabaseConstant.DATABASE_NAME - ).fallbackToDestructiveMigrationFrom( - *(1..66).toList().toIntArray() // allow destructive migration for version 1 to 66 - ).addMigrations(*MegaDatabase.MIGRATIONS) - .openHelperFactory( - MegaOpenHelperFactor( - factory, - legacyDatabaseMigration - ) + MegaDatabase.init( + applicationContext, + SupportFactory(passphrase), + legacyDatabaseMigration + ) + } catch (e: Exception) { + Timber.e(e, "Failed to migrate database to secure database") + sqlCipherManager.destructSecureDatabase(MegaDatabaseConstant.DATABASE_NAME) + MegaDatabase.init( + applicationContext, + FrameworkSQLiteOpenHelperFactory(), + legacyDatabaseMigration ) - .build() + } } @Provides @@ -123,10 +114,13 @@ internal object RoomDatabaseModule { passphraseFile: File, ): EncryptedFile? { return runCatching { + val masterKey = MasterKey.Builder(context) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build() EncryptedFile.Builder( - passphraseFile, context, - MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC), + passphraseFile, + masterKey, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() }.onFailure { diff --git a/feature/sync/src/test/java/mega/privacy/android/feature/sync/data/repository/SyncRepositoryImplTest.kt b/feature/sync/src/test/java/mega/privacy/android/feature/sync/data/repository/SyncRepositoryImplTest.kt index 589f76ce81..b795927112 100644 --- a/feature/sync/src/test/java/mega/privacy/android/feature/sync/data/repository/SyncRepositoryImplTest.kt +++ b/feature/sync/src/test/java/mega/privacy/android/feature/sync/data/repository/SyncRepositoryImplTest.kt @@ -3,18 +3,20 @@ package mega.privacy.android.feature.sync.data.repository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.test.TestCoroutineScheduler import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import mega.privacy.android.data.gateway.api.MegaApiGateway +import mega.privacy.android.data.model.GlobalUpdate import mega.privacy.android.feature.sync.data.gateway.SyncGateway import mega.privacy.android.feature.sync.data.gateway.SyncStatsCacheGateway import mega.privacy.android.feature.sync.data.mapper.FolderPairMapper import mega.privacy.android.feature.sync.data.mapper.StalledIssueTypeMapper import mega.privacy.android.feature.sync.data.mapper.StalledIssuesMapper import mega.privacy.android.feature.sync.data.mapper.SyncStatusMapper +import mega.privacy.android.feature.sync.data.model.MegaSyncListenerEvent import nz.mega.sdk.MegaSyncList import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll @@ -38,6 +40,9 @@ class SyncRepositoryImplTest { private val stalledIssuesMapper: StalledIssuesMapper = StalledIssuesMapper( StalledIssueTypeMapper() ) + + private val fakeGlobalUpdatesFlow = MutableSharedFlow() + private val fakeSyncUpdatesFlow = MutableSharedFlow() private val scheduler = TestCoroutineScheduler() private val unconfinedTestDispatcher = UnconfinedTestDispatcher(scheduler) private val testScope = CoroutineScope(unconfinedTestDispatcher) @@ -45,7 +50,8 @@ class SyncRepositoryImplTest { @BeforeAll fun setUp() { - Dispatchers.setMain(unconfinedTestDispatcher) + whenever(syncGateway.syncUpdate).thenReturn(fakeSyncUpdatesFlow) + whenever(megaApiGateway.globalUpdates).thenReturn(fakeGlobalUpdatesFlow) underTest = SyncRepositoryImpl( syncGateway = syncGateway, syncStatsCacheGateway = syncStatsCacheGateway, From ba1065e5a9d21cd28e16ad4db692a78939c3414b Mon Sep 17 00:00:00 2001 From: Javier Gomez Date: Tue, 2 Jan 2024 15:39:48 +0100 Subject: [PATCH 005/261] T13954448: Turn on history clearing for one day/week/month --- .../mega/privacy/android/app/main/megachat/ChatActivity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/megachat/ChatActivity.java b/app/src/main/java/mega/privacy/android/app/main/megachat/ChatActivity.java index 1e2b068a83..02edee1c59 100644 --- a/app/src/main/java/mega/privacy/android/app/main/megachat/ChatActivity.java +++ b/app/src/main/java/mega/privacy/android/app/main/megachat/ChatActivity.java @@ -85,7 +85,6 @@ import static mega.privacy.android.app.utils.ChatUtil.showShareChatLinkDialog; import static mega.privacy.android.app.utils.ChatUtil.unlockOrientation; import static mega.privacy.android.app.utils.Constants.ACTION_CHAT_NOTIFICATION_MESSAGE; -import static mega.privacy.android.app.utils.Constants.ACTION_CHAT_OPEN; import static mega.privacy.android.app.utils.Constants.ACTION_CHAT_SHOW_MESSAGES; import static mega.privacy.android.app.utils.Constants.ACTION_CHECK_COMPRESSING_MESSAGE; import static mega.privacy.android.app.utils.Constants.ACTION_JOIN_OPEN_CHAT_LINK; @@ -1451,7 +1450,6 @@ public void showGroupOrContactInfoActivity() { Intent i = new Intent(this, chatRoom.isGroup() ? GroupChatInfoActivity.class : ContactInfoActivity.class); i.putExtra(HANDLE, chatRoom.getChatId()); - i.putExtra(ACTION_CHAT_OPEN, true); startActivity(i); } } From 54ddb05bb19c28a13e8451b6ceadad7ad377f9e8 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Wed, 3 Jan 2024 11:27:38 +0530 Subject: [PATCH 006/261] update string translations --- app/src/main/res/values-ko/strings.xml | 4 +- app/src/main/res/values-pt/strings.xml | 16 +++--- app/src/main/res/values-zh-rTW/strings.xml | 2 +- .../res/values-ko/strings_sync_feature.xml | 50 ++++++++++--------- 4 files changed, 38 insertions(+), 34 deletions(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 2c5994ce46..26fc9a70cf 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4992,7 +4992,7 @@ 우리는 우리의 서비스를 향상시키고 광고를 하기 위한 목적으로 쿠키 그리고 이와 유사한 기술을 이용합니다. MEGA를 계속 이용함으로써 당신은 우리의 개정된 [A]쿠키 정책[/A]에 동의함을 뜻합니다. - 동기화 + Sync - • Ad free + • 광고 없음 \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c9e9a795e6..8ec8cdb0e4 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -764,7 +764,7 @@ Este é o último passo para excluir a sua conta. Todos os dados armazenados na sua nuvem de arquivos serão permanentemente deletados. Por favor, digite sua senha abaixo para confirmar. - Email address verification + Comprovação de email Por favor, verifique seu e-mail para continuar. @@ -1407,9 +1407,9 @@ Mover para a Lixeira? - Do you want to move this folder to the Rubbish bin? A new folder will be automatically created for Camera uploads. + Você quer mover esta pasta para a Lixeira? Será gerada automaticamente uma nova pasta para os Uploads da câmera. - Do you want to move this folder to the Rubbish bin? A new folder will be automatically created for Media uploads. + Você quer mover esta pasta para a Lixeira? Será gerada automaticamente uma nova pasta para os Uploads de mídias. Mover para a Lixeira? @@ -2050,7 +2050,7 @@ Ativar ou desativar o controle das versões de arquivos na sua conta. \nDesativar o controle das versões de arquivos não impede que os seus contatos criem novas versões em pastas compartilhadas. - Tap, enter name or email address + Digite o nome ou email Você quer adicionar %s aos seus contatos? @@ -3076,7 +3076,7 @@ Gerenciar cookies - We use cookies and similar technologies to help us improve our services. Learn more in our [A]Cookie Policy[/A]. + Usamos cookies e tecnologias semelhantes para melhorar os nossos serviços. Para mais informações, acesse a nossa [A]Política de cookies[/A]. As configurações dos cookies não foram salvas. @@ -5388,7 +5388,7 @@ Uploads da câmera concluídos, foi feito o upload de %1$d arquivos - MEGA has limited access to the photo library and cannot back up all your photos. + O MEGA tem acesso limitado à biblioteca de fotos e não pode fazer backup de todas as suas fotos. Pressione para alterar as permissões. @@ -5458,9 +5458,9 @@ Usados por parceiros de publicidade aprovados para coletar dados sobre as suas atividades de navegação e personalizar os anúncios que você vê nos nossos serviços e em outros sites. Não aceitar esses cookies significa que você ainda verá anúncios, mas eles não personalizados. - We use cookies and similar technologies to help us improve our services and for advertising purposes. By continuing to use MEGA you agree with the terms of our updated [A]Cookie Policy[/A]. + Nós usamos cookies e tecnologias similares para melhorar os nossos serviços e com fins publicitários. Ao continuar usado o MEGA, você concorda com os termos da nossa [A]Política de cookies[/A] atualizada. Sincronizar - • Ad free + • Sem anúncios \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 7d25f129ab..25f34fafd4 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -2048,7 +2048,7 @@ 最小大小為%1$s,最大大小為%2$s。 - 刪除早於此的舊檔案 + 刪除早於此期間的舊檔案 請通知我,如果大小大於 diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index d6e2f159bc..107c003fbb 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -1,11 +1,11 @@ - 동기화 + Sync - 동기화 + Sync - 동기화 + Sync Sync [A](%1$d)[/A] @@ -14,19 +14,23 @@ To continuously sync your files and folders, allow MEGA to run in the background. - %d개의 파일 + %d file + %d files - %d개의 폴더 + %d folder + %d folders - 폴더 %1$d개 .  + %1$d folder ·  + %1$d folders ·  - 파일 %1$d개 + %1$d file + %1$d files Sync options @@ -53,17 +57,17 @@ To back up your files, MEGA needs access to the files and folders in this device. Your data is always safe with us. - 계속 + Continue - 나중에 + Not now All files access Battery optimization - 취소 + Cancel - 허가 + Allow Allow MEGA to read, modify or delete all files on this device. @@ -75,33 +79,33 @@ Device folder - MEGA 폴더 + MEGA folder Sync type - 일시정지 중 + Paused Syncing… - 실패 + Failed Synced Device folder - MEGA 폴더 + MEGA folder Issues info - 일시정지 + Pause Run - 제거 + Remove - 와이파이 또는 모바일 데이터 + Wi-Fi or mobile data - 와이파이 전용 + Wi-Fi only You will need to set up a local folder on your\ndevice that would pair with a chosen folder on\nyour Cloud Drive. @@ -141,7 +145,7 @@ Last plus one - 폴더 + Folders Issues (%d) @@ -151,11 +155,11 @@ Start sync - 빈 폴더 + Empty folder - 폴더 선택 + Select folder - 선택 + Select A single file or folder had an issue that needs a user decision to solve From 3b0442c54078fcd6e8204043794535889023b7e9 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Wed, 3 Jan 2024 14:58:36 +0800 Subject: [PATCH 007/261] TRAN-306: Fix crash TransfersManagement.tryToStartForegroundService --- .../app/globalmanagement/TransfersManagement.kt | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/TransfersManagement.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/TransfersManagement.kt index dfefd4bc9f..1c1f878514 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/TransfersManagement.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/TransfersManagement.kt @@ -370,17 +370,11 @@ class TransfersManagement @Inject constructor( */ private fun tryToStartForegroundService(vararg intents: Intent) { val active = - ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast( - Lifecycle.State.STARTED - ) - val shouldStartForeground = - Build.VERSION.SDK_INT < Build.VERSION_CODES.S || active //starting with Android 12 only active apps can startForegroundService - - intents.forEach { - if (shouldStartForeground) { + ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) + //starting with Android 12 only active apps can startForegroundService + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || active) { + intents.forEach { context.startForegroundService(it) - } else { - context.startService(it) } } } From 81c260e358ce25d1c8a6db639c199d840ac7cd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20G=C3=B3mez=20Mart=C3=ADn?= Date: Wed, 3 Jan 2024 23:35:24 +1300 Subject: [PATCH 008/261] T13954448: Turn on history clearing for one day/week/month --- .../presentation/chat/list/ChatListBottomSheetDialogFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt index d68d7c6d9f..0b706f7fda 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt @@ -150,7 +150,6 @@ class ChatListBottomSheetDialogFragment : BottomSheetDialogFragment() { } else { Intent(context, GroupChatInfoActivity::class.java).apply { putExtra(Constants.HANDLE, chatId) - putExtra(Constants.ACTION_CHAT_OPEN, true) } } startActivity(intent) From b247266404d2eaf96e61bf173cf7b5405c018dc7 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Thu, 4 Jan 2024 12:34:47 +0530 Subject: [PATCH 009/261] update string translations --- app/src/main/res/values-ar/strings.xml | 8 ++++---- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 8 ++++---- app/src/main/res/values-th/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- 17 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 8c4fdadd9e..4df7a7bde3 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1484,7 +1484,7 @@ ملف مشارك جديد - طلب جهة اتصال جديد + طلب تواصل جديد مسح سجلات المحادثة @@ -1991,7 +1991,7 @@ %1$d طلب تواصل قيد الانتظار - طلب جهة اتصال جديد + طلب تواصل جديد [B]لا يوجد[/B][A] عمليات تراسل جارية[/A] @@ -2358,7 +2358,7 @@ [A]تذكير: [/A][B]%s [/B][C]أرسل لك طلب تواصل.[/C] - تم الغاء طلب الاتصال + تم الغاء طلب التواصل [A]%s [/A][B]ألغى طلب التواصل.[/B] @@ -6164,5 +6164,5 @@ مزامنة - •  خالي من الإعلانات + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c9e0245eec..1ef45552e2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5228,5 +5228,5 @@ Synchronisierung - • Werbefrei + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 74fd4a4abc..c49856f031 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5462,5 +5462,5 @@ Sincronizar - • Sin anuncios + • Ad-free \ 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 1342a9df57..bd3aec55c5 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5462,5 +5462,5 @@ Synchronisations - • Sans publicité + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index bf8d611ac7..11b8dfd99a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4994,5 +4994,5 @@ Sinkronkan - • Ad free + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8ea3e6be3c..fedc2b33e7 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5462,5 +5462,5 @@ Sincronizza - • Senza pubblicità + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8a80684e4d..7b72e1944c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4994,5 +4994,5 @@ 同期 - • 広告なし + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 26fc9a70cf..3696adcbd1 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4994,5 +4994,5 @@ Sync - • 광고 없음 + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 97ef7a0851..4027e06b42 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5228,5 +5228,5 @@ Synchroniseren - • Reclame vrij + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 7cf79a475e..b97c8228eb 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5696,5 +5696,5 @@ Sync - - Bez reklam + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 8ec8cdb0e4..55fe3c730e 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5462,5 +5462,5 @@ Sincronizar - • Sem anúncios + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index bab022ce28..707dc5359e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5462,5 +5462,5 @@ Sincronizează - •  Fără reclame + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 334b9b970f..97ffc9b9f7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1766,7 +1766,7 @@ Низкое Среднее Высокое - Оригинал + Исходное Пропущенный звонок @@ -3525,7 +3525,7 @@ [B]Недавние[/B] действия скрыты - Оригинальное качество + Исходное качество Отпечаток пальца @@ -5568,7 +5568,7 @@ Растянуть - Оригинал + Исходное Обнаружение медиа в подпапках @@ -5696,5 +5696,5 @@ Синхронизация - • Без рекламы + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 5311b5aeca..8a66a7eb77 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4994,5 +4994,5 @@ ซิงค์ - • ไม่มีโฆษณา + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 13a95ce757..2d8af87ce4 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4994,5 +4994,5 @@ Đồng bộ - • Ad free + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 08d6009930..80c9390301 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4994,5 +4994,5 @@ 同步 - • 无广告 + • Ad-free \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 25f34fafd4..4d938a5476 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4994,5 +4994,5 @@ 同步 - • 無廣告 + • Ad-free \ No newline at end of file From 8b5600c0b420a9fc8015ff0ffa444577e29fc9b5 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Thu, 4 Jan 2024 17:59:10 +0530 Subject: [PATCH 010/261] update string translations --- app/src/main/res/values-ar/strings.xml | 10 ++++++++++ app/src/main/res/values-de/strings.xml | 10 ++++++++++ app/src/main/res/values-es/strings.xml | 10 ++++++++++ app/src/main/res/values-fr/strings.xml | 10 ++++++++++ app/src/main/res/values-in/strings.xml | 10 ++++++++++ app/src/main/res/values-it/strings.xml | 10 ++++++++++ app/src/main/res/values-ja/strings.xml | 10 ++++++++++ app/src/main/res/values-ko/strings.xml | 10 ++++++++++ app/src/main/res/values-nl/strings.xml | 10 ++++++++++ app/src/main/res/values-pl/strings.xml | 10 ++++++++++ app/src/main/res/values-pt/strings.xml | 10 ++++++++++ app/src/main/res/values-ro/strings.xml | 10 ++++++++++ app/src/main/res/values-ru/strings.xml | 10 ++++++++++ app/src/main/res/values-th/strings.xml | 10 ++++++++++ app/src/main/res/values-vi/strings.xml | 10 ++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 10 ++++++++++ app/src/main/res/values-zh-rTW/strings.xml | 10 ++++++++++ 17 files changed, 170 insertions(+) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 4df7a7bde3..417011a1c6 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6165,4 +6165,14 @@ مزامنة • Ad-free + + دعوة لاجتماع + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1ef45552e2..a12ffe6d09 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5229,4 +5229,14 @@ Synchronisierung • Ad-free + + Einladung zu einem Meeting + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index c49856f031..be77cd75b0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5463,4 +5463,14 @@ Sincronizar • Ad-free + + Invitación a una reunión + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$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 bd3aec55c5..162c054afe 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5463,4 +5463,14 @@ Synchronisations • Ad-free + + Invitation à une réunion + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 11b8dfd99a..7fdfc09349 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4995,4 +4995,14 @@ Sinkronkan • Ad-free + + Undangan rapat + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index fedc2b33e7..091df753d8 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5463,4 +5463,14 @@ Sincronizza • Ad-free + + Invito al meeting + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 7b72e1944c..13bbd4b6d1 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4995,4 +4995,14 @@ 同期 • Ad-free + + ミーティングへの招待 + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3696adcbd1..491563d4ed 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4995,4 +4995,14 @@ Sync • Ad-free + + 회의 초대 + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4027e06b42..66976a2aca 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5229,4 +5229,14 @@ Synchroniseren • Ad-free + + Uitnodiging voor vergadering + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b97c8228eb..43addc04a2 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5697,4 +5697,14 @@ Sync • Ad-free + + Zaproszenie na spotkanie + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 55fe3c730e..59308ed847 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5463,4 +5463,14 @@ Sincronizar • Ad-free + + Meeting invite + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 707dc5359e..5372e88524 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5463,4 +5463,14 @@ Sincronizează • Ad-free + + Invitație la o întâlnire + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 97ffc9b9f7..6f18af20cf 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5697,4 +5697,14 @@ Синхронизация • Ad-free + + Приглашение на встречу + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 8a66a7eb77..db969d1e92 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4995,4 +4995,14 @@ ซิงค์ • Ad-free + + ขอเชิญประชุม + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 2d8af87ce4..c28a64a8a1 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4995,4 +4995,14 @@ Đồng bộ • Ad-free + + Meeting invite + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 80c9390301..643512f4dd 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4995,4 +4995,14 @@ 同步 • Ad-free + + 会议邀请 + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 4d938a5476..5e1dbd9eb3 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4995,4 +4995,14 @@ 同步 • Ad-free + + 會議邀請 + + %1$s is inviting you to a MEGA meeting + + Meeting name: %1$s + + Meeting link: %1$s + + Date and time: %1$s \ No newline at end of file From a5a43646008df50beff24cf5fc6942fe55dbef22 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Fri, 5 Jan 2024 03:41:11 +1300 Subject: [PATCH 011/261] Task/pre release/v11.3 --- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index afa547f9c1..c0f150908d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -81,7 +81,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "34.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20231227.045555-rel" +extra["megaSdkVersion"] = "20240104.132107-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index a8647d3230..7277cce99e 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit a8647d3230132f28770d39a7c4566b501730ce5c +Subproject commit 7277cce99e356d385f03ba40f14c090cd1bc76ac From 510932b14238da17c7ba9f4834d9debdb78b1d9f Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Thu, 11 Jan 2024 06:33:23 +0800 Subject: [PATCH 012/261] Correct the version name and update strings --- app/src/main/res/values-ar/strings.xml | 52 ++++++++------- app/src/main/res/values-de/strings.xml | 44 ++++++++----- app/src/main/res/values-es/strings.xml | 45 ++++++++----- app/src/main/res/values-fr/strings.xml | 30 ++++++--- app/src/main/res/values-in/strings.xml | 41 ++++++++---- app/src/main/res/values-it/strings.xml | 42 ++++++++----- app/src/main/res/values-ja/strings.xml | 36 +++++++---- app/src/main/res/values-ko/strings.xml | 44 ++++++++----- app/src/main/res/values-nl/strings.xml | 44 ++++++++----- app/src/main/res/values-pl/strings.xml | 42 ++++++++----- app/src/main/res/values-pt/strings.xml | 43 ++++++++----- app/src/main/res/values-ro/strings.xml | 50 +++++++++------ app/src/main/res/values-ru/strings.xml | 36 +++++++---- app/src/main/res/values-th/strings.xml | 45 ++++++++----- app/src/main/res/values-vi/strings.xml | 73 +++++++++++++--------- app/src/main/res/values-zh-rCN/strings.xml | 34 +++++++--- app/src/main/res/values-zh-rTW/strings.xml | 43 ++++++++----- app/src/main/res/values/strings.xml | 12 +++- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- sdk/src/main/jni/megachat/sdk | 2 +- 21 files changed, 502 insertions(+), 260 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 417011a1c6..5ad0a47193 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1357,7 +1357,7 @@ جاري الاتصال… - %s مدعو مسبقاً. راجع طلباتك قد الانتظار. + %s was already invited. Check your pending requests. اذا أخطأت بكتابة بريدك الالكتروني، قم بتصحيحه ثم اضغط على [A]إعادة الارسال[A]. @@ -1514,7 +1514,7 @@ ادع أصدقائك واحصل على مكافآت - %1$s من مساحة التخزين لكل دعوة. صالحة لمدة 365 يوم. + %1$s of storage for each invitation. Valid for 365 days. %1$s من مساحة التخزين. صالحة لمدة 365 يوم. @@ -1544,7 +1544,7 @@ تنطبق مكافأة التخزين المجانية على الدعوات الجديدة فقط وحين يتم تثبيت تطبيق ميغا للهاتف المحمول MEGA Mobile أو تطبيق ميغا للحاسب المكتبي MEGA Desktop App. - تم ارسال الدعوة + Invitation sent عنوان البريد الإلكتروني غير صحيح @@ -1675,7 +1675,7 @@ لم يتم حذف رمز الإستجابة السريعة بسبب خطأ. يرجى المحاولة مرة أخرى. - تم ارسال الدعوة + Invitation sent تمت دعوة المستخدم وسيظهر في قائمة جهات الاتصال الخاصة بك بمجرد قبول الدعوة. @@ -1689,7 +1689,7 @@ تم تنزيل ملف رمز الاستجابة السريعة QR الى %s - لم يتم إرسال الدعوة + Invitation not sent رمز الاستجابة السريعة QR أو رابط جهة الاتصال غير صالح. يرجى إعادة قراءة رمز صالح او ادخال رابط صالح. @@ -1789,7 +1789,7 @@ %s تيرا بايت بالثانية - ميغابايب + ميغابايت %1$d نسخة @@ -3735,7 +3735,7 @@ لقد قمت بالفعل بدعوة %1$s - تم إرسال الدعوة. انظر الطلبات المرسلة. + Invitation sent. See Sent requests. الملف متاح بدون اتصال @@ -3935,11 +3935,11 @@ إلغاء عمليات التراسل - سيتم إلغاء التحويلات التي لم تتم معالجتها بعد. + سيتم إلغاء عمليات تراسل المعطيات التي لم تتم معالجتها بعد. تابع - تم الغاء عمليات التراسلé + تم الغاء عمليات تراسل المعطيات عناصر مكررة @@ -5205,12 +5205,8 @@ أنضم إلى الاجتماع - %1$d طلب دعوة تم إرساله.  - %1$d طلب دعوة تم إرساله.  - %1$d طلبي دعوة تم إرسالهما.  - %1$d طلبات دعوة تم إرسالهم.  - %1$d طلب دعوة تم إرسالهم,  - %1$d طلب دعوة تم إرسالهم.  + %1$d invitation sent.  + %1$d invitations sent.  @@ -5373,7 +5369,7 @@ التكرار - إرسال دعوة للتقويم + Send calendar invitation إضافة وصف @@ -5619,7 +5615,7 @@ • نسخ احتياطية تلقائية - •  ترجيع لمدة تصل إلى 90 يومًا على برو لايت Pro Lite وما يصل إلى 180 يومًا على برو Pro I و II و III (قريبًا) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • جدولة سلة المحذوفات بين 7 أيام و 10 سنوات @@ -5917,7 +5913,7 @@ يمكنك عرض أو إلغاء أو تعديل أي تكرار لاجتماع متكرر من خلال النقر على النقاط الثلاث على اليمين وتحديد [A]التكرارات[/A]. - أرسل دعوة تقويم بالبريد الإلكتروني إلى المشاركين حتى يتمكنوا من إضافة الاجتماع إلى التقويم الخاص بهم. + Email a calendar invitation to participants so they can add the meeting to their calendars. تم تحديث الاجتماع @@ -6084,7 +6080,7 @@ اكتملت عمليات ترفيعات الكاميرا، وتم ترفيع %1$d ملف - تتمتع ميغا MEGA بوصول محدود إلى مكتبة الصور ولا يمكنها عمل نسخة احتياطية لجميع صورك. + MEGA has limited access to your photo library and cannot back up all your photos. انقر لتغيير الأذونات. @@ -6164,9 +6160,9 @@ مزامنة - • Ad-free + • Ad free - دعوة لاجتماع + MEGA meeting invitation %1$s is inviting you to a MEGA meeting @@ -6175,4 +6171,18 @@ Meeting link: %1$s Date and time: %1$s + + انضم جميع المشاركين المدعوين إلى المكالمة + + لا يوجد أحد في غرفة الانتظار + + اتصل + + ليس في المكالمة + + جار الاتصال… + + لا يوجد رد + + اتصل بالجميع \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a12ffe6d09..593dd9a803 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1420,7 +1420,7 @@ Der kostenlose Bonusspeicherplatz wird nur bei neuen Einladungen und bei Installation einer MEGA-Mobil-App oder der MEGA-Desktop-App gewährt. - Einladung versandt + Einladung gesendet Die E-Mail-Adresse hat ein falsches Format @@ -1539,7 +1539,7 @@ Fehler beim Löschen des QR-Codes. - Einladung versandt + Einladung gesendet Der Benutzer wurde eingeladen und erscheint nach Annahme der Einladung in Ihrer Kontaktliste. @@ -1553,7 +1553,7 @@ Der QR-Code wurde nach %s heruntergeladen - Einladung nicht versandt + Einladung nicht gesendet Link ungültig. Bitte scannen oder öffnen Sie einen gültigen Link. @@ -3363,7 +3363,7 @@ Sie haben %1$s bereits eingeladen - Einladung versandt. Siehe Gesendete Anfragen. + Einladung gesendet. Siehe Gesendete Anfragen. Datei offline verfügbar @@ -4469,8 +4469,8 @@ Meeting beitreten - %1$d Einladung versendet.  - %1$d Einladungen versendet.  + %1$d Einladung gesendet.  + %1$d Einladungen gesendet.  @@ -4767,7 +4767,7 @@ • Automatische Backups - • Rewind – bis zu 90 Tage für Pro Lite und bis zu 180 Tage für Pro I, II und III (demnächst) + • Rewind – bis zu 90 Tage für Pro Lite und bis zu 180 Tage für Pro I, II und III • Planmäßige Leerung des Papierkorbs – Intervall 7 Tage bis 10 Jahre @@ -5009,7 +5009,7 @@ Sie können alle Termine eines wiederkehrenden Meetings ansehen, absagen oder bearbeiten, indem Sie die drei Punkte auf der rechten Seite antippen und [A]Termine[/A] auswählen. - Senden Sie per E-Mail eine Kalendereinladung an die Teilnehmer, damit diese das Meeting in ihrem Kalender speichern können. + Senden Sie per E-Mail eine Kalendereinladung an die Teilnehmer, damit diese das Meeting in ihren Kalender übernehmen können. Meeting aktualisiert @@ -5156,7 +5156,7 @@ Kamera-Uploads abgeschlossen, %1$d Dateien hochgeladen - MEGA hat nur eingeschränkten Zugriff auf die Fotobibliothek und kann nicht alle Ihre Fotos sichern. + MEGA hat nur eingeschränkten Zugriff auf Ihre Fotobibliothek und kann daher nicht alle Ihre Fotos sichern. Antippen, um die Berechtigungen zu ändern. @@ -5228,15 +5228,29 @@ Synchronisierung - • Ad-free + • Werbefrei - Einladung zu einem Meeting + Einladung zu einem MEGA-Meeting - %1$s is inviting you to a MEGA meeting + %1$s lädt Sie zu einem MEGA-Meeting ein - Meeting name: %1$s + Name des Meetings: %1$s - Meeting link: %1$s + Meetinglink: %1$s - Date and time: %1$s + Datum und Uhrzeit: %1$s + + Alle eingeladenen Teilnehmer sind der Konferenz beigetreten + + Der Warteraum ist leer + + Anrufen + + Nicht in Konferenz + + Verbinde… + + Keine Antwort + + Alle anrufen \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index be77cd75b0..c4dbd05c95 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -203,7 +203,7 @@ Recientes - Media uploads + Subidas multimedia Sin conexión @@ -1273,7 +1273,7 @@ Conectando… - %s ya ha sido invitado. Consulta tus invitaciones pendientes. + %s was already invited. Check your pending requests. Si has escrito mal tu dirección de correo electrónico, corrígela y pulsa en [A]Reenviar[A]. @@ -1421,7 +1421,7 @@ Invita a tus amigos y gana bonos - %1$s de almacenamiento por cada invitación. Válido durante 365 días. + %1$s of storage for each invitation. Valid for 365 days. %1$s de almacenamiento. Válido durante 365 días. @@ -1451,7 +1451,7 @@ Bono de almacenamiento gratuito aplicable solo a usuarios nuevos que instalen la aplicación móvil o de escritorio de MEGA. - Invitación enviada + Invitation sent Correo electrónico no válido @@ -1573,7 +1573,7 @@ No se ha podido eliminar el código QR. Inténtalo de nuevo. - Invitación enviada + Invitation sent El usuario ha sido invitado y aparecerá en tu lista de contactos en cuanto acepte la invitación. @@ -1587,7 +1587,7 @@ El código QR se ha descargado en %s - Invitación no enviada + Invitation not sent El código QR o el enlace de contacto no son válidos. Intenta escanear un código válido o abrir un enlace válido. @@ -3456,7 +3456,7 @@ Ya has invitado a %1$s - Se ha enviado la invitación. Ver las solicitudes enviadas. + Invitation sent. See Sent requests. Archivo disponible sin conexión @@ -4653,9 +4653,8 @@ Unirse a la reunión - Se ha enviado %1$d invitación.  - Se han enviado %1$d de invitaciones.  - Se han enviado %1$d invitaciones.  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4776,7 +4775,7 @@ Repetir - Enviar invitación al evento + Send calendar invitation Añadir descripción @@ -4980,7 +4979,7 @@ • Backups automáticos - • Rebobinado hasta 90 días en Pro Lite y hasta 180 días en Pro I, II y III (próximamente) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • Limpieza automática de la papelera entre 7 días y 10 años @@ -5236,7 +5235,7 @@ Puedes ver, cancelar o editar cualquier evento de una reunión periódica tocando los tres puntos a la derecha y seleccionando [A]Eventos[/A]. - Envía por correo electrónico una invitación a los participantes para que puedan añadir la reunión a sus calendarios. + Email a calendar invitation to participants so they can add the meeting to their calendars. Reunión actualizada @@ -5388,7 +5387,7 @@ Subidas de la cámara completadas, %1$d archivos subidos - MEGA tiene acceso limitado a la biblioteca de fotos y no puede hacer un backup de todas tus fotos. + MEGA has limited access to your photo library and cannot back up all your photos. Pulsa para cambiar los permisos. @@ -5462,9 +5461,9 @@ Sincronizar - • Ad-free + • Ad free - Invitación a una reunión + MEGA meeting invitation %1$s is inviting you to a MEGA meeting @@ -5473,4 +5472,18 @@ Meeting link: %1$s Date and time: %1$s + + Todos los participantes invitados se han unido a la llamada + + No hay nadie en la sala de espera + + Llamar + + Fuera de llamada + + Llamando… + + Sin respuesta + + Llamar a todos \ 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 162c054afe..8f137e0874 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -4980,7 +4980,7 @@ • Sauvegardes automatiques - • Retour en arrière jusqu\’à 90 jours pour Pro Lite et jusqu\’à 180 jours pour Pro I, II et III (offert bientôt) + • Retour en arrière jusqu\’à 90 jours pour Pro Lite et jusqu\’à 180 jours pour Pro I, II et III • Programmation du vidage de la corbeille entre 7 jours et 10 ans. @@ -5388,7 +5388,7 @@ Téléversements de l’appareil photo terminés, %1$d fichiers téléversés - MEGA a un accès limité à la photothèque et ne peut pas sauvegarder toutes vos photos. + MEGA a un accès limité à votre photothèque et ne peut pas sauvegarder toutes vos photos. Toucher pour changer les autorisations. @@ -5462,15 +5462,29 @@ Synchronisations - • Ad-free + • Sans publicité - Invitation à une réunion + Invitation à une réunion sur MEGA - %1$s is inviting you to a MEGA meeting + %1$s vous invite à une réunion sur MEGA - Meeting name: %1$s + Nom de la réunion : %1$s - Meeting link: %1$s + Lien de la réunion : %1$s - Date and time: %1$s + Date et heure : %1$s + + Tous les participants invités se sont joints à l’appel + + La salle d’attente est vide + + Appeler + + Hors appel + + Appel… + + Pas de réponse + + Appel général \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 7fdfc09349..2e8a2de463 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -1217,7 +1217,7 @@ Menghubungkan… - %s sudah diundang. Konsultasikan permintaan anda yang tertunda. + %s was already invited. Check your pending requests. Jika anda salah mengeja alamat e-mail, perbaiki dan ketuk [A]Kirim Ulang[A]. @@ -1359,7 +1359,7 @@ Undang teman dan dapatkan hadiah - %1$s penyimpanan untuk setiap undangan. Berlaku selama 365 hari. + %1$s of storage for each invitation. Valid for 365 days. %1$spenyimpanan. Berlaku selama 365 hari. @@ -1389,7 +1389,7 @@ Bonus penyimpanan gratis hanya berlaku untuk undangan baru dan di mana Aplikasi Seluler MEGA atau Aplikasi Desktop MEGA diinstal. - Undangan terkirim + Invitation sent Alamat email salah format @@ -1505,7 +1505,7 @@ Kode QR tidak dihapus karena kesalahan. Tolong, coba lagi. - Undangan terkirim + Invitation sent Pengguna telah diundang dan akan muncul di daftar kontak anda setelah diterima. @@ -1519,7 +1519,7 @@ Kode QR telah diunduh ke %s - Undangan tidak terkirim + Invitation not sent Kode QR atau tautan kontak tidak valid. Coba pindai kode yang valid atau untuk membuka tautan yang valid. @@ -3270,7 +3270,7 @@ Anda sudah mengundang %1$s - Undangan terkirim. Lihat Permintaan terkirim. + Invitation sent. See Sent requests. File tersedia Offline @@ -4285,7 +4285,8 @@ Gabung rapat - %1$d permintaan undangan dikirim.  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4378,7 +4379,7 @@ Berulang - Kirim undangan kalender + Send calendar invitation Tambah deskripsi @@ -4554,7 +4555,7 @@ • Cadangan otomatis - •   Putar mundur hingga 90 hari di Pro Lite dan hingga 180 hari pada Pro I, II, dan III (segera hadir) + •   Putar balik hingga 90 hari di Pro Lite dan hingga 180 hari pada Pro I, II, dan III • Jadwalkan pembersihan tempat sampah antara 7 hari dan 10 tahun @@ -4782,7 +4783,7 @@ Anda dapat melihat, membatalkan, atau mengedit kejadian rapat berulang dengan mengetuk tiga titik di sebelah kanan dan memilih [A]Kejadian[/A]. - Kirimkan undangan kalender melalui email kepada peserta sehingga mereka dapat menambahkan rapat ke kalender mereka. + Email a calendar invitation to participants so they can add the meeting to their calendars. Rapat diperbarui @@ -4924,7 +4925,7 @@ Unggahan kamera selesai, %1$d file diunggah - MEGA has limited access to the photo library and cannot back up all your photos. + MEGA has limited access to your photo library and cannot back up all your photos. Ketuk untuk mengubah izin. @@ -4994,9 +4995,9 @@ Sinkronkan - • Ad-free + • Ad free - Undangan rapat + MEGA meeting invitation %1$s is inviting you to a MEGA meeting @@ -5005,4 +5006,18 @@ Meeting link: %1$s Date and time: %1$s + + Semua peserta yang diundang telah bergabung dalam panggilan tersebut + + There is no one in the waiting room + + Panggilan + + Tidak sedang menelepon + + Panggilan… + + Tidak ada respon + + Hubungi semua \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 091df753d8..6dab8012bc 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -1273,7 +1273,7 @@ Connessione in corso… - %s è già stato invitato. Consulta le tue richieste in sospeso. + %s ha già ricevuto un tuo invito. Consulta le tue richieste in sospeso. Se hai scritto male il tuo indirizzo e-mail, correggilo e poi tocca su [A]Reinvia[A]. @@ -3456,7 +3456,7 @@ Hai già invitato %1$s - Richiesta inviata. Vedi le Richieste inviate. + Invito spedito. Vedi le Richieste inviate. File disponibile offline @@ -4653,9 +4653,9 @@ Unisciti al meeting - %1$d richiesta di invito spedita.  - %1$d di richieste di invito spedite.  - %1$d richieste di invito spedite.  + %1$d invito spedito.  + %1$d di inviti spediti.  + %1$d inviti spediti.  @@ -4776,7 +4776,7 @@ Evento - Invia invito per calendario + Spedisci invito per il calendario Aggiungi descrizione @@ -4980,7 +4980,7 @@ • Backup automatici - • Ripristina fino a 90 giorni su Pro Lite e fino a 180 giorni su Pro I, II, e III (in arrivo) + • Ripristina fino a 90 giorni su Pro Lite e fino a 180 giorni su Pro I, II, e III • Pulizia regolare del Cestino programmabile tra 7 giorni e 10 anni @@ -5388,7 +5388,7 @@ Caricamenti da fotocamera completati, %1$d file caricati - MEGA ha accesso limitato alla Galleria e non può effettuare il backup di tutte le tue foto. + MEGA ha accesso limitato alla tua Galleria e non può effettuare il backup di tutte le tue foto. Tocca per cambiare i permessi. @@ -5462,15 +5462,29 @@ Sincronizza - • Ad-free + • Senza pubblicità - Invito al meeting + Invito al meeting MEGA - %1$s is inviting you to a MEGA meeting + %1$s ti sta invitando ad un meeting MEGA - Meeting name: %1$s + Nome del meeting: %1$s - Meeting link: %1$s + Link del meeting: %1$s - Date and time: %1$s + Data e ora: %1$s + + Tutti i partecipanti invitati si sono uniti alla chiamata + + Non c\’è nessuno nella sala d\’attesa + + Chiama + + Non nella chiamata + + Chiamata in corso… + + Nessuna risposta + + Chiama tutti \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 13bbd4b6d1..396db20924 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1217,7 +1217,7 @@ 接続中… - %sさんはすでに招待されました。あなたの保留中の要求を確認してください。 + %sさんはすでに招待されました。保留中の要求を確認してください。 メールアドレスのスペルを間違った場合、それを修正して[A]再送信[A]をタップしてください。 @@ -1389,7 +1389,7 @@ 新規ご招待かつ、MEGAモバイルアプリかMEGAデスクトップアプリをインストールした場合に限り、無料ストレージボーナスが適用されます。 - 招待状が送信されました + 招待状が送られました メールアドレスの形式が間違っています @@ -1505,7 +1505,7 @@ エラーによりQRコードは削除されません。もう一度やり直してください。 - 招待状が送信されました + 招待状が送られました そのユーザーさんは招待済みで、受け入れられ次第すぐにあなたの連絡先リストに表示されます。 @@ -1519,7 +1519,7 @@ QRコードが%sにダウンロードされました - 招待状は未送信です + 招待状が送信されませんでした QRコードまたは連絡先リンクが無効です。有効なコードをスキャンするか、有効なリンクを開いてみてください。 @@ -4554,7 +4554,7 @@ • 自動バックアップ - • Pro Liteでは最大90日、Pro I、II、IIIでは最大180日巻き戻し(近日公開予定) + • Pro Liteでは最大90日、Pro I、II、IIIでは最大180日巻き戻し • ごみ箱を空にするのを7日から10年の間でスケジュールする @@ -4994,15 +4994,29 @@ 同期 - • Ad-free + • 広告 なし - ミーティングへの招待 + MEGAミーティングへの招待 - %1$s is inviting you to a MEGA meeting + %1$sさんがMEGAミーティングに招待しています - Meeting name: %1$s + ミーティング名:%1$s - Meeting link: %1$s + ミーティングリンク:%1$s - Date and time: %1$s + 日付と時刻:%1$s + + 招待された参加者全員が通話に参加しました + + 待合室に誰もいません + + 通話 + + 通話中ではありません + + 通話中… + + 応答なし + + 全員と通話 \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 491563d4ed..151cf66ca9 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1217,7 +1217,7 @@ 연결중… - %s님이 이미 초대되었습니다. 보류중인 요청을 참조하세요. + %s님이 이미 초대되었습니다. 보류중인 요청을 확인하세요. 만약 이메일 주소를 잘못 입력하였다면, 수정하고 [A]재발송[A]을 탭하세요. @@ -1389,7 +1389,7 @@ 무료 저장소 보너스는 새 초대에만 적용되며 MEGA 모바일 앱 또는 MEGA 데스크톱 앱이 설치되어야 합니다. - 초대를 발송하였습니다 + 초대장 발송됨 이메일 주소 형식이 이상합니다 @@ -1505,7 +1505,7 @@ 오류로 인해 QR 코드가 삭제되지 않았습니다. 다시 시도하세요. - 초대를 발송하였습니다 + 초대장 발송됨 이용자가 초대되었으며 수락되면 당신의 연락처 목록에 나타날 것입니다. @@ -1519,7 +1519,7 @@ QR 코드가 %s에 다운로드되었습니다 - 초대가 발송되지 않았습니다 + 초대장 발송되지 않음 QR 코드 또는 연락처 링크가 잘못 되었습니다. 올바른 코드를 스캔하거나 올바른 링크를 여세요. @@ -3270,7 +3270,7 @@ 당신은 이미 %1$s님을 초대하였습니다 - 초대 발송됨. 보낸 요청을 보세요. + 초대장 발송됨. 보낸 요청을 보세요. 파일을 오프라인에서 이용할 수 있음 @@ -4285,7 +4285,7 @@ 회의 참여 - %1$d개의 초대 요청이 발송 되었습니다.  + %1$d개의 초대장 발송됨.  @@ -4378,7 +4378,7 @@ 되풀이 - 달력 초대 보내기 + 일정 초대장 보내기 설명 추가 @@ -4554,7 +4554,7 @@ • 자동 백업 - • Pro Lite는 최대 90일, Pro I, II, 그리고 III은 최대 180일 되돌리기 기능 (출시 예정) + • Pro Lite는 최대 90일, Pro I, II, 그리고 III은 최대 180일 되돌리기 • 7일과 10년 사이의 휴지통 비우기 예약 @@ -4782,7 +4782,7 @@ 반복 회의의 되풀이 항목의 오른쪽의 점 3개를 탭하고 [A]되풀이 항목[/A]을 선택하여 항목을 보거나, 취소하거나, 편집할 수 있습니다. - 참여자들이 달력에 회의를 추가할 수 있도록 달력 초대를 이메일로 보냅니다. + 참여자들이 달력에 회의를 추가할 수 있도록 일정 초대장을 이메일로 보냅니다. 회의 수정됨 @@ -4994,15 +4994,29 @@ Sync - • Ad-free + • 광고 없음 - 회의 초대 + MEGA 회의 초대장 - %1$s is inviting you to a MEGA meeting + %1$s 님이 당신을 MEGA 회의에 초대합니다 - Meeting name: %1$s + 회의 이름: %1$s - Meeting link: %1$s + 회의 링크: %1$s - Date and time: %1$s + 날짜와 시간: %1$s + + 모든 초대된 참여자가 통화에 참여했습니다 + + 대기실에 아무도 없습니다 + + 전화 + + 통화 중 아님 + + 통화 중… + + 응답 없음 + + 모두 통화 \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 66976a2aca..06b76c6481 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1245,7 +1245,7 @@ Verbinden… - %s was al uitgenodigd. Raadpleeg uw lopende verzoeken. + %s was al uitgenodigd. Controleer uw openstaande verzoeken. Als u uw e-mailadres verkeerd hebt gespeld, corrigeer het dan en tik op [A]Opnieuw versturen[A]. @@ -1553,7 +1553,7 @@ De QR Code werd gedownload naar %s - Uitnodiging niet verzonden + Uitnodiging niet verstuurd De QR-code of contact link is ongeldig. Probeer een geldige code te scannen of een geldige link te openen. @@ -3363,7 +3363,7 @@ U heeft %1$s al uitgenodigd - Uitnodiging verstuurd. Zie verstuurde verzoeken. + Uitnodiging verstuurd. Zie Verzonden verzoeken. Bestand Offline beschikbaar @@ -4469,8 +4469,8 @@ Vergadering aansluiten - %1$d uitnodiging verzoek verstuurd.  - %1$d uitnodiging verzoeken verstuurd.   + %1$duitnodiging verstuurd.   + %1$d uitnodigingen verstuurd.  @@ -4577,7 +4577,7 @@ Herhaling - Verstuur kalender uitnodiging + Agenda-uitnodiging verzenden Omschrijving toevoegen @@ -4767,7 +4767,7 @@ • Automatische back-ups - • Spoel terug tot op 90 dagen met Pro Lite en tot op 180 dagen met Pro I, II, en III (komt binnenkort) + • Tot 90 dagen terugspoelen op Pro Lite en tot 180 dagen op Pro I, II en III • Plan het opruimen van vuilnisbakken tussen 7 dagen en 10 jaar @@ -5009,7 +5009,7 @@ U kunt elke gebeurtenis van een terugkerende vergadering bekijken, annuleren of bewerken door op de drie stippen aan de rechterkant te tikken en [A]Gebeurtenissen[/A] te selecteren. - E-mail een agenda-uitnodiging naar deelnemers zodat ze de vergadering aan hun agenda kunnen toevoegen. + E-mail een agenda-uitnodiging naar deelnemers, zodat zij de vergadering aan hun agenda kunnen toevoegen. Vergadering bijgewerkt @@ -5156,7 +5156,7 @@ Camera uploads voltooid, %1$d bestanden geüpload - MEGA heeft beperkte toegang tot de fotobibliotheek en kan geen back-up maken van al uw foto\’s. + MEGA heeft beperkte toegang tot uw fotobibliotheek en kan geen back-up maken van al uw foto\’s. Tik om de toestemmingen te wijzigen. @@ -5228,15 +5228,29 @@ Synchroniseren - • Ad-free + • Advertentie gratis - Uitnodiging voor vergadering + Uitnodiging voor MEGA-vergadering - %1$s is inviting you to a MEGA meeting + %1$s nodigt u uit voor een MEGA bijeenkomst - Meeting name: %1$s + Vergader naam: %1$s - Meeting link: %1$s + Vergader link:%1$s - Date and time: %1$s + Datum en tijd: %1$s + + Alle uitgenodigde deelnemers hebben zich bij het gesprek aangesloten + + Er is niemand in de wachtkamer + + Bellen + + Niet in oproep + + Bellen… + + Geen antwoord + + Iedereen bellen \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 43addc04a2..bc92179c33 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -1452,7 +1452,7 @@ Zaproś znajomych i odbierz nagrody - %1$s pamięci dla każdego zaproszenia. Ważny przez 365 dni. + %1$s miejsca za każde zaproszenie. Ważność przez 365 dni. %1$s przechowywania danych. Ważny przez 365 dni. @@ -3549,7 +3549,7 @@ Zaprosiłeś już %1$s - Zaproszenie wysłane. Zobacz sekcję Wysłane żądania. + Zaproszenie wysłane. Zobacz Wysłane zaproszenia. Plik dostępny offline @@ -4837,10 +4837,10 @@ Dołącz do spotkania - %1$d zaproszenie wysłane.  - %1$d zaproszeń wysłanych.  - %1$d zaproszeń wysłanych.  - %1$d zaproszeń wysłanych.  + %1$d wysłane zaproszenie.  + %1$d wysłanych zaproszeń.  + %1$d wysłanych zaproszeń.  + %1$d wysłanych zaproszeń.  @@ -5193,7 +5193,7 @@ - Automatyczne kopie zapasowe - - Rewind do 90 dni na Pro Lite i do 180 dni na Pro I, II i III (wkrótce) + - Przewijanie do 90 dni na Pro Lite i do 180 dni na Pro I, II i III - Zaplanuj czyszczenie pojemnika na śmieci od 7 dni do 10 lat @@ -5620,7 +5620,7 @@ Przesyłanie kamery zakończone, przesłano %1$d plików - MEGA ma ograniczony dostęp do biblioteki zdjęć i nie może utworzyć kopii zapasowej wszystkich zdjęć. + MEGA has limited access to your photo library and cannot back up all your photos. Wybierz, aby zmienić uprawnienia. @@ -5696,15 +5696,29 @@ Sync - • Ad-free + • Bez reklam - Zaproszenie na spotkanie + Zaproszenie na spotkanie MEGA - %1$s is inviting you to a MEGA meeting + %1$s zaprasza na spotkanie na MEGA - Meeting name: %1$s + Nazwa spotkania: %1$s - Meeting link: %1$s + Link do spotkania: %1$s - Date and time: %1$s + Data i godzina: %1$s + + Wszyscy zaproszeni uczestnicy dołączyli do rozmowy + + W poczekalni nie ma nikogo + + Połączenie + + Nie w trakcie rozmowy + + Dzwonię… + + Brak odpowiedzi + + Zadzwoń do wszystkich \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 59308ed847..d400041f8a 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -1273,7 +1273,7 @@ Conectando… - %s já foi convidado. Consulte as suas solicitações pendentes. + %s was already invited. Check your pending requests. Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[A]. @@ -1421,7 +1421,7 @@ Convide amigos e ganhe bônus - %1$s de armazenamento por cada indicação. Válido por 365 dias. + %1$s of storage for each invitation. Valid for 365 days. %1$s de espaço de armazenamento. Válido por 365 dias. @@ -1451,7 +1451,7 @@ O bônus de armazenamento gratuito somente será concedido ao convidar novos usuários, os quais devem instalar o aplicativo do MEGA para dispositivos móveis ou para desktop. - Convite enviado + Invitation sent Formato de email incorreto @@ -1573,7 +1573,7 @@ Não foi possível deletar o código QR devido a um erro. Por favor, tente novamente. - Convite enviado + Invitation sent A solicitação de contato foi enviada e o usuário aparecerá na sua lista de contatos quando a aceitar. @@ -1587,7 +1587,7 @@ O código QR foi salvo em %s - Convite não enviado + Invitation not sent O código QR ou o link de contato é inválido. Por favor, tente escanear um código válido ou acessar um link válido. @@ -3456,7 +3456,7 @@ Você já convidou %1$s - O convite foi enviado. Ver as Solicitações enviadas. + Invitation sent. See Sent requests. Arquivo disponível offline @@ -4653,9 +4653,8 @@ Entrar na reunião - %1$d solicitaçao de contato foi enviada.  - %1$d de solicitações de contato foram enviadas.  - %1$d solicitações de contato foram enviadas.  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4776,7 +4775,7 @@ Repetir - Enviar convite de calendário + Send calendar invitation Adicionar descrição @@ -4980,7 +4979,7 @@ • Backups automáticos - • Retroceder até 90 dias com o plano Pro Lite e até 180 dias com os planos Pro I, II e III (em breve) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • Programação da limpeza da lixeira entre 7 dias e 10 anos @@ -5236,7 +5235,7 @@ Você pode visualizar, cancelar ou editar qualquer agendamento de uma reunião periódica pressionando os três pontos à direita e selecionando [A]Agendamentos[/A]. - Envie por email um convite de calendário aos participantes para que possam adicionar a reunião aos seus calendários. + Email a calendar invitation to participants so they can add the meeting to their calendars. Reunião atualizada @@ -5388,7 +5387,7 @@ Uploads da câmera concluídos, foi feito o upload de %1$d arquivos - O MEGA tem acesso limitado à biblioteca de fotos e não pode fazer backup de todas as suas fotos. + MEGA has limited access to your photo library and cannot back up all your photos. Pressione para alterar as permissões. @@ -5462,9 +5461,9 @@ Sincronizar - • Ad-free + • Ad free - Meeting invite + MEGA meeting invitation %1$s is inviting you to a MEGA meeting @@ -5473,4 +5472,18 @@ Meeting link: %1$s Date and time: %1$s + + Todos os participantes convidados entraram na chamada + + There is no one in the waiting room + + Chamar + + Fora da chamada + + Chamando… + + Não há resposta + + Chamar a todos \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 5372e88524..58d16243d2 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -1273,7 +1273,7 @@ Se conectează… - %s a fost invitat deja. Consultă cererile în așteptare. + %s a fost deja invitat. Verificați cererile în așteptare. Dacă ți-ai scris greșit adresa de e-mail, corecteaz-o și atinge [A]Retrimite[A]. @@ -1421,7 +1421,7 @@ Invită prieteni și obține recompense - %1$s spațiu de stocare pentru fiecare invitație completată. Valabili timp de 365 de zile. + %1$s spațiu de stocare pentru fiecare invitație. Valabil 365 de zile. %1$s spațiu de stocare. Valabili timp de 365 de zile. @@ -1451,7 +1451,7 @@ Bonusul pentru spațiul de stocare gratuit se aplică numai la noile invitații și în cazul în care este instalată Aplicația Mobilă MEGA sau Aplicația Desktop MEGA. - Invitație trimisă + Invitația a fost trimisă Adresa de e-mail este malformată @@ -1573,7 +1573,7 @@ Codul QR nu a fost șters din cauza unei erori. Te rugăm să încerci din nou. - Invitație trimisă + Invitația a fost trimisă Utilizatorul a fost invitat și va apărea în lista de contacte de îndată ce a acceptat invitația. @@ -1587,7 +1587,7 @@ Codul QR a fost descărcat în %s - Invitație netrimisă + Invitația nu a fost trimisă Codul QR sau linkul de contact este nevalid. Te rugăm să încerci să scanezi un cod valid sau să deschizi un link valid. @@ -3456,7 +3456,7 @@ Ați invitat deja pe %1$s - Invitație trimisă. Vezi Cererile trimise. + Invitație a fost trimisă. Consultați Cereri trimise. Fișier disponibil offline @@ -4653,9 +4653,9 @@ Alătură-te întâlnirii - A fost trimisă %1$d cerere de invitație.  - Au fost trimise %1$d cereri de invitație.  - Au fost trimise %1$d de cereri de invitație.  + %1$d invitație a fost trimisă.  + %1$d invitații au fost trimise.  + %1$d de invitații au fost trimise.  @@ -4980,7 +4980,7 @@ • Backupuri automate - • Derulați înapoi până la 90 de zile pe Pro Lite și până la 180 de zile pe Pro I, II și III (în curând) + • Derulați înapoi până la 90 de zile pe Pro Lite și până la 180 de zile pe Pro I, II și III • Planifică golirea coșurilor de gunoi între 7 zile și 10 ani @@ -5236,7 +5236,7 @@ Puteți vizualiza, anula sau edita orice ocurență a unei întâlniri recurente atingând cele trei puncte din dreapta și selectând [A]Ocurențe[/A]. - Trimită prin e-mail invitația pentru calendar participanților, astfel încât aceștia să poată adăuga întâlnirea în calendarele lor. + Trimiteți invitație pentru calendar participanților prin e-mail, astfel încât aceștia să poată adăuga întâlnirea în calendarele lor. Întâlnire a fost actualizată @@ -5388,7 +5388,7 @@ Încărcări cameră complete, %1$d de fișiere încărcate - MEGA are acces limitat la biblioteca foto și nu poate face copii de rezervă pentru toate fotografiile. + MEGA are acces limitat la biblioteca dvs. foto și nu poate face copii de rezervă pentru toate fotografiile. Atinge pentru a modifica permisiunile. @@ -5462,15 +5462,29 @@ Sincronizează - • Ad-free + • Fără reclame - Invitație la o întâlnire + Invitație la întâlnire MEGA - %1$s is inviting you to a MEGA meeting + %1$s vă invită la o întâlnire MEGA - Meeting name: %1$s + Numele întâlnirii: %1$s - Meeting link: %1$s + Link pentru întâlnire: %1$s - Date and time: %1$s + Data și ora: %1$s + + Toți participanții invitați s-au alăturat apelului + + Nu este nimeni în sala de așteptare + + Apelează + + Nu în apel + + Se apelează… + + Niciun răspuns + + Suna pe toți \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6f18af20cf..085e926262 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1301,7 +1301,7 @@ Соединение… - %s уже приглашён. Посмотрите отправленные запросы. + %s уже приглашён. Проверьте отправленные запросы. Если вы ввели неправильный адрес электронной почты, исправьте его и нажмите [A]«Отправить повторно»[A]. @@ -5193,7 +5193,7 @@ • Автоматическое резервное копирование - • Перемотка на период до 90 дней на Pro Lite и до 180 дней на Pro I, II и III (скоро) + • Перемотка на период до 90 дней на Pro Lite и до 180 дней на Pro I, II и III • Срок очистки корзины от 7 дней до 10 лет @@ -5485,7 +5485,7 @@ Чтобы подтвердить контакт, убедитесь, что учётные данные, которые вы видите выше, соответствуют его учётным данным. Вы можете попросить его поделиться с вами своими учётными данными. - Подтвердите учётные данные + Подтверждение учётных данных Комната ожидания @@ -5586,7 +5586,7 @@ Облачный диск пуст - Отметить как прочитанное + Отметить как подтверждённые Проверены @@ -5620,7 +5620,7 @@ Загрузка из камеры завершена, загружено %1$d файла - MEGA имеет ограниченный доступ к библиотеке фотографий и не может создавать резервные копии всех ваших фотографий. + MEGA имеет ограниченный доступ к вашей библиотеке фотографий и не может создавать резервные копии всех ваших фотографий. Нажмите, чтобы изменить разрешения. @@ -5696,15 +5696,29 @@ Синхронизация - • Ad-free + • Без рекламы - Приглашение на встречу + Приглашения на встречу MEGA - %1$s is inviting you to a MEGA meeting + %1$s приглашает вас на MEGA-встречу - Meeting name: %1$s + Название встречи: %1$s - Meeting link: %1$s + Ссылка на встречу: %1$s - Date and time: %1$s + Дата и время: %1$s + + Все приглашённые участники присоединились к звонку + + В комнате ожидания никого нет + + Позвонить + + Не в звонке + + Вызов… + + Не отвечает + + Позвонить всем \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index db969d1e92..9154d88013 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -585,9 +585,9 @@ อัปโหลดอย่างไร - เปิดใช้งานการอัปโหลดสื่อสำรอง + เปิดใช้งานการอัปโหลดสื่อจากโฟลเดอร์อื่น - ปิดใช้งานการอัปโหลดสื่อสำรอง + ปิดใช้งานการอัปโหลดสื่อจากโฟลเดอร์อื่น เลือกโฟลเดอร์ @@ -1217,7 +1217,7 @@ กำลังเชื่อมต่อ… - %s ได้รับเชิญไปแล้ว พิจารณาคำขอที่รอดำเนินการของคุณ + %s was already invited. Check your pending requests. หากคุณสะกดอีเมลผิด ให้แก้ไขแล้วแตะ[A]ส่งใหม่[A] @@ -1359,7 +1359,7 @@ เชิญเพื่อนและรับรางวัล - รับพื้นที่เก็บข้อมูล %1$s ทุกครั้งเมื่อชวนเพื่อนสร้างรายได้ มีอายุใช้งาน 365 วัน + %1$s of storage for each invitation. Valid for 365 days. พื้นที่เก็บข้อมูล %1$s มีอายุใช้งาน 365 วัน @@ -1389,7 +1389,7 @@ โบนัสพื้นที่เก็บข้อมูลฟรี เฉพาะคำเชิญใหม่และติดตั้งแอป MEGA บนมือถือหรือแอป MEGA เดสก์ทอปเท่านั้น - ส่งคำเชิญแล้ว + Invitation sent ที่อยู่อีเมลมีรูปแบบไม่ถูกต้อง @@ -1505,7 +1505,7 @@ คิวอาร์โค้ดไม่ถูกลบเนื่องจากข้อผิดพลาด กรุณาลองอีกครั้ง - ส่งคำเชิญแล้ว + Invitation sent ได้เชิญผู้ใช้แล้ว และจะปรากฏในรายชื่อผู้ติดต่อของคุณเมื่ออีกฝ่ายกดยอมรับ @@ -1519,7 +1519,7 @@ ดาวน์โหลดคิวอาร์โค้ดไปที่ %s แล้ว - ยังไม่ได้ส่งคำเชิญ + Invitation not sent คิวอาร์โค้ดหรือรายชื่อผู้ติดต่อไม่ถูกต้อง ลองสแกนโค้ดที่ถูกต้องหรือเปิดลิงก์ที่ถูกต้องอีกครั้ง @@ -3270,7 +3270,7 @@ คุณเคยเชิญ %1$s แล้ว - ส่งคำเชิญแล้ว ดูได้ที่คำขอที่ส่งแล้ว + Invitation sent. See Sent requests. ไฟล์พร้อมใช้งานออฟไลน์แล้ว @@ -4285,7 +4285,8 @@ เข้าร่วมการประชุม - ส่งคำเชิญ %1$d รายการแล้ว  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4378,7 +4379,7 @@ กิจวัตร - ส่งไปคำเชิญปฏิทิน + Send calendar invitation เพิ่มคำอธิบาย @@ -4554,7 +4555,7 @@ • ตั้งค่าการสำรองข้อมูลอัตโนมัติได้ - • ใช้ฟีเจอร์ย้อนกลับไฟล์ได้ โดย Pro Lite ย้อนกลับได้ถึง 90 วัน ส่วน Pro I, II และ III ย้อนกลับได้ถึง 180 วัน (จะมาในเร็ว ๆ นี้) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • สร้างกำหนดการล้างถังขยะได้ตั้งแต่ 7 วันถึง 10 ปี @@ -4782,7 +4783,7 @@ คุณสามารถดู ยกเลิก หรือแก้ไขการประชุมแบบเป็นประจำได้โดยแตะที่จุดสามจุดทางด้านขวาและเลือก [A]เหตุการณ์[/A] - ส่งอีเมลคำเชิญในปฏิทินไปที่ผู้เข้าร่วมเพื่อให้สามารถเพิ่มการประชุมลงในปฏิทินได้ + Email a calendar invitation to participants so they can add the meeting to their calendars. อัปเดตการประชุมแล้ว @@ -4924,7 +4925,7 @@ การอัปโหลดจากกล้องเสร็จสมบูรณ์ มี %1$d ไฟล์ที่อัปโหลดแล้ว - MEGA ถูกจำกัดการเข้าถึงไลบรารีรูปภาพของคุณและไม่สามารถสำรองรูปภาพทั้งหมดของคุณได้ + MEGA has limited access to your photo library and cannot back up all your photos. แตะเพื่อเปลี่ยนการอนุญาต @@ -4994,9 +4995,9 @@ ซิงค์ - • Ad-free + • Ad free - ขอเชิญประชุม + MEGA meeting invitation %1$s is inviting you to a MEGA meeting @@ -5005,4 +5006,18 @@ Meeting link: %1$s Date and time: %1$s + + ทุกคนที่ถูกเชิญมา ได้เข้าร่วมสายครบแล้ว + + ไม่มีใครอยู่ในห้องนั่งรอ + + โทร + + ไม่อยู่ในสาย + + กำลังโทร… + + ไม่รับสาย + + โทรหาทั้งหมด \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index c28a64a8a1..0b00615ae7 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -127,7 +127,7 @@ Đăng nhập - Email + Địa chỉ email Mật khẩu @@ -746,7 +746,7 @@ Đây là bước cuối cùng để hoàn tất việc xóa bỏ tài khoản. Bạn sẽ mất hoàn toàn tất cả dữ liệu bạn đã lưu trên ổ mây. Để tiến hành, xin nhập mật khẩu vào dưới đây. - Email address verification + Xác thực địa chỉ email Xin kiểm tra hộp thư e-mail để thục hiện bước kế tiếp. @@ -1217,7 +1217,7 @@ Đang kết nối… - %s đã được mời rồi. Xem lại các lời yêu cầu đang chờ. + %s was already invited. Check your pending requests. Nếu địa chỉ e-mail bị viết sai, sửa lại cho đúng và chạm vào [A]Gửi lại[A]. @@ -1345,9 +1345,9 @@ Chuyển vào Thùng Rác? - Do you want to move this folder to the Rubbish bin? A new folder will be automatically created for Camera uploads. + Bạn có muốn di chuyển thư mục này vào Thùng Rác không? Một thư mục mới sẽ được tự động tạo ra cho Đăng tải camêra. - Do you want to move this folder to the Rubbish bin? A new folder will be automatically created for Media uploads. + Bạn có muốn di chuyển thư mục này vào Thùng Rác không? Một thư mục mới sẽ được tự động tạo ra cho Đăng tải phương tiện. Bỏ vào Thùng Rác? @@ -1359,7 +1359,7 @@ Mời bạn bè tham gia và nhận thưởng - %1$s vào không gian lưu trữ cho mỗi lần mời. Hạn dùng là 365 ngày. + %1$s of storage for each invitation. Valid for 365 days. %1$s vào không gian lưu trữ. Hạn dùng là 365 ngày. @@ -1389,9 +1389,9 @@ Phần thưởng không gian lưu trữ miễn phí chỉ có áp dụng cho những lời mời mới và khi App MEGA cho Di Động hoặc App MEGA cho Máy Tính được cài đặt. - Lời mời đã gửi đi + Invitation sent - Email address is malformed + Địa chỉ email không đúng cú pháp Sau khi cài đặt MEGA trên máy tính, bạn sẽ nhận được thêm %1$s vào không gian lưu trữ, có hạn sử dụng là 365 ngày. MEGA còn có apps dành cho Windows, macOS và đa số các máy Linux distros. @@ -1505,7 +1505,7 @@ Không xoá được mã ảnh QR vì xảy ra lỗi. Xin thử lại. - Lời mời đã gửi đi + Invitation sent Đối tượng đã được mời và sẽ xuất hiện trong sổ liên lạc sau khi họ chấp nhận lời mời. @@ -1519,7 +1519,7 @@ Mã QR đã được tải xuống vào vị trí %s - Lời mời chưa được gửi + Invitation not sent Mã QR hoặc đường liên kết tên liên lạc không hợp lệ. Xin thử quét mã khác hoặc đường liên kết phù hợp. @@ -1960,7 +1960,7 @@ Kích hoạt hoặc tắt tính năng ghi nhật ký phiên bản tệp tin cho toàn bộ tài khoản.\nTắt đi tính năng ghi nhật ký phiên bản sẽ không ngăn cản các tên liên lạc trong tài khoản của bạn tạo ra phiên bản mới của thư mục chia sẻ chung. - Tap, enter name or email address + Chạm để nhập tên hay địa chỉ email Thêm %s vào sổ liên lạc? @@ -2920,7 +2920,7 @@ Quản lý cookies - Chúng tôi sử dụng cookies và các công nghệ tương tự để giúp chúng tôi cải thiện dịch vụ của mình. Tìm hiểu thêm về [A]Chính Sách Cookie[/A] của chúng tôi. + Chúng tôi sử dụng cookies và các công nghệ tương tự để giúp chúng tôi cải thiện dịch vụ của mình. Tìm hiểu thêm về [A]Chính Sách Cookie[/A] của chúng tôi. Cài Đặt Cookie chưa được lưu lại. @@ -3270,7 +3270,7 @@ Bạn đã gửi cho %1$s rồi - Lời mời đã được gửi. Xem các yêu cầu gửi đi. + Invitation sent. See Sent requests. Tệp đã được lưu về Ngoại Tuyến @@ -4285,7 +4285,8 @@ Tham gia cuộc họp - %1$d yêu cầu lời mời đã được gửi.  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4378,7 +4379,7 @@ Tái diễn - Gửi thư mời lịch + Send calendar invitation Thêm miêu tả @@ -4554,7 +4555,7 @@ • Sao lưu dự phòng tự động - • Tua lại phiên bản lên đến 90 ngày với hạng Pro Lite và đến 180 ngày với hạng Pro I, II, và III (sớm có mặt) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • Lên lịch dọn dẹp thùng rác từ 7 ngày đến 10 năm @@ -4782,7 +4783,7 @@ Bạn có thể xem qua, hủy bỏ hoặc chỉnh sửa bất kỳ thời điểm tái diễn nào của cuộc họp định kỳ bằng cách chạm vào dấu ba chấm ngay bên phải, sau đó chọn [A]Thời điểm tái diễn[/A]. - Gửi email lời mời lịch hẹn cho những người tham gia biết và thêm cuộc họp vào lịch của họ. + Email a calendar invitation to participants so they can add the meeting to their calendars. Cuộc họp đã được cập nhật @@ -4924,7 +4925,7 @@ Đăng tải camêra hoàn tất, %1$d tệp tin đã được tải lên - MEGA has limited access to the photo library and cannot back up all your photos. + MEGA has limited access to your photo library and cannot back up all your photos. Chạm để đổi quyền hạn. @@ -4972,21 +4973,21 @@ Cuộc gọi này đang được ghi lại - By staying in the call you give permission to be recorded. The recording is only stored on the device of the person who records it. + Bằng cách tiếp tục tham gia cuộc gọi là bạn có cho phép được ghi âm và hình. Bản ghi chỉ được lưu trữ trong thiết bị của người ghi. OK, hiểu rồi Rời khỏi cuộc gọi - [A]Learn more[/A] + [A]Tìm hiểu thêm[/A] - %1$s started recording + %1$s đã bắt đầu ghi âm hình - %1$s stopped recording + %1$s đã chấm dứt ghi âm hình Thư Viện Phim Ảnh - Cookies Quảng Cáo + Cookies Quảng Cáo Được sử dụng bởi các đối tác quảng cáo đã được phê duyệt của chúng tôi để thu thập dữ liệu về các hoạt động duyệt web của bạn và tùy chỉnh quảng cáo bạn thấy trên các dịch vụ của chúng tôi và trên các trang web khác. Không chấp nhận các cookies này có nghĩa là bạn vẫn sẽ thấy quảng cáo nhưng nội dung sẽ không liên quan. @@ -4994,15 +4995,29 @@ Đồng bộ - • Ad-free + • Không có quảng cáo - Meeting invite + MEGA meeting invitation - %1$s is inviting you to a MEGA meeting + %1$s mời bạn tham gia một cuộc họp MEGA - Meeting name: %1$s + Tên cuộc họp: %1$s - Meeting link: %1$s + Đường liên kết cuộc họp: %1$s - Date and time: %1$s + Ngày và giờ: %1$s + + Tất cả thành viên được mời đã tham gia vào cuộc gọi + + Không có ai ở trong phòng chờ + + Gọi + + Ở ngoài cuộc gọi + + Đang gọi… + + Không có phản hồi + + Gọi tất cả \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 643512f4dd..4d7f2b224d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -3270,7 +3270,7 @@ 您已经邀请了%1$s - 已发送邀请。查看已发送的请求。 + 邀请已发送。请查看已发送的请求。 文件可离线使用 @@ -4285,7 +4285,7 @@ 加入会议 - 已发送%1$d个邀请请求。  + %1$d邀请已发送。  @@ -4554,7 +4554,7 @@ • 自动备份 - • Pro Lite最多可回溯90天,Pro I、II和III最多可回溯180天(即将推出) + • Pro Lite最多可还原90天,Pro I、II和III最多可还原180天 • 安排垃圾桶清理工作7天至10年 @@ -4924,7 +4924,7 @@ 相机上传完成,%1$d个文件已上传 - MEGA对照片库的访问权限有限,无法备份您的所有照片。 + MEGA对您的照片库的访问权限有限,无法备份您的所有照片。 点按以更改权限。 @@ -4994,15 +4994,29 @@ 同步 - • Ad-free + •无 广告  - 会议邀请 + MEGA会议邀请 - %1$s is inviting you to a MEGA meeting + %1$s正在邀请您参加MEGA会议 - Meeting name: %1$s + 会议名称:%1$s - Meeting link: %1$s + 会议链接:%1$s - Date and time: %1$s + 日期和时间:%1$s + + 所有受邀的参与者都已加入通话 + + 等候室里没有人 + + 通话 + + 未在通话中 + + 正在通话… + + 无应答 + + 给所有人通话 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5e1dbd9eb3..8d65710fa4 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1217,7 +1217,7 @@ 正在連線⋯ - %s已經被邀請了。請與他聯絡以確認成為聯絡人。 + %s was already invited. Check your pending requests. 如果您拼錯您的電子郵件地址,請更正它並點擊[A]重新發送[A]。 @@ -1359,7 +1359,7 @@ 邀請朋友以獲得獎勵 - 每邀請1個可獲得%1$s儲存空間。有效期為365天。 + %1$s of storage for each invitation. Valid for 365 days. %1$s儲存空間。有效期限365天。 @@ -1519,7 +1519,7 @@ 二維條碼已下載到%s - 邀請未發送 + Invitation not sent 二維條碼或聯絡人連結無效。請嘗試掃描有效二維條碼或開啟有效連結。 @@ -3270,7 +3270,7 @@ 您已邀請過%1$s - 已發送邀請。查看已發送請求。 + Invitation sent. See Sent requests. 檔案可離線使用 @@ -4285,7 +4285,8 @@ 加入會議 - 已發送%1$d個邀請請求。  + %1$d invitation sent.  + %1$d invitations sent.  @@ -4554,7 +4555,7 @@ • 自動備份 - • Pro Lite最多可回溯90天,Pro I、II和III最多可回溯180天(即將推出) + • Rewind up to 90 days on Pro Lite and up to 180 days on Pro I, II, and III • 垃圾筒清理排程7天至10年 @@ -4782,7 +4783,7 @@ 您現在可以點選右側的三個小圓點並選擇[A]事件[/A]來查看、取消、或編輯週期性會的任何事件。 - 透過電子郵件發送行事曆邀請給與會者,以便他們可以將會議加到他們的行事曆。 + 透過電子郵件向與會者發送行事曆邀請,以便他們可以將會議加到行事曆中。 會議已更新 @@ -4924,7 +4925,7 @@ 相機上傳已完成,%1$d個檔案已上傳 - MEGA對相簿的存取權限有限,無法備份您所的有照片。 + MEGA has limited access to your photo library and cannot back up all your photos. 點選以更改權限。 @@ -4994,15 +4995,29 @@ 同步 - • Ad-free + • 無 廣告  - 會議邀請 + MEGA meeting invitation - %1$s is inviting you to a MEGA meeting + %1$s正在邀請你參加MEGA會議 - Meeting name: %1$s + 會議名稱:%1$s - Meeting link: %1$s + 會議連結:%1$s - Date and time: %1$s + 日期和時間:%1$s + + 所有受邀參與者都加入了通話 + + 等候室裡沒有人 + + 通話 + + 不在通話中 + + 正在撥打⋯ + + 沒有回應 + + 與所有人通話 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e98999c945..847df600bd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4487,12 +4487,18 @@ Couldn’t copy %1$d item Couldn’t copy %1$d items - + Copied %1$d item,  Copied %1$d items,  - + couldn’t copy %1$d item couldn’t copy %1$d items @@ -5156,7 +5162,7 @@ Camera uploads complete, %1$d files uploaded - MEGA has limited access to the photo library and cannot back up all your photos. + MEGA has limited access to your photo library and cannot back up all your photos. Tap to change permissions. diff --git a/build.gradle.kts b/build.gradle.kts index 68a419011e..3c7846a736 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "<11.4>" +extra["appVersion"] = "11.4" // Sdk and tools extra["compileSdkVersion"] = 34 diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index a8647d3230..076d12cbb1 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit a8647d3230132f28770d39a7c4566b501730ce5c +Subproject commit 076d12cbb158f6fe20ba4f610c249bcc54334dea diff --git a/sdk/src/main/jni/megachat/sdk b/sdk/src/main/jni/megachat/sdk index ad72670c99..4150da6a0a 160000 --- a/sdk/src/main/jni/megachat/sdk +++ b/sdk/src/main/jni/megachat/sdk @@ -1 +1 @@ -Subproject commit ad72670c99469144f27a00778dbbf6607bdea763 +Subproject commit 4150da6a0ac006039d2bf1eec88b62f304804645 From ed00f1830f3a15ecbc4dc525bf5f843aa19358ca Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Thu, 11 Jan 2024 07:20:26 +0800 Subject: [PATCH 013/261] Update the megaSdkVersion --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3c7846a736..e7d9db5fa0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -81,7 +81,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "34.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240105.141212-dev" +extra["megaSdkVersion"] = "20240110.231623-rel" //JDK and Java Version extra["jdk"] = "17" From 45cac48452176a050d7a5a942bb535b946762738 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Thu, 11 Jan 2024 07:53:52 +0800 Subject: [PATCH 014/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index cc850cbbbc..4ee8c2cec7 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -70,7 +70,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240110.220050" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 47309899ec24ad8e7f999ee2717703b6caa39b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Wed, 17 Jan 2024 16:55:35 +1300 Subject: [PATCH 015/261] T14123137, T14123138 & T14123043 Txt files are not listed in Documents --- .../fragments/homepage/documents/DocumentsViewModel.kt | 6 +++--- .../android/app/presentation/search/SearchActivity.kt | 2 +- .../android/app/presentation/search/SearchFragment.kt | 4 ++-- .../search/mapper/EmptySearchViewMapper.kt | 10 +++++----- .../presentation/search/mapper/SearchFilterMapper.kt | 4 ++-- .../presentation/search/view/SearchFilterChipsView.kt | 4 ++-- .../search/mapper/EmptySearchViewMapperTest.kt | 2 +- .../search/mapper/SearchFilterMapperTest.kt | 2 +- build.gradle.kts | 2 +- .../data/mapper/search/SearchCategoryIntMapper.kt | 2 +- .../android/data/mapper/search/SearchCategoryMapper.kt | 2 +- .../android/data/repository/SearchRepositoryImpl.kt | 2 +- .../data/mapper/search/SearchCategoryIntMapper.kt | 2 +- .../data/mapper/search/SearchCategoryMapperTest.kt | 2 +- .../android/domain/entity/search/SearchCategories.kt | 2 +- .../usecase/search/GetSearchCategoriesUseCaseTest.kt | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 17 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/fragments/homepage/documents/DocumentsViewModel.kt b/app/src/main/java/mega/privacy/android/app/fragments/homepage/documents/DocumentsViewModel.kt index 3f15313537..4e4e5c37c1 100644 --- a/app/src/main/java/mega/privacy/android/app/fragments/homepage/documents/DocumentsViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/fragments/homepage/documents/DocumentsViewModel.kt @@ -13,8 +13,6 @@ import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.launch -import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase -import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import mega.privacy.android.app.fragments.homepage.NodeItem import mega.privacy.android.app.fragments.homepage.TypedFilesRepository import mega.privacy.android.app.search.callback.SearchCallback @@ -22,6 +20,8 @@ import mega.privacy.android.app.utils.TextUtil import mega.privacy.android.domain.entity.SortOrder import mega.privacy.android.domain.usecase.GetCloudSortOrder import mega.privacy.android.domain.usecase.network.IsConnectedToInternetUseCase +import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase +import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import nz.mega.sdk.MegaApiJava import nz.mega.sdk.MegaCancelToken import timber.log.Timber @@ -82,7 +82,7 @@ class DocumentsViewModel @Inject constructor( cancelToken?.let { repository.getFiles( it, - MegaApiJava.FILE_TYPE_DOCUMENT, + MegaApiJava.FILE_TYPE_ALL_DOCS, sortOrder ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt index 53695bb8b5..10bfb83aeb 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt @@ -252,7 +252,7 @@ class SearchActivity : AppCompatActivity() { } else { when (selectedFilter?.filter) { SearchCategory.IMAGES -> SearchImageFilterPressedEvent - SearchCategory.DOCUMENTS -> SearchDocsFilterPressedEvent + SearchCategory.ALL_DOCUMENTS -> SearchDocsFilterPressedEvent SearchCategory.AUDIO -> SearchAudioFilterPressedEvent SearchCategory.VIDEO -> SearchVideosFilterPressedEvent else -> SearchResetFilterPressedEvent diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFragment.kt index 42c1a65c90..8d0112c74f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFragment.kt @@ -82,7 +82,6 @@ import mega.privacy.android.app.utils.MegaNodeUtil.areAllFileNodesAndNotTakenDow import mega.privacy.android.app.utils.Util import mega.privacy.android.app.utils.Util.hideKeyboard import mega.privacy.android.app.utils.displayMetrics -import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.android.data.qualifier.MegaApi import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.entity.node.NodeId @@ -91,6 +90,7 @@ import mega.privacy.android.domain.entity.search.SearchCategory import mega.privacy.android.domain.usecase.GetThemeMode import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyViewForSearch +import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.mobile.analytics.event.SearchAudioFilterPressedEvent import mega.privacy.mobile.analytics.event.SearchDocsFilterPressedEvent import mega.privacy.mobile.analytics.event.SearchImageFilterPressedEvent @@ -1191,7 +1191,7 @@ class SearchFragment : RotatableFragment() { SearchAudioFilterPressedEvent ) - SearchCategory.DOCUMENTS -> Analytics.tracker.trackEvent( + SearchCategory.ALL_DOCUMENTS -> Analytics.tracker.trackEvent( SearchDocsFilterPressedEvent ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/EmptySearchViewMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/EmptySearchViewMapper.kt index c49108d314..fba3aaeac0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/EmptySearchViewMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/EmptySearchViewMapper.kt @@ -4,11 +4,11 @@ import android.content.Context import android.content.res.Configuration import dagger.hilt.android.qualifiers.ApplicationContext import mega.privacy.android.app.R -import mega.privacy.android.app.featuretoggle.AppFeatures -import mega.privacy.android.data.qualifier.MegaApi import mega.privacy.android.domain.entity.search.SearchCategory -import mega.privacy.android.domain.entity.search.SearchCategory.* -import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase +import mega.privacy.android.domain.entity.search.SearchCategory.ALL_DOCUMENTS +import mega.privacy.android.domain.entity.search.SearchCategory.AUDIO +import mega.privacy.android.domain.entity.search.SearchCategory.IMAGES +import mega.privacy.android.domain.entity.search.SearchCategory.VIDEO import nz.mega.sdk.MegaApiJava.INVALID_HANDLE import javax.inject.Inject @@ -76,7 +76,7 @@ class EmptySearchViewMapper @Inject constructor( context.getString(R.string.search_empty_screen_no_images) ) - category == DOCUMENTS -> Pair( + category == ALL_DOCUMENTS -> Pair( R.drawable.ic_homepage_empty_document, context.getString(R.string.search_empty_screen_no_documents) ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/SearchFilterMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/SearchFilterMapper.kt index 897bb9e266..b2ac585871 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/SearchFilterMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/mapper/SearchFilterMapper.kt @@ -32,8 +32,8 @@ class SearchFilterMapper @Inject constructor( context.getString(R.string.section_images) ) - SearchCategory.DOCUMENTS -> SearchFilter( - SearchCategory.DOCUMENTS, + SearchCategory.ALL_DOCUMENTS -> SearchFilter( + SearchCategory.ALL_DOCUMENTS, context.getString(R.string.section_documents) ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchFilterChipsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchFilterChipsView.kt index bf0c15f7e0..b44771b5e0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchFilterChipsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchFilterChipsView.kt @@ -21,10 +21,10 @@ import kotlinx.coroutines.launch import mega.privacy.android.app.R import mega.privacy.android.app.presentation.search.model.SearchFilter import mega.privacy.android.app.presentation.search.model.SearchState -import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.domain.entity.search.SearchCategory import mega.privacy.android.legacy.core.ui.controls.chips.TextButtonWithIconChipForSearch +import mega.privacy.android.shared.theme.MegaAppTheme /** * Search filter chips view @@ -101,7 +101,7 @@ internal class SearchStatePreviewsProvider : PreviewParameterProvider MegaApiAndroid.FILE_TYPE_AUDIO SearchCategory.VIDEO -> MegaApiAndroid.FILE_TYPE_VIDEO - SearchCategory.DOCUMENTS -> MegaApiAndroid.FILE_TYPE_DOCUMENT + SearchCategory.ALL_DOCUMENTS -> MegaApiAndroid.FILE_TYPE_ALL_DOCS SearchCategory.IMAGES -> MegaApiAndroid.FILE_TYPE_PHOTO else -> MegaApiAndroid.FILE_TYPE_DEFAULT } diff --git a/data/src/main/java/mega/privacy/android/data/mapper/search/SearchCategoryMapper.kt b/data/src/main/java/mega/privacy/android/data/mapper/search/SearchCategoryMapper.kt index 272e5458c0..6a27d39959 100644 --- a/data/src/main/java/mega/privacy/android/data/mapper/search/SearchCategoryMapper.kt +++ b/data/src/main/java/mega/privacy/android/data/mapper/search/SearchCategoryMapper.kt @@ -18,7 +18,7 @@ internal class SearchCategoryMapper @Inject constructor() { operator fun invoke(filter: Int): SearchCategory = when (filter) { MegaApiAndroid.FILE_TYPE_AUDIO -> SearchCategory.AUDIO MegaApiAndroid.FILE_TYPE_VIDEO -> SearchCategory.VIDEO - MegaApiAndroid.FILE_TYPE_DOCUMENT -> SearchCategory.DOCUMENTS + MegaApiAndroid.FILE_TYPE_ALL_DOCS -> SearchCategory.ALL_DOCUMENTS MegaApiAndroid.FILE_TYPE_PHOTO -> SearchCategory.IMAGES else -> SearchCategory.ALL } diff --git a/data/src/main/java/mega/privacy/android/data/repository/SearchRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/SearchRepositoryImpl.kt index 1b32904fdf..27a64c218b 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/SearchRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/SearchRepositoryImpl.kt @@ -36,7 +36,7 @@ internal class SearchRepositoryImpl @Inject constructor( override fun getSearchCategories(): List = listOf( MegaApiAndroid.FILE_TYPE_DEFAULT, MegaApiAndroid.FILE_TYPE_PHOTO, - MegaApiAndroid.FILE_TYPE_DOCUMENT, + MegaApiAndroid.FILE_TYPE_ALL_DOCS, MegaApiAndroid.FILE_TYPE_AUDIO, MegaApiAndroid.FILE_TYPE_VIDEO, ).map { diff --git a/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryIntMapper.kt b/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryIntMapper.kt index 9e4c8542a3..c7fdb2d392 100644 --- a/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryIntMapper.kt +++ b/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryIntMapper.kt @@ -24,7 +24,7 @@ class SearchCategoryIntMapperTest { Arguments.of(MegaApiAndroid.FILE_TYPE_DEFAULT, SearchCategory.ALL), Arguments.of(MegaApiAndroid.FILE_TYPE_AUDIO, SearchCategory.AUDIO), Arguments.of(MegaApiAndroid.FILE_TYPE_VIDEO, SearchCategory.VIDEO), - Arguments.of(MegaApiAndroid.FILE_TYPE_DOCUMENT, SearchCategory.DOCUMENTS), + Arguments.of(MegaApiAndroid.FILE_TYPE_ALL_DOCS, SearchCategory.ALL_DOCUMENTS), Arguments.of(MegaApiAndroid.FILE_TYPE_PHOTO, SearchCategory.IMAGES), ) } \ No newline at end of file diff --git a/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryMapperTest.kt b/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryMapperTest.kt index df6ccd239e..2e8df83412 100644 --- a/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryMapperTest.kt +++ b/data/src/test/java/mega/privacy/android/data/mapper/search/SearchCategoryMapperTest.kt @@ -32,7 +32,7 @@ class SearchCategoryMapperTest { Arguments.of(SearchCategory.ALL, MegaApiAndroid.FILE_TYPE_DEFAULT), Arguments.of(SearchCategory.AUDIO, MegaApiAndroid.FILE_TYPE_AUDIO), Arguments.of(SearchCategory.VIDEO, MegaApiAndroid.FILE_TYPE_VIDEO), - Arguments.of(SearchCategory.DOCUMENTS, MegaApiAndroid.FILE_TYPE_DOCUMENT), + Arguments.of(SearchCategory.ALL_DOCUMENTS, MegaApiAndroid.FILE_TYPE_ALL_DOCS), Arguments.of(SearchCategory.IMAGES, MegaApiAndroid.FILE_TYPE_PHOTO), ) } \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/search/SearchCategories.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/search/SearchCategories.kt index cc15aec3c9..7f998d77ce 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/search/SearchCategories.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/search/SearchCategories.kt @@ -24,7 +24,7 @@ enum class SearchCategory { * * shows only documents which is matching the search keyword */ - DOCUMENTS, + ALL_DOCUMENTS, /** * AUDIO diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/GetSearchCategoriesUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/GetSearchCategoriesUseCaseTest.kt index e179862f5e..009b68c73e 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/GetSearchCategoriesUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/GetSearchCategoriesUseCaseTest.kt @@ -18,7 +18,7 @@ class GetSearchCategoriesUseCaseTest { fun `test that GetSearchCategoriesUseCase returns list of search categories`() { val expected = listOf( SearchCategory.AUDIO, - SearchCategory.DOCUMENTS + SearchCategory.ALL_DOCUMENTS ) whenever(searchRepository.getSearchCategories()).thenReturn(expected) val actual = underTest() diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index 076d12cbb1..334ffa4e1f 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit 076d12cbb158f6fe20ba4f610c249bcc54334dea +Subproject commit 334ffa4e1fc3b808d95e04ac89e03efc5d974473 From ec8698c5c717885a41fbb4c4a50b326b8ce2168e Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Mon, 22 Jan 2024 23:53:28 +1300 Subject: [PATCH 016/261] AND-18021: Add Worker pending list logs --- .../app/service/push/MegaMessageService.kt | 55 +++++++++++-------- .../app/data/extensions/WorkManager.kt | 11 +++- .../android/app/main/ManagerActivity.kt | 14 ++++- .../android/data/facade/WorkManagerFacade.kt | 29 +++++++++- .../data/gateway/WorkManagerGateway.kt | 2 +- .../repository/DefaultTransfersRepository.kt | 2 +- .../android/data/worker/NewMediaWorker.kt | 3 + .../DefaultTransfersRepositoryTest.kt | 9 +-- .../domain/repository/TransferRepository.kt | 2 +- .../downloads/StartDownloadWorkerUseCase.kt | 4 +- 10 files changed, 94 insertions(+), 37 deletions(-) diff --git a/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt b/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt index 6ee9161651..5bbc0b2cb9 100644 --- a/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt +++ b/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt @@ -1,22 +1,33 @@ package mega.privacy.android.app.service.push -import android.content.Context import androidx.work.Data import androidx.work.WorkManager -import com.google.android.gms.tasks.Task import com.google.firebase.messaging.FirebaseMessaging import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.tasks.await import mega.privacy.android.app.data.extensions.enqueuePushMessage import mega.privacy.android.app.data.extensions.enqueueUniqueWorkNewToken import mega.privacy.android.app.utils.Constants.DEVICE_ANDROID +import mega.privacy.android.domain.qualifier.ApplicationScope import timber.log.Timber -import java.util.concurrent.Executors +import javax.inject.Inject @AndroidEntryPoint class MegaMessageService : FirebaseMessagingService() { + @Inject + @ApplicationScope + lateinit var applicationScope: CoroutineScope + + @Inject + lateinit var workManager: WorkManager + override fun onDestroy() { Timber.d("onDestroy") super.onDestroy() @@ -27,15 +38,17 @@ class MegaMessageService : FirebaseMessagingService() { val workerData = remoteMessage.data.toWorkerData() - WorkManager.getInstance(this) - .enqueuePushMessage(workerData) + applicationScope.launch { + workManager.enqueuePushMessage(workerData) + } } override fun onNewToken(token: String) { Timber.d("New token: $token") - WorkManager.getInstance(this) - .enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) + applicationScope.launch { + workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) + } } /** @@ -49,28 +62,24 @@ class MegaMessageService : FirebaseMessagingService() { .build() companion object { + /** + * Mutex to avoid multiple calls to getToken. + */ + private val mutex = Mutex() + /** * Request push service token, then register it in API as an identifier of the device. - * - * @param context Context. */ @JvmStatic - fun getToken(context: Context) { + suspend fun getToken(workManager: WorkManager) { //project number from google-service.json - Executors.newFixedThreadPool(1).submit { - FirebaseMessaging.getInstance().token.addOnCompleteListener { task: Task -> - if (!task.isSuccessful) { - Timber.w("Get token failed.") - return@addOnCompleteListener - } - - // Get new Instance ID token - val token = task.result - Timber.d("Get token: $token") + mutex.withLock { + val token = FirebaseMessaging.getInstance().token.await() - WorkManager.getInstance(context) - .enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) - } + token?.let { + Timber.d("Get token succeeded") + workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) + } ?: Timber.w("Get token failed.") } } } diff --git a/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt b/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt index 42fe64361d..d55005b4e1 100644 --- a/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt +++ b/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt @@ -7,13 +7,16 @@ import androidx.work.OutOfQuotaPolicy import androidx.work.WorkManager import mega.privacy.android.app.fcm.NewTokenWorker import mega.privacy.android.app.fcm.PushMessageWorker +import mega.privacy.android.data.facade.debugWorkInfo /** * Enqueues a [PushMessageWorker] request to manage a push notification. * * @param data [Data] containing the push information. */ -fun WorkManager.enqueuePushMessage(data: Data) { +suspend fun WorkManager.enqueuePushMessage(data: Data) { + debugWorkInfo() + enqueue( OneTimeWorkRequestBuilder() .setInputData(data) @@ -28,7 +31,9 @@ fun WorkManager.enqueuePushMessage(data: Data) { * @param newToken Required token for register pushes. * @param deviceType Type of device. */ -fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) { +suspend fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) { + debugWorkInfo() + enqueueUniqueWork( NewTokenWorker.WORK_NAME, ExistingWorkPolicy.REPLACE, @@ -42,4 +47,4 @@ fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) { .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .build() ) -} \ No newline at end of file +} diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index fe0f64a68c..10f54a285d 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -66,6 +66,7 @@ import androidx.navigation.NavDestination import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment import androidx.viewpager2.widget.ViewPager2 +import androidx.work.WorkManager import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.bottomnavigation.BottomNavigationItemView @@ -83,6 +84,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.kotlin.addTo import io.reactivex.rxjava3.schedulers.Schedulers import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch @@ -300,6 +302,7 @@ import mega.privacy.android.domain.exception.QuotaExceededMegaException import mega.privacy.android.domain.exception.chat.IAmOnAnotherCallException import mega.privacy.android.domain.exception.chat.MeetingEndedException import mega.privacy.android.domain.exception.node.ForeignNodeException +import mega.privacy.android.domain.qualifier.ApplicationScope import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.usecase.GetChatRoomUseCase import mega.privacy.android.domain.usecase.chat.HasArchivedChatsUseCase @@ -452,6 +455,13 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf @Inject lateinit var syncNavigator: SyncNavigator + @Inject + lateinit var workManager: WorkManager + + @Inject + @ApplicationScope + lateinit var applicationScope: CoroutineScope + //GET PRO ACCOUNT PANEL private lateinit var getProLayout: LinearLayout private lateinit var getProText: TextView @@ -1385,7 +1395,9 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf megaApi.invalidateCache() } dbH.setInvalidateSdkCache(false) - MegaMessageService.getToken(this) + applicationScope.launch { + MegaMessageService.getToken(workManager) + } userInfoViewModel.getUserInfo() preloadPayment() megaApi.isGeolocationEnabled(this) diff --git a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt index aa03a55d45..75023e03b3 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt @@ -7,8 +7,10 @@ import androidx.work.OneTimeWorkRequest import androidx.work.PeriodicWorkRequest import androidx.work.WorkInfo import androidx.work.WorkManager +import androidx.work.WorkQuery import androidx.work.await import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.merge import mega.privacy.android.data.gateway.WorkManagerGateway @@ -41,6 +43,8 @@ internal class WorkManagerFacade @Inject constructor( ) : WorkManagerGateway { override suspend fun enqueueDeleteOldestCompletedTransfersWorkRequest() { + workManager.debugWorkInfo() + val workRequest = OneTimeWorkRequest.Builder(DeleteOldestCompletedTransfersWorker::class.java) .addTag(DeleteOldestCompletedTransfersWorker.DELETE_OLDEST_TRANSFERS_WORKER_TAG) @@ -54,7 +58,9 @@ internal class WorkManagerFacade @Inject constructor( ) } - override fun enqueueDownloadsWorkerRequest() { + override suspend fun enqueueDownloadsWorkerRequest() { + workManager.debugWorkInfo() + val request = OneTimeWorkRequest.Builder(DownloadsWorker::class.java) .addTag(DownloadsWorker.SINGLE_DOWNLOAD_TAG) .build() @@ -69,6 +75,8 @@ internal class WorkManagerFacade @Inject constructor( override suspend fun startCameraUploads() { // Check if CU periodic worker is working. If yes, then don't start a single one if (!checkWorkerRunning(CAMERA_UPLOAD_TAG)) { + workManager.debugWorkInfo() + Timber.d("No CU periodic process currently running, proceed with one time request") val cameraUploadWorkRequest = OneTimeWorkRequest.Builder( CameraUploadsWorker::class.java @@ -111,6 +119,9 @@ internal class WorkManagerFacade @Inject constructor( override suspend fun scheduleCameraUploads() { scheduleCameraUploadSyncActiveHeartbeat() + + workManager.debugWorkInfo() + // periodic work that runs during the last 10 minutes of every one hour period val cameraUploadWorkRequest = PeriodicWorkRequest.Builder( CameraUploadsWorker::class.java, @@ -139,6 +150,8 @@ internal class WorkManagerFacade @Inject constructor( * Schedule camera uploads active heartbeat worker */ private suspend fun scheduleCameraUploadSyncActiveHeartbeat() { + workManager.debugWorkInfo() + // periodic work that runs during the last 10 minutes of every half an hour period val cuSyncActiveHeartbeatWorkRequest = PeriodicWorkRequest.Builder( SyncHeartbeatCameraUploadWorker::class.java, @@ -223,3 +236,17 @@ internal class WorkManagerFacade @Inject constructor( override fun monitorDownloadsStatusInfo() = workManager.getWorkInfosByTagFlow(DownloadsWorker.SINGLE_DOWNLOAD_TAG) } + +/** + * Prints the list of pending [WorkInfo] in the log. + */ +suspend fun WorkManager.debugWorkInfo() { + getWorkInfosFlow( + WorkQuery.fromStates( + WorkInfo.State.ENQUEUED, + ) + ).firstOrNull() + ?.map { it.tags } + ?.let { Timber.d("Worker pending list: $it") } + ?: Timber.d("Worker pending list: empty") +} diff --git a/data/src/main/java/mega/privacy/android/data/gateway/WorkManagerGateway.kt b/data/src/main/java/mega/privacy/android/data/gateway/WorkManagerGateway.kt index 3099028220..7a54f513d6 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/WorkManagerGateway.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/WorkManagerGateway.kt @@ -16,7 +16,7 @@ interface WorkManagerGateway { /** * Enqueue unique work request to start download worker to monitor the download transfers as a foreground service */ - fun enqueueDownloadsWorkerRequest() + suspend fun enqueueDownloadsWorkerRequest() /** * Queue a one time work request of camera upload to upload immediately. diff --git a/data/src/main/java/mega/privacy/android/data/repository/DefaultTransfersRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/DefaultTransfersRepository.kt index 3c93dbad6b..68a04d75e7 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/DefaultTransfersRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/DefaultTransfersRepository.kt @@ -457,7 +457,7 @@ internal class DefaultTransfersRepository @Inject constructor( workerManagerGateway.enqueueDeleteOldestCompletedTransfersWorkRequest() } - override fun startDownloadWorker() { + override suspend fun startDownloadWorker() = withContext(ioDispatcher) { workerManagerGateway.enqueueDownloadsWorkerRequest() } diff --git a/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt index a8be2d1b6c..8702e2c740 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt @@ -12,6 +12,7 @@ import androidx.work.WorkManager import androidx.work.WorkerParameters import dagger.assisted.Assisted import dagger.assisted.AssistedInject +import mega.privacy.android.data.facade.debugWorkInfo import mega.privacy.android.domain.usecase.camerauploads.IsCameraUploadsEnabledUseCase import mega.privacy.android.domain.usecase.workers.StartCameraUploadUseCase import timber.log.Timber @@ -46,6 +47,8 @@ internal class NewMediaWorker @AssistedInject constructor( if (isForce || isQueuedOrRunning(workManager) ) { + workManager.debugWorkInfo() + val photoCheckBuilder = OneTimeWorkRequest.Builder(NewMediaWorker::class.java) photoCheckBuilder.setConstraints( diff --git a/data/src/test/java/mega/privacy/android/data/repository/DefaultTransfersRepositoryTest.kt b/data/src/test/java/mega/privacy/android/data/repository/DefaultTransfersRepositoryTest.kt index fa64b65144..d4a9f0602f 100644 --- a/data/src/test/java/mega/privacy/android/data/repository/DefaultTransfersRepositoryTest.kt +++ b/data/src/test/java/mega/privacy/android/data/repository/DefaultTransfersRepositoryTest.kt @@ -1087,10 +1087,11 @@ class DefaultTransfersRepositoryTest { @TestInstance(TestInstance.Lifecycle.PER_CLASS) inner class WorkerTests { @Test - fun `test that workerManagerGateway enqueueDownloadsWorkerRequest is called when startDownloadWorker is called`() { - underTest.startDownloadWorker() - verify(workerManagerGateway).enqueueDownloadsWorkerRequest() - } + fun `test that workerManagerGateway enqueueDownloadsWorkerRequest is called when startDownloadWorker is called`() = + runTest { + underTest.startDownloadWorker() + verify(workerManagerGateway).enqueueDownloadsWorkerRequest() + } @ParameterizedTest @EnumSource(WorkInfo.State::class) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/repository/TransferRepository.kt b/domain/src/main/kotlin/mega/privacy/android/domain/repository/TransferRepository.kt index 3b240407f5..cc39d38c34 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/repository/TransferRepository.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/repository/TransferRepository.kt @@ -253,7 +253,7 @@ interface TransferRepository { /** * Starts the download worker to monitor the download transfers as a foreground service */ - fun startDownloadWorker() + suspend fun startDownloadWorker() /** * Monitors transfers finished. diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadWorkerUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadWorkerUseCase.kt index a9b18d99f0..4071e7c99b 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadWorkerUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadWorkerUseCase.kt @@ -16,5 +16,5 @@ class StartDownloadWorkerUseCase @Inject constructor( * Invoke. * */ - operator fun invoke() = transferRepository.startDownloadWorker() -} \ No newline at end of file + suspend operator fun invoke() = transferRepository.startDownloadWorker() +} From 0cca6845e7fab2fa3468a3d3868379865b53e737 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Tue, 23 Jan 2024 16:52:42 +1300 Subject: [PATCH 017/261] AND-18026: Fix Non-fatal Exception: java.io.IOException --- .../app/service/push/MegaMessageService.kt | 24 ++++++++++++------- .../app/data/extensions/WorkManager.kt | 13 ++++++---- .../android/app/main/ManagerActivity.kt | 6 ++++- .../android/data/facade/WorkManagerFacade.kt | 21 ++++++++++------ .../DefaultCameraUploadRepository.kt | 4 +++- .../android/data/worker/NewMediaWorker.kt | 12 +++++++--- .../DefaultCameraUploadRepositoryTest.kt | 1 + 7 files changed, 57 insertions(+), 24 deletions(-) diff --git a/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt b/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt index 5bbc0b2cb9..ed71017a20 100644 --- a/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt +++ b/app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.tasks.await import mega.privacy.android.app.data.extensions.enqueuePushMessage import mega.privacy.android.app.data.extensions.enqueueUniqueWorkNewToken import mega.privacy.android.app.utils.Constants.DEVICE_ANDROID +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.ApplicationScope import timber.log.Timber import javax.inject.Inject @@ -28,6 +29,9 @@ class MegaMessageService : FirebaseMessagingService() { @Inject lateinit var workManager: WorkManager + @Inject + lateinit var crashReporter: CrashReporter + override fun onDestroy() { Timber.d("onDestroy") super.onDestroy() @@ -39,7 +43,7 @@ class MegaMessageService : FirebaseMessagingService() { val workerData = remoteMessage.data.toWorkerData() applicationScope.launch { - workManager.enqueuePushMessage(workerData) + workManager.enqueuePushMessage(workerData, crashReporter) } } @@ -47,7 +51,7 @@ class MegaMessageService : FirebaseMessagingService() { Timber.d("New token: $token") applicationScope.launch { - workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) + workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID, crashReporter) } } @@ -71,15 +75,19 @@ class MegaMessageService : FirebaseMessagingService() { * Request push service token, then register it in API as an identifier of the device. */ @JvmStatic - suspend fun getToken(workManager: WorkManager) { + suspend fun getToken(workManager: WorkManager, crashReporter: CrashReporter) { //project number from google-service.json mutex.withLock { - val token = FirebaseMessaging.getInstance().token.await() + runCatching { + val token = FirebaseMessaging.getInstance().token.await() - token?.let { - Timber.d("Get token succeeded") - workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID) - } ?: Timber.w("Get token failed.") + token?.let { + Timber.d("Get token succeeded") + workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID, crashReporter) + } ?: Timber.w("Get token failed.") + }.onFailure { + Timber.e(it) + } } } } diff --git a/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt b/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt index d55005b4e1..b78c8acef0 100644 --- a/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt +++ b/app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt @@ -8,14 +8,15 @@ import androidx.work.WorkManager import mega.privacy.android.app.fcm.NewTokenWorker import mega.privacy.android.app.fcm.PushMessageWorker import mega.privacy.android.data.facade.debugWorkInfo +import mega.privacy.android.domain.monitoring.CrashReporter /** * Enqueues a [PushMessageWorker] request to manage a push notification. * * @param data [Data] containing the push information. */ -suspend fun WorkManager.enqueuePushMessage(data: Data) { - debugWorkInfo() +suspend fun WorkManager.enqueuePushMessage(data: Data, crashReporter: CrashReporter) { + debugWorkInfo(crashReporter) enqueue( OneTimeWorkRequestBuilder() @@ -31,8 +32,12 @@ suspend fun WorkManager.enqueuePushMessage(data: Data) { * @param newToken Required token for register pushes. * @param deviceType Type of device. */ -suspend fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) { - debugWorkInfo() +suspend fun WorkManager.enqueueUniqueWorkNewToken( + newToken: String, + deviceType: Int, + crashReporter: CrashReporter, +) { + debugWorkInfo(crashReporter) enqueueUniqueWork( NewTokenWorker.WORK_NAME, diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 10f54a285d..d3cfa28eb2 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -302,6 +302,7 @@ import mega.privacy.android.domain.exception.QuotaExceededMegaException import mega.privacy.android.domain.exception.chat.IAmOnAnotherCallException import mega.privacy.android.domain.exception.chat.MeetingEndedException import mega.privacy.android.domain.exception.node.ForeignNodeException +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.ApplicationScope import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.usecase.GetChatRoomUseCase @@ -458,6 +459,9 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf @Inject lateinit var workManager: WorkManager + @Inject + lateinit var crashReporter: CrashReporter + @Inject @ApplicationScope lateinit var applicationScope: CoroutineScope @@ -1396,7 +1400,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } dbH.setInvalidateSdkCache(false) applicationScope.launch { - MegaMessageService.getToken(workManager) + MegaMessageService.getToken(workManager, crashReporter) } userInfoViewModel.getUserInfo() preloadPayment() diff --git a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt index 75023e03b3..0ad0c05927 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt @@ -18,6 +18,7 @@ import mega.privacy.android.data.worker.CameraUploadsWorker import mega.privacy.android.data.worker.DeleteOldestCompletedTransfersWorker import mega.privacy.android.data.worker.DownloadsWorker import mega.privacy.android.data.worker.SyncHeartbeatCameraUploadWorker +import mega.privacy.android.domain.monitoring.CrashReporter import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -40,10 +41,11 @@ private const val SCHEDULER_FLEX_INTERVAL: Long = 50 // Minutes internal class WorkManagerFacade @Inject constructor( private val workManager: WorkManager, + private val crashReporter: CrashReporter, ) : WorkManagerGateway { override suspend fun enqueueDeleteOldestCompletedTransfersWorkRequest() { - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) val workRequest = OneTimeWorkRequest.Builder(DeleteOldestCompletedTransfersWorker::class.java) @@ -59,7 +61,7 @@ internal class WorkManagerFacade @Inject constructor( } override suspend fun enqueueDownloadsWorkerRequest() { - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) val request = OneTimeWorkRequest.Builder(DownloadsWorker::class.java) .addTag(DownloadsWorker.SINGLE_DOWNLOAD_TAG) @@ -75,7 +77,7 @@ internal class WorkManagerFacade @Inject constructor( override suspend fun startCameraUploads() { // Check if CU periodic worker is working. If yes, then don't start a single one if (!checkWorkerRunning(CAMERA_UPLOAD_TAG)) { - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) Timber.d("No CU periodic process currently running, proceed with one time request") val cameraUploadWorkRequest = OneTimeWorkRequest.Builder( @@ -120,7 +122,7 @@ internal class WorkManagerFacade @Inject constructor( override suspend fun scheduleCameraUploads() { scheduleCameraUploadSyncActiveHeartbeat() - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) // periodic work that runs during the last 10 minutes of every one hour period val cameraUploadWorkRequest = PeriodicWorkRequest.Builder( @@ -150,7 +152,7 @@ internal class WorkManagerFacade @Inject constructor( * Schedule camera uploads active heartbeat worker */ private suspend fun scheduleCameraUploadSyncActiveHeartbeat() { - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) // periodic work that runs during the last 10 minutes of every half an hour period val cuSyncActiveHeartbeatWorkRequest = PeriodicWorkRequest.Builder( @@ -240,13 +242,18 @@ internal class WorkManagerFacade @Inject constructor( /** * Prints the list of pending [WorkInfo] in the log. */ -suspend fun WorkManager.debugWorkInfo() { +suspend fun WorkManager.debugWorkInfo(crashReporter: CrashReporter) { getWorkInfosFlow( WorkQuery.fromStates( WorkInfo.State.ENQUEUED, ) ).firstOrNull() ?.map { it.tags } - ?.let { Timber.d("Worker pending list: $it") } + ?.groupBy { it } + ?.mapValues { it.value.size } + ?.let { + Timber.d("Worker pending list: $it") + crashReporter.log("Worker pending list: $it") + } ?: Timber.d("Worker pending list: empty") } diff --git a/data/src/main/java/mega/privacy/android/data/repository/DefaultCameraUploadRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/DefaultCameraUploadRepository.kt index 72e3522ece..d4ea78f9f6 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/DefaultCameraUploadRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/DefaultCameraUploadRepository.kt @@ -47,6 +47,7 @@ import mega.privacy.android.domain.entity.camerauploads.CameraUploadsSettingsAct import mega.privacy.android.domain.entity.camerauploads.HeartbeatStatus import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.settings.camerauploads.UploadOption +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.repository.CameraUploadRepository import nz.mega.sdk.MegaApiJava @@ -81,6 +82,7 @@ internal class DefaultCameraUploadRepository @Inject constructor( @ApplicationContext private val context: Context, private val cameraUploadsSettingsPreferenceGateway: CameraUploadsSettingsPreferenceGateway, private val cameraUploadsStatusInfoMapper: CameraUploadsStatusInfoMapper, + private val crashReporter: CrashReporter, ) : CameraUploadRepository { override fun getInvalidHandle(): Long = megaApiGateway.getInvalidHandle() @@ -396,7 +398,7 @@ internal class DefaultCameraUploadRepository @Inject constructor( override suspend fun listenToNewMedia() { withContext(ioDispatcher) { if (isCameraUploadsEnabled() == true) { - NewMediaWorker.scheduleWork(context, false) + NewMediaWorker.scheduleWork(context, false, crashReporter) } } } diff --git a/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt index 8702e2c740..037df10ae0 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt @@ -13,6 +13,7 @@ import androidx.work.WorkerParameters import dagger.assisted.Assisted import dagger.assisted.AssistedInject import mega.privacy.android.data.facade.debugWorkInfo +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.usecase.camerauploads.IsCameraUploadsEnabledUseCase import mega.privacy.android.domain.usecase.workers.StartCameraUploadUseCase import timber.log.Timber @@ -23,6 +24,7 @@ internal class NewMediaWorker @AssistedInject constructor( @Assisted workerParams: WorkerParameters, private val isCameraUploadsEnabledUseCase: IsCameraUploadsEnabledUseCase, private val startCameraUploadUseCase: StartCameraUploadUseCase, + private val crashReporter: CrashReporter, ) : CoroutineWorker(context, workerParams) { override suspend fun doWork(): Result { runCatching { @@ -30,7 +32,7 @@ internal class NewMediaWorker @AssistedInject constructor( Timber.d("Capture new media") startCameraUploadUseCase() // it's one time job, we need to re-listen again - scheduleWork(context, true) + scheduleWork(context, true, crashReporter) } }.onFailure { Timber.e(it) @@ -41,13 +43,17 @@ internal class NewMediaWorker @AssistedInject constructor( companion object { private const val NEW_MEDIA_WORKER_TAG = "NEW_MEDIA_WORKER_TAG" - suspend fun scheduleWork(context: Context, isForce: Boolean = false) { + suspend fun scheduleWork( + context: Context, + isForce: Boolean = false, + crashReporter: CrashReporter, + ) { val workManager = WorkManager.getInstance(context.applicationContext) if (isForce || isQueuedOrRunning(workManager) ) { - workManager.debugWorkInfo() + workManager.debugWorkInfo(crashReporter) val photoCheckBuilder = OneTimeWorkRequest.Builder(NewMediaWorker::class.java) diff --git a/data/src/test/java/mega/privacy/android/data/repository/DefaultCameraUploadRepositoryTest.kt b/data/src/test/java/mega/privacy/android/data/repository/DefaultCameraUploadRepositoryTest.kt index 76d41f79b1..5f31ca251f 100644 --- a/data/src/test/java/mega/privacy/android/data/repository/DefaultCameraUploadRepositoryTest.kt +++ b/data/src/test/java/mega/privacy/android/data/repository/DefaultCameraUploadRepositoryTest.kt @@ -117,6 +117,7 @@ class DefaultCameraUploadRepositoryTest { context = mock(), cameraUploadsSettingsPreferenceGateway = cameraUploadsSettingsPreferenceGateway, cameraUploadsStatusInfoMapper = cameraUploadsStatusInfoMapper, + crashReporter = mock(), ) } From 21a8dd8da80dfdf1dfed58ad1734a2c76fadac6f Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Wed, 24 Jan 2024 09:53:09 +0800 Subject: [PATCH 018/261] Increase the version to 11.4.1 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index b8204a05ac..1a8075c00e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "11.4" +extra["appVersion"] = "11.4.1" // Sdk and tools extra["compileSdkVersion"] = 34 From d753cd6c83a64f76ec185f9889cde726223aabd9 Mon Sep 17 00:00:00 2001 From: raquelgc Date: Wed, 24 Jan 2024 13:54:59 +0100 Subject: [PATCH 019/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 14b9ba0bb9..bbbbf10fa9 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -68,7 +68,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240117.013801" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 7c82fab1ca7708c09c48bea11bdaaf6034ae012d Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Mon, 29 Jan 2024 16:52:39 +1300 Subject: [PATCH 020/261] AP-995 Fix Navigation in VPN Cross App Account Checking (T14552065) (cherry picked from commit 3f2de681bed495b5b467b7e143c22f36a11a3e48) --- .../android/app/main/ManagerActivity.kt | 7 ++++- .../mapper/ManagerRedirectIntentMapper.kt | 4 +++ .../app/presentation/login/LoginFragment.kt | 15 ++++++++++- .../presentation/openlink/OpenLinkActivity.kt | 26 +++++++++---------- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index dd89ab4caa..c162729aea 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -6025,6 +6025,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } return } else if (Constants.ACTION_SHOW_UPGRADE_ACCOUNT == intent.action) { + setIntent(intent) navigateToUpgradeAccount() return } else if (Constants.ACTION_SHOW_TRANSFERS == intent.action) { @@ -6055,7 +6056,11 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf ) { drawerLayout.closeDrawer(GravityCompat.START) } - startActivity(Intent(this, UpgradeAccountActivity::class.java)) + val isCrossAccountMatch = + intent?.getBooleanExtra(UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, false) ?: false + startActivity(Intent(this, UpgradeAccountActivity::class.java).apply { + putExtra(UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, isCrossAccountMatch) + }) myAccountInfo.upgradeOpenedFrom = MyAccountInfo.UpgradeFrom.MANAGER } diff --git a/app/src/main/java/mega/privacy/android/app/main/mapper/ManagerRedirectIntentMapper.kt b/app/src/main/java/mega/privacy/android/app/main/mapper/ManagerRedirectIntentMapper.kt index ae53b1cacc..8f721f8e2c 100644 --- a/app/src/main/java/mega/privacy/android/app/main/mapper/ManagerRedirectIntentMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/main/mapper/ManagerRedirectIntentMapper.kt @@ -9,6 +9,7 @@ import mega.privacy.android.app.presentation.extensions.serializable import mega.privacy.android.app.presentation.filelink.FileLinkComposeActivity import mega.privacy.android.app.presentation.login.LoginActivity import mega.privacy.android.app.presentation.manager.model.TransfersTab +import mega.privacy.android.app.upgradeAccount.UpgradeAccountActivity import mega.privacy.android.app.utils.Constants import mega.privacy.android.domain.entity.Feature import timber.log.Timber @@ -161,7 +162,10 @@ class ManagerRedirectIntentMapper @Inject constructor(private val activity: Acti Constants.ACTION_SHOW_UPGRADE_ACCOUNT -> Intent(activity, LoginActivity::class.java) .apply { + val isCrossAccountMatch = + intent.getBooleanExtra(UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, false) putExtra(Constants.VISIBLE_FRAGMENT, Constants.LOGIN_FRAGMENT) + putExtra(UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, isCrossAccountMatch) flags = Intent.FLAG_ACTIVITY_CLEAR_TOP action = Constants.ACTION_SHOW_UPGRADE_ACCOUNT } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt index d220fb9612..6ed4d936d0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt @@ -50,6 +50,7 @@ import mega.privacy.android.app.presentation.login.view.LoginView import mega.privacy.android.app.presentation.settings.startscreen.util.StartScreenUtil.setStartScreenTimeStamp import mega.privacy.android.app.providers.FileProviderActivity import mega.privacy.android.app.upgradeAccount.ChooseAccountActivity +import mega.privacy.android.app.upgradeAccount.UpgradeAccountActivity import mega.privacy.android.app.utils.AlertsAndWarnings.showOverDiskQuotaPaywallWarning import mega.privacy.android.app.utils.ColorUtils.getThemeColor import mega.privacy.android.app.utils.Constants @@ -557,6 +558,18 @@ class LoginFragment : Fragment() { } } + Constants.ACTION_SHOW_UPGRADE_ACCOUNT -> { + intent.action = Constants.ACTION_SHOW_UPGRADE_ACCOUNT + val isCrossAccountMatch = requireActivity().intent.getBooleanExtra( + UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, + false + ) + intent.putExtra( + UpgradeAccountActivity.IS_CROSS_ACCOUNT_MATCH, + isCrossAccountMatch + ) + } + else -> intent = refreshActivityIntent ?: handleLinkNavigation(loginActivity) } @@ -889,4 +902,4 @@ class LoginFragment : Fragment() { } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/presentation/openlink/OpenLinkActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/openlink/OpenLinkActivity.kt index d9767ecc2b..2dc759a044 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/openlink/OpenLinkActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/openlink/OpenLinkActivity.kt @@ -32,12 +32,12 @@ import mega.privacy.android.app.presentation.filelink.FileLinkComposeActivity import mega.privacy.android.app.presentation.folderlink.FolderLinkComposeActivity import mega.privacy.android.app.presentation.login.LoginActivity import mega.privacy.android.app.presentation.photos.albums.AlbumScreenWrapperActivity -import mega.privacy.android.app.upgradeAccount.UpgradeAccountActivity import mega.privacy.android.app.upgradeAccount.UpgradeAccountActivity.Companion.IS_CROSS_ACCOUNT_MATCH import mega.privacy.android.app.usecase.QuerySignupLinkUseCase import mega.privacy.android.app.utils.CallUtil import mega.privacy.android.app.utils.CallUtil.participatingInACall import mega.privacy.android.app.utils.CallUtil.showConfirmationInACall +import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.Constants.ACCOUNT_INVITATION_LINK_REGEXS import mega.privacy.android.app.utils.Constants.ACTION_CANCEL_ACCOUNT import mega.privacy.android.app.utils.Constants.ACTION_CHANGE_MAIL @@ -146,6 +146,7 @@ class OpenLinkActivity : PasscodeActivity(), MegaRequestListenerInterface, private val binding: ActivityOpenLinkBinding by lazy(LazyThreadSafetyMode.NONE) { ActivityOpenLinkBinding.inflate(layoutInflater) } + private var isCrossAccountMatch: Boolean = false /** * onCreate @@ -498,20 +499,11 @@ class OpenLinkActivity : PasscodeActivity(), MegaRequestListenerInterface, // Check if the email passed in the intent matches the one currently logged in // and make sure that the VPN app is updated to the latest version. If it's not // updated, then it will be considered as cross account match. - val isCrossAccountMatch = + isCrossAccountMatch = !isVpnAppUpdated || email == getCurrentUserEmail(forceRefresh = false) - startActivity( - Intent( - this@OpenLinkActivity, - UpgradeAccountActivity::class.java - ).apply { - putExtra( - IS_CROSS_ACCOUNT_MATCH, - isCrossAccountMatch - ) - } - ) + navigateToUpgradeAccount() + finish() } } @@ -526,6 +518,14 @@ class OpenLinkActivity : PasscodeActivity(), MegaRequestListenerInterface, } } + override fun navigateToUpgradeAccount() { + val intent = Intent(this, ManagerActivity::class.java) + intent.action = Constants.ACTION_SHOW_UPGRADE_ACCOUNT + intent.putExtra(IS_CROSS_ACCOUNT_MATCH, isCrossAccountMatch) + intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP) + startActivity(intent) + } + private fun collectFlows() { collectFlow(viewModel.state) { openLinkState: OpenLinkState -> when { From 3a2e8525f3efcd23b347d8615d2856cb3eeb78cd Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Mon, 29 Jan 2024 20:05:26 +0800 Subject: [PATCH 021/261] BAC-779: Fix Cloud Drive Not in Root Level When Clicking the Feature Again This brings back the existing behavior wherein if the User is in Cloud Drive and clicks the Cloud Drive Navigation Button again, then the Nodes are shown from the Root Level. Media Discovery is also deactivated when this happens. Furthermore, replace all null checks of MediaDiscoveryFragment with FileBrowserViewModel.isMediaDiscoveryOpen() to better determine if the User is in Media Discovery or not. --- .../android/app/main/ManagerActivity.kt | 34 +++++++++---------- .../clouddrive/FileBrowserViewModel.kt | 16 +++++++++ 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index c162729aea..40a7672bc5 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -2960,7 +2960,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf if (megaApi.rootNode != null) { if ((parentNode.handle == megaApi.rootNode?.handle || fileBrowserViewModel.state().fileBrowserHandle == -1L) - && mediaDiscoveryFragment == null + && !fileBrowserViewModel.isMediaDiscoveryOpen() ) { supportActionBar?.title = getString(R.string.section_cloud_drive) viewModel.setIsFirstNavigationLevel(true) @@ -4529,7 +4529,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf DrawerItem.CLOUD_DRIVE -> { openLinkMenuItem?.isVisible = isFirstNavigationLevel moreMenuItem.isVisible = !isFirstNavigationLevel - if (mediaDiscoveryFragment == null && isCloudAdded && fileBrowserViewModel.state().nodesList.isNotEmpty() + if (!fileBrowserViewModel.isMediaDiscoveryOpen() && isCloudAdded && fileBrowserViewModel.state().nodesList.isNotEmpty() ) { searchMenuItem?.isVisible = true } @@ -5244,16 +5244,16 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf val oldDrawerItem = drawerItem when (menuItem.itemId) { R.id.bottom_navigation_item_cloud_drive -> { - if (drawerItem === DrawerItem.CLOUD_DRIVE) { - val rootNode = megaApi.rootNode - if (rootNode == null) { - Timber.e("Root node is null") - } - if (rootNode != null && fileBrowserViewModel.state().fileBrowserHandle != INVALID_HANDLE && fileBrowserViewModel.state().fileBrowserHandle != rootNode.handle) { - fileBrowserViewModel.setFileBrowserHandle(rootNode.handle) - refreshFragment(FragmentTag.CLOUD_DRIVE.tag) + // User is in Cloud Drive. Go back to the Root Node level + if (drawerItem == DrawerItem.CLOUD_DRIVE) { + lifecycleScope.launch { + if (fileBrowserViewModel.isMediaDiscoveryOpen()) { + removeFragment(mediaDiscoveryFragment) + } + fileBrowserViewModel.goBackToRootLevel() } } else { + // User is not in Cloud Drive. Navigate to the feature drawerItem = DrawerItem.CLOUD_DRIVE setBottomNavigationMenuItemChecked(CLOUD_DRIVE_BNV) } @@ -5274,7 +5274,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf R.id.bottom_navigation_item_camera_uploads -> { // if pre fragment is the same one, do nothing. - if (oldDrawerItem !== DrawerItem.PHOTOS) { + if (oldDrawerItem != DrawerItem.PHOTOS) { drawerItem = DrawerItem.PHOTOS setBottomNavigationMenuItemChecked(PHOTOS_BNV) } @@ -5283,14 +5283,14 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf R.id.bottom_navigation_item_shared_items -> { Analytics.tracker.trackEvent(SharedItemsScreenEvent) - if (drawerItem === DrawerItem.SHARED_ITEMS) { - if (tabItemShares === SharesTab.INCOMING_TAB && incomingSharesViewModel.state().incomingHandle != INVALID_HANDLE) { + if (drawerItem == DrawerItem.SHARED_ITEMS) { + if (tabItemShares == SharesTab.INCOMING_TAB && incomingSharesViewModel.state().incomingHandle != INVALID_HANDLE) { incomingSharesViewModel.resetIncomingTreeDepth() refreshIncomingShares() - } else if (tabItemShares === SharesTab.OUTGOING_TAB && outgoingSharesViewModel.state().outgoingHandle != INVALID_HANDLE) { + } else if (tabItemShares == SharesTab.OUTGOING_TAB && outgoingSharesViewModel.state().outgoingHandle != INVALID_HANDLE) { outgoingSharesViewModel.resetOutgoingTreeDepth() refreshOutgoingShares() - } else if (tabItemShares === SharesTab.LINKS_TAB && legacyLinksViewModel.state().linksHandle != INVALID_HANDLE) { + } else if (tabItemShares == SharesTab.LINKS_TAB && legacyLinksViewModel.state().linksHandle != INVALID_HANDLE) { legacyLinksViewModel.resetLinksTreeDepth() refreshLinks() } @@ -7536,7 +7536,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf return@launch } when (drawerItem) { - DrawerItem.CLOUD_DRIVE -> if (mediaDiscoveryFragment == null) { + DrawerItem.CLOUD_DRIVE -> if (!fileBrowserViewModel.isMediaDiscoveryOpen()) { updateFabAndShow() } @@ -8222,7 +8222,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf * @return True if the current screen is MD, false otherwise. */ fun isInMediaDiscovery() = - drawerItem == DrawerItem.CLOUD_DRIVE && mediaDiscoveryFragment != null + drawerItem == DrawerItem.CLOUD_DRIVE && fileBrowserViewModel.isMediaDiscoveryOpen() /** * Create the instance of FileBackupManager diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt index bf8dc00520..c6e8a8bba3 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt @@ -369,6 +369,22 @@ class FileBrowserViewModel @Inject constructor( } } + /** + * Navigate back to the Cloud Drive Root Level hierarchy + */ + suspend fun goBackToRootLevel() { + _state.update { + it.copy( + accessedFolderHandle = null, + isMediaDiscoveryOpen = false, + isMediaDiscoveryOpenedByIconClick = false, + ) + } + getRootNodeUseCase()?.id?.longValue?.let { rootHandle -> + setFileBrowserHandle(rootHandle) + } + } + /** * Exits the Media Discovery * From 670c2e65e9bbad60effff936d32a4b51a030fadf Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Mon, 29 Jan 2024 19:46:43 +0530 Subject: [PATCH 022/261] T14557550: "New" label for notification disappears automatically after 1 seconds --- .../android/app/main/ManagerActivity.kt | 22 +++++++++---------- .../notification/view/NotificationView.kt | 22 ++++++++++++------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 40a7672bc5..3e11a13659 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -3405,15 +3405,11 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf appBarLayout.visibility = View.VISIBLE drawerItem = DrawerItem.NOTIFICATIONS setBottomNavigationMenuItemChecked(NO_BNV) - var notificationsFragment = - supportFragmentManager.findFragmentByTag(FragmentTag.NOTIFICATIONS.tag) as? NotificationsFragment - if (notificationsFragment == null) { - Timber.w("New NotificationsFragment") - notificationsFragment = NotificationsFragment.newInstance() - } else { - refreshFragment(FragmentTag.NOTIFICATIONS.tag) - } - replaceFragment(notificationsFragment, FragmentTag.NOTIFICATIONS.tag) + replaceFragmentWithBackStack( + fragmentToReplace = notificationsFragment, + newFragmentInstance = NotificationsFragment.newInstance(), + fragmentTag = FragmentTag.NOTIFICATIONS.tag, + ) setToolbarTitle() showFabButton() } @@ -4181,6 +4177,9 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf private val deviceCenterFragment: DeviceCenterFragment? get() = supportFragmentManager.findFragmentByTag(FragmentTag.DEVICE_CENTER.tag) as? DeviceCenterFragment + private val notificationsFragment: NotificationsFragment? + get() = supportFragmentManager.findFragmentByTag(FragmentTag.NOTIFICATIONS.tag) as? NotificationsFragment + private val backupsFragment: BackupsFragment? get() = supportFragmentManager.findFragmentByTag(FragmentTag.BACKUPS.tag) as? BackupsFragment @@ -4684,12 +4683,12 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf return when (item.itemId) { android.R.id.home -> { if (isFirstNavigationLevel && drawerItem != DrawerItem.SEARCH) { - if (drawerItem == DrawerItem.SYNC || drawerItem == DrawerItem.RUBBISH_BIN || drawerItem == DrawerItem.NOTIFICATIONS || drawerItem == DrawerItem.TRANSFERS) { + if (drawerItem == DrawerItem.SYNC || drawerItem == DrawerItem.RUBBISH_BIN || drawerItem == DrawerItem.TRANSFERS) { goBackToBottomNavigationItem(bottomNavigationCurrentItem) if (transfersToImageViewer) { switchImageViewerToFront() } - } else if (drawerItem == DrawerItem.DEVICE_CENTER) { + } else if (drawerItem == DrawerItem.DEVICE_CENTER || drawerItem == DrawerItem.NOTIFICATIONS) { handleSuperBackPressed() goBackToBottomNavigationItem(bottomNavigationCurrentItem) if (transfersToImageViewer) { @@ -4995,6 +4994,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf bottomNavigationCurrentItem ) } else if (drawerItem == DrawerItem.NOTIFICATIONS) { + handleSuperBackPressed() goBackToBottomNavigationItem(bottomNavigationCurrentItem) } else if (drawerItem == DrawerItem.SHARED_ITEMS) { onBackPressedInSharedItemsDrawerItem() diff --git a/app/src/main/java/mega/privacy/android/app/presentation/notification/view/NotificationView.kt b/app/src/main/java/mega/privacy/android/app/presentation/notification/view/NotificationView.kt index 9216d28a10..d3d591ab80 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/notification/view/NotificationView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/notification/view/NotificationView.kt @@ -17,11 +17,13 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.imageResource import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.Lifecycle import mega.privacy.android.app.R import mega.privacy.android.app.presentation.notification.model.Notification import mega.privacy.android.app.presentation.notification.model.NotificationState import mega.privacy.android.app.utils.StringUtils.formatColorTag import mega.privacy.android.app.utils.StringUtils.toSpannedHtmlText +import mega.privacy.android.core.ui.utils.ComposableLifecycle import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** @@ -35,10 +37,12 @@ fun NotificationView( onNotificationsLoaded: () -> Unit = {}, ) { if (state.notifications.isNotEmpty()) { - NotificationListView(modifier, + NotificationListView( + modifier, state, onClick = { notification: Notification -> onClick(notification) }, - onNotificationsLoaded = onNotificationsLoaded) + onNotificationsLoaded = onNotificationsLoaded + ) } else { NotificationEmptyView(modifier) } @@ -63,8 +67,12 @@ private fun NotificationListView( derivedStateOf { listState.layoutInfo.totalItemsCount == state.notifications.size } } - if (allItemsLoaded) { - onNotificationsLoaded() + ComposableLifecycle { event -> + if (event == Lifecycle.Event.ON_PAUSE) { + if (allItemsLoaded) { + onNotificationsLoaded() + } + } } LazyColumn(state = listState, modifier = modifier.testTag("NotificationListView")) { @@ -80,8 +88,7 @@ private fun NotificationListView( @Composable private fun NotificationEmptyView(modifier: Modifier) { val context = LocalContext.current - val isPortrait = - LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT + val isPortrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT val emptyImgResId = if (isPortrait) R.drawable.empty_notification_portrait else R.drawable.empty_notification_landscape @@ -92,8 +99,7 @@ private fun NotificationEmptyView(modifier: Modifier) { imageBitmap = ImageBitmap.imageResource(id = emptyImgResId), text = context.getString(R.string.context_empty_notifications) .formatColorTag(context, 'A', R.color.grey_900_grey_100) - .formatColorTag(context, 'B', R.color.grey_300_grey_600) - .toSpannedHtmlText() + .formatColorTag(context, 'B', R.color.grey_300_grey_600).toSpannedHtmlText() ) } From 3cbfd2e8f698c34340243713380fa7385401ed1b Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Tue, 30 Jan 2024 15:07:32 +1300 Subject: [PATCH 023/261] AP-1012: Ads url should reflect the Ads cookie status --- .../domain/usecase/advertisements/FetchAdDetailUseCase.kt | 2 +- .../domain/usecase/advertisements/FetchAdDetailsUseCaseTest.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailUseCase.kt index 91efd63981..f4689b0b6c 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailUseCase.kt @@ -42,7 +42,7 @@ class FetchAdDetailUseCase @Inject constructor( ) ) return if (isAdsCookieEnabled) { - adDetails.copy(slotId = adDetails.slotId, url = "${adDetails.url}&ads=1") + adDetails.copy(slotId = adDetails.slotId, url = "${adDetails.url}&ac=1") } else { adDetails } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailsUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailsUseCaseTest.kt index 71c02c9074..9a469df385 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailsUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/advertisements/FetchAdDetailsUseCaseTest.kt @@ -27,7 +27,7 @@ class FetchAdDetailUseCaseTest { private val slotId = "ANDFB" private val adBaseUrl = "https://megaad.nz/#z_xyz" - private val adsCookieEnabledPostfix = "&ads=1" + private val adsCookieEnabledPostfix = "&ac=1" private val fetchDetailsRequest = FetchAdDetailRequest(slotId, null) private fun initTestClass() { underTest = FetchAdDetailUseCase( From 52c4f99bbb415728261b7b32095c485c96b4584d Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Wed, 31 Jan 2024 01:46:05 +1300 Subject: [PATCH 024/261] Pre-release v11.5 --- app/src/main/res/values-ar/strings.xml | 29 +++- app/src/main/res/values-de/strings.xml | 17 ++- app/src/main/res/values-es/strings.xml | 26 +++- app/src/main/res/values-fr/strings.xml | 30 ++++- app/src/main/res/values-in/strings.xml | 14 +- app/src/main/res/values-it/strings.xml | 20 ++- app/src/main/res/values-ja/strings.xml | 14 +- app/src/main/res/values-ko/strings.xml | 14 +- app/src/main/res/values-nl/strings.xml | 17 ++- app/src/main/res/values-pl/strings.xml | 29 +++- app/src/main/res/values-pt/strings.xml | 26 +++- app/src/main/res/values-ro/strings.xml | 22 ++- app/src/main/res/values-ru/strings.xml | 35 ++++- app/src/main/res/values-th/strings.xml | 14 +- app/src/main/res/values-vi/strings.xml | 14 +- app/src/main/res/values-zh-rCN/strings.xml | 14 +- app/src/main/res/values-zh-rTW/strings.xml | 16 ++- app/src/main/res/values/strings.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../res/values-ar/strings_sync_feature.xml | 6 +- .../res/values-de/strings_sync_feature.xml | 4 +- .../res/values-es/strings_sync_feature.xml | 6 +- .../res/values-fr/strings_sync_feature.xml | 26 ++-- .../res/values-in/strings_sync_feature.xml | 6 +- .../res/values-it/strings_sync_feature.xml | 4 +- .../res/values-ja/strings_sync_feature.xml | 6 +- .../res/values-ko/strings_sync_feature.xml | 4 +- .../res/values-nl/strings_sync_feature.xml | 4 +- .../res/values-pl/strings_sync_feature.xml | 28 ++-- .../res/values-pt/strings_sync_feature.xml | 6 +- .../res/values-ro/strings_sync_feature.xml | 6 +- .../res/values-ru/strings_sync_feature.xml | 114 ++++++++-------- .../res/values-th/strings_sync_feature.xml | 4 +- .../res/values-vi/strings_sync_feature.xml | 6 +- .../values-zh-rCN/strings_sync_feature.xml | 4 +- .../values-zh-rTW/strings_sync_feature.xml | 126 +++++++++--------- .../main/res/values/strings_sync_feature.xml | 6 +- 37 files changed, 497 insertions(+), 224 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index eef50139b3..8dbc4d6e13 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6150,7 +6150,7 @@ اتصل بالجميع - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -6161,4 +6161,31 @@ Start download Always download and don’t ask again + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index d1b287ad9d..497184c25d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5226,7 +5226,7 @@ Alle anrufen - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -5237,4 +5237,19 @@ Start download Always download and don’t ask again + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 69eb699cc2..fe04661bb3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5458,15 +5458,33 @@ Llamar a todos - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA necesita acceso a tu cámara para hacer fotos y vídeos. Has denegado el acceso a tu ubicación para MEGA. Si quieres compartir tu ubicación, concede a MEGA el permiso para hacerlo. - Large download + Descarga pesada - Start download + Iniciar descarga - Always download and don’t ask again + Descargar siempre y no volver a preguntar + + + + + + + + + + + + + + + + + + \ 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 e7ce89c0aa..f6989c7f69 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5458,15 +5458,33 @@ Appel général - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + Cette appli est connectée à un autre compte MEGA.\nDéconnectez-vous de ce compte et connectez-vous avec votre compte RPV MEGA VPN. - MEGA needs access to your camera to capture photos and videos. + MEGA a besoin d’accéder à votre appareil photo pour capturer des photos et des vidéos. - You denied MEGA access to your location. If you’d like to share your location, allow MEGA permission to do so. + Vous avez refusé à MEGA l’accès à votre position. Si vous souhaitez partager votre position, autorisez MEGA à le faire. - Large download + Téléchargement volumineux - Start download + Lancer le téléchargement - Always download and don’t ask again + Toujours télécharger et ne plus demander + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index cc68b6d654..beb196eaa9 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4994,7 +4994,7 @@ Panggil semua - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA membutuhkan akses ke kamera anda untuk menangkap foto dan video. @@ -5005,4 +5005,16 @@ Start download Always download and don’t ask again + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index b80eef6876..cf48b84f57 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5458,7 +5458,7 @@ Chiama tutti - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -5469,4 +5469,22 @@ Start download Always download and don’t ask again + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 395c6097b2..7e1571345d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4994,7 +4994,7 @@ 全員と通話 - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + このアプリは別のMEGAアカウントにログインしています。\nこのアカウントからログアウトし、MEGA VPNアカウントでログインしてください MEGAは写真や動画を取得するためにカメラにアクセスする必要があります。 @@ -5005,4 +5005,16 @@ ダウンロード開始 常にダウンロードし、再度質問しない + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index a0374ea717..9884c5f6db 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4994,7 +4994,7 @@ 모두 통화 - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA는 사진과 동영상을 촬영하기 위해 당신의 카메라에 접근해야 합니다 @@ -5005,4 +5005,16 @@ Start download Always download and don’t ask again + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b315b54216..1508f651a5 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5226,7 +5226,7 @@ Iedereen bellen - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA heeft toegang tot uw camera nodig om foto\’s en video\’s vast te leggen @@ -5237,4 +5237,19 @@ Download starten Altijd downloaden en niet nogmaals vragen + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index f1b035ab0d..aa61482306 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5690,15 +5690,36 @@ Zadzwoń do wszystkich - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + Ta aplikacja jest zalogowana do innego konta MEGA. \nWyloguj się z tego konta i zaloguj się na swoje konto MEGA VPN. MEGA potrzebuje dostępu do kamery, aby robić zdjęcia i nagrywać filmy. Użytkownik odmówił firmie MEGA dostępu do swojej lokalizacji. Jeśli chcesz udostępnić swoją lokalizację, zezwól na to firmie MEGA. - Large download + Duże pobieranie - Start download + Rozpocznij pobieranie - Always download and don’t ask again + Zawsze pobieraj i nie pytaj ponownie + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 850b447902..c8a4e1beff 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5458,15 +5458,33 @@ Chamar a todos - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + Este aplicativo está conectado a outra conta do MEGA. \nFaça logout desta conta e faça login na sua conta da MEGA VPN O MEGA precisa acessar a sua câmera para fazer fotos e gravar vídeos. Você não permitiu que o MEGA acesse à sua localização. Se você quiser compartilhar a sua localização, dê permissão à MEGA para fazer isso. - Large download + Download grande - Start download + Começar a fazer o download - Always download and don’t ask again + Sempre fazer o download e não perguntar novamente + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index ff49476c52..dd14469bcb 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5432,7 +5432,7 @@ Sincronizează - • Fără reclame + • Fără publicitate Invitație la întâlnire MEGA @@ -5458,7 +5458,7 @@ Suna pe toți - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + Această aplicație este conectată la un alt cont MEGA. \nDeconectați-vă de la acest cont și conectați-vă cu contul MEGA VPN MEGA are nevoie de acces la camera dvs. pentru a captura fotografii și videoclipuri. @@ -5469,4 +5469,22 @@ Începeți descărcarea Descărcați întotdeauna și nu întrebați din nou + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6af2f34a42..0800424a60 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1512,7 +1512,7 @@ Помощь - Центр помощи + Справочный центр Отправить отзыв @@ -5660,7 +5660,7 @@ Используются нашими одобренными рекламными партнерами для сбора данных о вашей активности в Интернете и настройки рекламы, которую вы видите в наших сервисах и на других веб-сайтах. Если вы не примете эти куки-файлы, вы всё равно будете видеть рекламу, но она не будет персонализированной. - Мы используем куки и аналогичные технологии для улучшения наших сервисов и в рекамных целях. Продолжая использовать MEGA, вы соглашаетесь с условиями нашей обновлённой [A]Политики в отношении куки-файлов[/A]. + Мы используем куки и аналогичные технологии для улучшения наших сервисов и в рекламных целях. Продолжая использовать MEGA, вы соглашаетесь с условиями нашей обновлённой [A]Политики в отношении куки-файлов[/A]. Синхронизация @@ -5690,15 +5690,36 @@ Позвонить всем - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + В этом приложении выполнен вход в другой аккаунт MEGA. \nВыйдите из этого аккаунта и войдите в свой аккаунт MEGA VPN Для фото- и видеосъёмки MEGA требуется доступ к камере. - You denied MEGA access to your location. If you’d like to share your location, allow MEGA permission to do so. + Вы запретили MEGA доступ к местоположению. Если вы хотите поделиться своим местоположением, выдайте MEGA это разрешение. - Large download + Большой размер скачивания - Start download + Скачать - Always download and don’t ask again + Всегда скачивать и больше не спрашивать + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 30d49128bc..4b03753fa6 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4994,7 +4994,7 @@ โทรหาทั้งหมด - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + บัญชี MEGA ที่ใช้อยู่ในแอปพลิเคชันนี้ไม่ตรงกับบัญชี MEGA VPN ของคุณ\nกรุณาออกจากระบบบัญชีนี้ก่อน แล้วเข้าสู่ระบบด้วยบัญชี MEGA VPN ของคุณอีกครั้ง MEGA ต้องการเข้าถึงกล้องของคุณเพื่อถ่ายภาพและวิดีโอ @@ -5005,4 +5005,16 @@ เริ่มดาวน์โหลด ดาวน์โหลดทันทีและไม่ต้องถามอีก + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index de344e796f..cb0ff8f934 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4995,7 +4995,7 @@ Gọi tất cả - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -5006,4 +5006,16 @@ Start download Always download and don’t ask again + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1a558e38f2..9c6e03b1ec 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4994,7 +4994,7 @@ 给所有人通话 - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -5005,4 +5005,16 @@ Start download Always download and don’t ask again + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1a7e97ec3a..c3a6c3a180 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -11,7 +11,7 @@ 取消 - 移動至 + 移動到 選擇 @@ -4994,7 +4994,7 @@ 與所有人通話 - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + 此應用程式已登入不同的MEGA帳戶。\n登出此帳戶,然後使用您的MEGA VPN帳戶登入 MEGA需要存取您的相機來拍攝照片和影片。 @@ -5005,4 +5005,16 @@ 開始下載 總是下載並且不再詢問 + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5b8596c34f..b007c60c83 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5232,7 +5232,7 @@ Call all - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. diff --git a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml index cec2b2fde0..fc3acedd10 100644 --- a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported. + MEGA ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ได้ เนื่องจากไม่สนับสนุนระบบไฟล์ในอุปกรณ์ของคุณ The folder you chose can’t be synced diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index a147b7acd8..1adaa2aa8d 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -123,7 +123,7 @@ شبكة الوايرلس فقط - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. Monitoring syncs @@ -151,7 +151,7 @@ Sync item exceeds maximum folder depth - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index bbfba3f01b..a45d81cac7 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisierungen [A](%1$d)[/A] - Um Ihren lokalen Ordner zu synchronisieren, müssen wir auf Ihren Gerätespeicher zugreifen. Tippen Sie, um Zugriff zu gewähren + We need to access your device storage in order to sync your local folder. Tap here to grant access. Um Ihre Dateien und Ordner fortlaufend zu synchronisieren, erlauben Sie das Ausführen von MEGA im Hintergrund. @@ -135,7 +135,7 @@ Synchronisierungsobjekt überschreitet maximale Ordnertiefe - Ordner steht Datei gegenüber + Die zu synchronisierende Datei hat keine Erweiterung und hat den gleichen Namen wie ein bestehender Ordner Sowohl lokales als auch entferntes Objekt seit der letzten Synchronisierung geändert diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index c9c766ad89..01476a0e72 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -111,7 +111,7 @@ Solo Wi-Fi - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. Monitoring syncs @@ -139,7 +139,7 @@ Sync item exceeds maximum folder depth - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index 32b47b3b99..000734fb8c 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisations [A](%1$d)[/A] - Nous devons accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez pour accorder l\’accès + Nous devons accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour accorder l\’accès. Afin de synchroniser en permanence vos fichiers et dossiers, autorisez MEGA à fonctionner en arrière-plan. @@ -51,11 +51,11 @@ Fusionner les dossiers - Choose local file + Choisir le fichier local - Choose remote file + Choisir le fichier distant - Choose the last modified file + Choisir le dernier fichier modifié Le conflit a été résolu @@ -67,9 +67,9 @@ Accès à tous les fichiers - Battery optimisation + Optimisation de la batterie - Don’t allow + Ne pas autoriser Autoriser @@ -77,7 +77,7 @@ Aucun problème résolu - No issues + Aucun blocage Nommer la synchronisation @@ -103,7 +103,7 @@ Mettre en pause - Resume + Reprendre Supprimer @@ -113,7 +113,7 @@ Vous devrez configurer un dossier local sur\nvotre appareil qui se synchronisera avec un\ndossier choisi sur votre Disque nuagique. - Monitoring syncs + Surveillance des synchronisations Les options de synchronisation ont été changées : Wi-Fi seulement @@ -121,7 +121,7 @@ No reason - File or folder issue + Problème de fichier ou de dossier Impossible de déplacer ou de renommer @@ -139,11 +139,11 @@ L’élément de synchronisation est trop bas dans l\’arborescence - Un dossier est mis en correspondance avec un fichier + Le fichier que vous tentez de synchroniser n’a pas d’extension et porte le même nom qu’un dossier existant Changements locaux et distants depuis la dernière synchronisation - File or folder conflict + Conflit de fichier ou de dossier Conflit de nom de fichier ou de dossier @@ -151,7 +151,7 @@ Dossiers - Issues (%d) + Problèmes (%d) Problèmes diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index 95b320c11c..2c86857c1f 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -103,7 +103,7 @@ Hanya Wi-Fi - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. Monitoring syncs @@ -131,7 +131,7 @@ Sync item exceeds maximum folder depth - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index 5a940fa089..a3df9d5bf9 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - Abbiamo bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca per dare l\’accesso + We need to access your device storage in order to sync your local folder. Tap here to grant access. Per sincronizzare in modo continuo i tuoi file e le tue cartelle, permetti a MEGA di operare in background. @@ -139,7 +139,7 @@ L\’oggetto della sincronizzazione supera il massimo di profondità di cartelle - Folder matched against file + Il file che stai cercando di sincronizzare non ha un\’estensione e ha lo stesso nome di una cartella esistente L\’oggetto remoto e l\’oggetto locale sono cambiati dopo l\’ultima sincronizzazione diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index fa3be129e7..d6146eb455 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -9,7 +9,7 @@ 同期 [A](%1$d)[/A] - ローカルフォルダを同期するには、お使いのデバイスのストレージにアクセスする必要があります。タップしてアクセスを許可してください + ローカルフォルダを同期するには、お使いのデバイスのストレージにアクセスする必要があります。こちらをタップしてアクセスを許可してください。 ファイルとフォルダを継続的に同期するには、MEGAをバックグラウンドで実行できるようにします。 @@ -69,7 +69,7 @@ 解決済みの問題はありません - No issues + 問題はありません 同期に名前を付ける @@ -131,7 +131,7 @@ 同期項目がフォルダの最大深さを超えています - ファイルと一致するフォルダ + 同期しようとしているファイルには拡張子がなく、既存のフォルダと同じ名前が付いています 前回の同期以降にローカルとリモートが変更されました diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 38487dd103..6aa65168a0 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - 당신의 로컬 폴더를 동기화하기 위해 장치 저장소에 접근이 필요합니다. 접근을 승인하려면 탭하세요 + We need to access your device storage in order to sync your local folder. Tap here to grant access. 파일과 폴더를 계속 동기화하려면, MEGA가 백그라운드에서 작동하도록 허용하세요. @@ -131,7 +131,7 @@ 동기화 항목이 최대 폴더 깊이를 초과함 - 파일이 폴더와 연결됨 + 동기화하려는 파일에 확장자가 없고 존재하는 폴더와 이름이 같습니다 로컬과 원격이 지난 동기화 이후로 변경됨 diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index 246bd855c2..7476e93c15 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisaties [A](%1$d)[/A] - We hebben toegang tot uw apparaatopslag nodig om uw lokale map te kunnen synchroniseren. Tik om toegang te verlenen + We need to access your device storage in order to sync your local folder. Tap here to grant access. Om uw bestanden en mappen continu te synchroniseren, kunt u MEGA op de achtergrond laten draaien. @@ -135,7 +135,7 @@ Synchronisatie item overschrijdt de maximale map inhoud - Map afgestemd op bestand + Het bestand dat u probeert te synchroniseren heeft geen extensie en heeft dezelfde naam als een bestaande map Lokaal en op afstand gewijzigd sinds de laatste synchronisatie diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index 863fac58df..0ee3be5404 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -7,9 +7,9 @@ Sync - Syncs [A](%1$d)[/A] + Synchronizacja [A](%1$d)[/A] - Aby zsynchronizować katalog lokalny, musimy uzyskać dostęp do pamięci urządzenia. Wybierz, aby przyznać dostęp + Aby zsynchronizować katalog lokalny, musimy uzyskać dostęp do pamięci urządzenia. Wybierz tutaj, aby przyznać dostęp. Aby stale synchronizować pliki i katalogi, pozwól MEGA działać w tle. @@ -53,13 +53,13 @@ Zmień nazwę wszystkich elementów - Merge folders + Scalanie katalogów - Choose local file + Wybierz plik lokalny - Choose remote file + Wybierz plik zdalny - Choose the last modified file + Wybierz ostatnio zmodyfikowany plik Konflikt rozwiązany @@ -71,9 +71,9 @@ Dostęp do wszystkich plików - Battery optimisation + Optymalizacja baterii - Don’t allow + Nie zezwalaj Zezwól @@ -81,7 +81,7 @@ Brak rozwiązanych problemów - No issues + Brak problemów Nazwa synchronizacji @@ -107,7 +107,7 @@ Wstrzymaj - Resume + Wznów Usuń @@ -117,7 +117,7 @@ Konieczne będzie skonfigurowanie lokalnego\n katalogu na urządzeniu, który będzie synchronizowany z wybranym katalogiem \nna dysku w chmurze. - Monitoring syncs + Monitorowanie synchronizacji Opcje synchronizacji zmieniono na: Tylko Wi-Fi @@ -125,7 +125,7 @@ No reason - File or folder issue + Problem z plikiem lub katalogiem Nie można przenieść ani zmienić nazwy @@ -143,11 +143,11 @@ Synchronizowany element przekracza maksymalną głębokość katalogu - Katalog dopasowany do pliku + Plik, który próbujesz zsynchronizować, nie ma rozszerzenia i ma taką samą nazwę jak istniejący katalog Zmiany lokalne i zdalne od ostatniej synchronizacji - File or folder conflict + Konflikt plików lub katalogów Konflikt nazw plików lub katalogów diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index 6cc4d9a6c1..b794ceaa93 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -9,7 +9,7 @@ Sincronizações [A](%1$d)[/A] - Nós precisamos acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque para permitir o acesso + Nós precisamos acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque aqui para permitir o acesso Para a sincronização contínua dos seus arquivos e das suas pastas, permita que o MEGA seja executado em segundo plano. @@ -77,7 +77,7 @@ Não há problemas solucionados - No issues + Não há problemas Nomeie a sincronização @@ -139,7 +139,7 @@ A sincronização do item excede a profundidade máxima da pasta - Pasta pareada com arquivo + O arquivo que você está tentando sincronizar não tem extensão e tem o mesmo nome de uma pasta existente Itens locais e remotos alterados desde a última sincronização diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index d5248cb5e8..d36412a2e4 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -9,7 +9,7 @@ Sincronizări [A](%1$d)[/A] - Trebuie să accesăm memoria dispozitivului dvs. pentru a vă sincroniza folderul local. Atingeți ușor pentru a acorda acces + Trebuie să accesăm spațiul de stocare al dispozitivului pentru a vă sincroniza folderul local. Atingeți aici pentru a acorda acces. Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal. @@ -77,7 +77,7 @@ Nicio problemă rezolvată - No issues + Nicio problemă Denumiți sincronizarea @@ -139,7 +139,7 @@ Element de sincronizare prea jos în arborele de foldere - Un folder este comparat cu un fișier + Fișierul pe care încercați să îl sincronizați nu are extensie și are același nume ca un folder existent Elemente locale și distante modificate de la ultima sincronizare diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index ca7a1fcf47..601b6747fe 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -9,9 +9,9 @@ Синхронизации [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + Нам нужен доступ к памяти устройства, чтобы синхронизировать локальную папку. Нажмите здесь, чтобы предоставить доступ. - To continuously sync your files and folders, allow MEGA to run in the background. + Чтобы непрерывно синхронизировать файлы и папки, разрешите MEGA работать в фоновом режиме. %d файл @@ -43,25 +43,25 @@ Параметры синхронизации - Clear solved issues + Удалить решённые проблемы - Two-way sync + Двухсторонняя синхронизация Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + На одной стороне есть несколько названий файлов, которые на другой строне станут одинаковыми. Переименовать все элементы Объединить папки - Choose local file + Выбрать локальный файл - Choose remote file + Выбрать удалённый файл - Choose the last modified file + Выбрать последний изменённый файл - Conflict resolved + Конфликт разрешён Для резервного копирования файлов MEGA требуется доступ к файлам и папкам на этом устройстве. С нами ваши данные всегда в безопасности. @@ -69,9 +69,9 @@ Не сейчас - Access to all files + Доступ ко всем файлам - Battery optimisation + Оптимизация аккумулятора Не разрешать @@ -79,35 +79,35 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + Нет решённых проблем - No issues + Нет проблем - Name the sync + Назовите синхронизацию - Device folder + Папка на устройстве MEGA-папка - Sync type + Тип синхронизации На паузе Синхронизация… - Stopped + Остановлено - Synced + Синхронизировано - Device folder + Папка на устройстве MEGA-папка - Issues info + О проблеме Пауза - Resume + Возобновить Удалить @@ -115,87 +115,87 @@ Только Wi-Fi - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + Вам нужно будет настроить локальную папку на устройстве, которая будет синхронизироваться с выбранной папкой на Облачном диске. - Monitoring syncs + Отслеживание синхронизаций - Sync options changed to: Wi-Fi only + Параметры синхронизации изменены на: только Wi-Fi - Sync options changed to: Wi-Fi or mobile data + Параметры синхронизации изменены на: Wi-Fi или мобильные данные No reason - File or folder issue + Проблема файла или папки - Can’t move or rename + Невозможно переместить или переименовать - Delete or move waiting on scanning + Поиск ожидающих операций удаления или перемещения - Can’t delete yet + Пока нельзя удалить - Upload problem + Проблема при загрузке - Download problem + Проблема при скачивании - Can’t create folder + Невозможно создать папку - Can’t delete item + Невозиожно удалить элемент - Sync item exceeds maximum folder depth + Расположение элемента синхронизации превышает максимальную глубину папки - Folder matched against file + У файла, который вы пытаетесь синхронизировать, нет расширения и такое же название, как у существующей папки - Local and remote changed since last sync + Локальный и удаленный элементы изменены с момента последней синхронизации - File or folder conflict + Конфликт файла или папки - File or folder name conflict + Конфликт названия файла или папки Last plus one Папки - Issues (%d) + Проблемы (%d) - Issues + Проблемы - Solved issues + Решённые проблемы - Set up a sync + Настроить синхронизацию - Папка пуста + Пустая папка Выбор папки Выбрать - A single file or folder had an issue that needs your decision to solve + С одним файлом или папкой возникла проблема, для решения которой требуется ваше решение - Waiting for other processes to complete + Ожидание завершения других процессов - Can’t reach the destination folder + Не удаётся добраться до папки назначения - A failure occurred either downloading the file, or moving the downloaded temporary file to its final location + Произошел сбой либо при скачивании файла, либо при перемещении скачанного временного файла в его конечное расположение - A local error prevents folder access + Локальная ошибка, препятствующая доступу к папке Filesystem error preventing folder access. - Target is too deep on your folder structure.\nMove it to a location that is less than 64 folders deep. + Целевой элемент находится слишком глубоко в структуре папок.\nПереместите его в расположение глубиной менее 64 папок. - The file you’re attempting to sync has no extension and has the same name as an existing folder + У файла, который вы пытаетесь синхронизировать, нет расширения и такое же название, как у существующей папки - This file has been changed both in MEGA and locally since it was last synced. + Этот файл был изменён как в MEGA, так и локально с момента последней синхронизации. - This file has conflicting copies + У этого файла есть конфликтующие копии - There are multiple file names on one side that would all become the same single name on the other side + На одной стороне есть несколько названий файлов, которые на другой строне станут одинаковыми - A move or rename was detected in MEGA, but couldn’t be replicated locally. + В MEGA обнаружено перемещение или переименование, но его не удалось воспроизвести локально. - A move or rename was detected locally, but couldn’t be replicated in MEGA. + Обнаружено локальное перемещение или переименование, но его не удалось воспроизвести в MEGA. - Waiting to finish scan to see if the file was moved or deleted. + Ожидание завершения сканирования, чтобы проверить, был ли файл перемещён или удалён. - Choose folders + Выбор папок \ No newline at end of file diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index dd802c0eeb..3494753b48 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -9,7 +9,7 @@ ซิงค์ [A](%1$d)[/A] - เราจำเป็นต้องเข้าถึงไฟล์ในเครื่องของคุณ เพื่อซิงค์รายการเหล่านั้นกับอุปกรณ์อื่น ๆ แตะเพื่ออนุญาตให้เราเข้าถึง + We need to access your device storage in order to sync your local folder. Tap here to grant access. เพื่อให้การซิงค์ไฟล์และโฟลเดอร์ของคุณเป็นไปอย่างต่อเนื่อง คุณต้องอนุญาตให้ MEGA ทำงานในเบื้องหลัง @@ -131,7 +131,7 @@ ไม่สามารถซิงค์รายการนี้ เนื่องจากโฟลเดอร์มีระดับลึกเกินไป - โฟลเดอร์มีชื่อตรงกับไฟล์ + ไฟล์ที่คุณพยายามซิงค์ไม่มีนามสกุลและชื่อไฟล์ซ้ำกับโฟลเดอร์ที่มีอยู่ ข้อมูลที่อยู่บนเครื่องและข้อมูลจากระยะไกลเปลี่ยนแปลงไปตั้งแต่ซิงค์ครั้งล่าสุด diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 95b21ac4d5..e5b4399fc3 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -103,7 +103,7 @@ Chỉ lúc dùng Wi-Fi - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. Monitoring syncs @@ -131,7 +131,7 @@ Sync item exceeds maximum folder depth - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index 2e3dbb1055..51396fe2ee 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -131,7 +131,7 @@ 同步项目超过最大文件夹深度 - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 8a82110a16..27ec0e0886 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -7,11 +7,11 @@ 同步 - Syncs [A](%1$d)[/A] + 同步[A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + 我們需要存取您的裝置儲存空間,以便同步您的本地資料夾。點選此處以授予存取權限。 - To continuously sync your files and folders, allow MEGA to run in the background. + 若要持續同步您的檔案和資料夾,請允許MEGA在背景執行。 %d個檔案 @@ -29,73 +29,73 @@ %1$d個檔案 - Sync options + 同步選項 - Clear solved issues + 清除已解決的問題 - Two-way sync + 雙向同步 Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + 在一側有多個檔案名稱,這些檔名在另一側都會變成同一個名稱。 - Rename all items + 重新命名所有項目 - Merge folders + 合併資料夾 - Choose local file + 選擇本地檔案 - Choose remote file + 選擇遠端檔案 - Choose the last modified file + 選擇最後修改的檔案 - Conflict resolved + 衝突已解決 - To back up your files, MEGA needs access to the files and folders in this device. Your data is always safe with us. + 要備份您的檔案,MEGA需要存取此裝置中的檔案和資料夾。您的資料在我們這裡始終是安全的。 繼續 稍後再說 - Access to all files + 存取所有檔案 - Battery optimisation + 電池最佳化 - Don’t allow + 不允許 允許 Allow MEGA to read, modify or delete all files on this device. - No solved issues + 沒有已解決問題 - No issues + 沒有問題 - Name the sync + 為同步命名 - Device folder + 裝置資料夾 MEGA資料夾 - Sync type + 同步類型 暫停 - Syncing… + 正在同步⋯ - Stopped + 已停止 - Synced + 已同步 - Device folder + 裝置資料夾 MEGA資料夾 - Issues info + 問題訊息 暫停 - Resume + 恢復 移除 @@ -103,53 +103,53 @@ 只在WiFi連線 - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + 您需要在\n裝置上設定一個本地資料夾,該資料夾將與\n您雲端硬碟上選定的資料夾同步。 - Monitoring syncs + 監控同步 - Sync options changed to: Wi-Fi only + 同步選項更改為:僅限Wi-Fi - Sync options changed to: Wi-Fi or mobile data + 同步選項更改為:Wi-Fi或行動數據 No reason - File or folder issue + 檔案或資料夾問題 - Can’t move or rename + 無法移動或重新命名 - Delete or move waiting on scanning + 刪除或移動,等待掃描中 - Can’t delete yet + 還無法刪除 - Upload problem + 上傳問題 - Download problem + 下載問題 - Can’t create folder + 無法建立資料夾 - Can’t delete item + 無法刪除項目 - Sync item exceeds maximum folder depth + 同步項目超過最大資料夾深度 - Folder matched against file + 您嘗試同步的檔案沒有副檔名,並且與現有資料夾的名稱相同 - Local and remote changed since last sync + 自上次同步以來,本地和遠端已更改 - File or folder conflict + 檔案或資料夾衝突 - File or folder name conflict + 檔案或資料夾名稱衝突 Last plus one 資料夾 - Issues (%d) + 問題(%d) - Issues + 問題 - Solved issues + 已解決的問題 - Set up a sync + 設定同步 空資料夾 @@ -157,33 +157,33 @@ 選擇 - A single file or folder had an issue that needs your decision to solve + 單一檔案或資料夾存在需要您的決定才能解決的問題單個檔案或資料夾存在需要您決定解決的問題 - Waiting for other processes to complete + 正在等待其它程序完成 - Can’t reach the destination folder + 無法到達目的資料夾 - A failure occurred either downloading the file, or moving the downloaded temporary file to its final location + 下載檔案或將下載的暫存檔案移動到其最終位置時發生失敗 - A local error prevents folder access + 一個阻止資料夾存取的本地錯誤 Filesystem error preventing folder access. - Target is too deep on your folder structure.\nMove it to a location that is less than 64 folders deep. + 目標在您的資料夾結構中的位置太深。\n請將其移到深度少於64個資料夾的位置。 - The file you’re attempting to sync has no extension and has the same name as an existing folder + 您嘗試同步的檔案沒有副檔名,並且與現有資料夾的名稱相同 - This file has been changed both in MEGA and locally since it was last synced. + 自上次同步以來,此檔案在MEGA和本地均已更改。 - This file has conflicting copies + 此檔案有衝突的副本 - There are multiple file names on one side that would all become the same single name on the other side + 在一側有多個檔案名稱,這些檔名在另一側都會變成同一個名稱 - A move or rename was detected in MEGA, but couldn’t be replicated locally. + 在MEGA中偵測到移動或重新命名的變動,但無法在本地複製。 - A move or rename was detected locally, but couldn’t be replicated in MEGA. + 在本地偵測到移動或重新命名的變動,但無法在MEGA中複製。 - Waiting to finish scan to see if the file was moved or deleted. + 等待完成掃描以查看檔案是否被移動或刪除。 - Choose folders + 選擇資料夾 \ No newline at end of file diff --git a/feature/sync/src/main/res/values/strings_sync_feature.xml b/feature/sync/src/main/res/values/strings_sync_feature.xml index bfd32e3338..eed1573a12 100644 --- a/feature/sync/src/main/res/values/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap to grant access. + We need to access your device storage in order to sync your local folder. Tap here to grant access. To continuously sync your files and folders, allow MEGA to run in the background. @@ -107,7 +107,7 @@ Wi-Fi only - You’ll need to set up a local folder on your\ndevice that will sync with a chosen folder on\nyour Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. Monitoring syncs @@ -135,7 +135,7 @@ Sync item exceeds maximum folder depth - Folder matched against file + The file you’re attempting to sync has no extension and has the same name as an existing folder Local and remote changed since last sync From 641f10da96c2770a3cb4e3f758f5f04d2cc64a8f Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Wed, 31 Jan 2024 11:17:27 +0800 Subject: [PATCH 025/261] BAC-779: Add Logs on Clicking the Cloud Drive Bottom Navigation Icon The logs would help debug a rare issue in specific Devices wherein the User is not taken back to the Cloud Drive Root Level when the User opens the Media Discovery Folder, switches to Thumbnail View and clicks the Cloud Drive Bottom Navigation Icon. --- .../java/mega/privacy/android/app/main/ManagerActivity.kt | 5 +++++ .../app/presentation/clouddrive/FileBrowserViewModel.kt | 1 + 2 files changed, 6 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 3e11a13659..a91bf251b1 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -3935,6 +3935,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf */ private fun handleCloudDriveNavigation() { if (fileBrowserViewModel.isMediaDiscoveryOpen()) { + Timber.d("Show Media Discovery Screen") Handler(Looper.getMainLooper()).post { showMediaDiscovery( mediaHandle = fileBrowserViewModel.getSafeBrowserParentHandle(), @@ -3942,6 +3943,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf ) } } else { + Timber.d("Show Cloud Drive Screen") selectDrawerItemCloudDrive() } } @@ -5246,14 +5248,17 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf R.id.bottom_navigation_item_cloud_drive -> { // User is in Cloud Drive. Go back to the Root Node level if (drawerItem == DrawerItem.CLOUD_DRIVE) { + Timber.d("User is in Cloud Drive. Go back to the Root Level") lifecycleScope.launch { if (fileBrowserViewModel.isMediaDiscoveryOpen()) { + Timber.d("Remove the Media Discovery Fragment") removeFragment(mediaDiscoveryFragment) } fileBrowserViewModel.goBackToRootLevel() } } else { // User is not in Cloud Drive. Navigate to the feature + Timber.d("User is not in Cloud Drive. Navigate to Cloud Drive") drawerItem = DrawerItem.CLOUD_DRIVE setBottomNavigationMenuItemChecked(CLOUD_DRIVE_BNV) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt index c6e8a8bba3..a588b74a64 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt @@ -381,6 +381,7 @@ class FileBrowserViewModel @Inject constructor( ) } getRootNodeUseCase()?.id?.longValue?.let { rootHandle -> + Timber.d("Root Node Exists. Set data from the Root Node") setFileBrowserHandle(rootHandle) } } From 261cc872fd60fa017e27cdb03ce56c88e0c5e50c Mon Sep 17 00:00:00 2001 From: Amr Date: Thu, 1 Feb 2024 00:27:13 +0800 Subject: [PATCH 026/261] AP-1054: Add Subscription Details Section in the UpgradeAccountView --- .../upgradeAccount/UpgradeAccountFragment.kt | 12 +++ .../upgradeAccount/view/UpgradeAccountView.kt | 79 ++++++++++++++++--- .../mega/privacy/android/app/utils/URLUtil.kt | 9 ++- app/src/main/res/values/strings.xml | 4 + .../upgradeAccount/UpgradeAccountViewTest.kt | 49 ++++++++++++ .../domain/usecase/IsUrlWhitelistedUseCase.kt | 9 ++- 6 files changed, 148 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt index 7a0fb8748b..d78858b06d 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt @@ -1,6 +1,7 @@ package mega.privacy.android.app.upgradeAccount import android.content.Intent +import android.content.Intent.ACTION_VIEW import android.net.Uri import android.os.Bundle import android.view.LayoutInflater @@ -105,6 +106,7 @@ class UpgradeAccountFragment : Fragment() { } }, onTOSClicked = this::redirectToTOSPage, + onPlayStoreLinkClicked = this::redirectToPlayStoreSubscription, onPricingPageClicked = this::redirectToPricingPage, onChoosingMonthlyYearlyPlan = upgradeAccountViewModel::onSelectingMonthlyPlan, onChoosingPlanType = { @@ -214,6 +216,16 @@ class UpgradeAccountFragment : Fragment() { ) } + private fun redirectToPlayStoreSubscription(link: String) { + val uriUrl = Uri.parse(link) + val launchBrowser = Intent(ACTION_VIEW, uriUrl) + runCatching { + startActivity(launchBrowser) + }.onFailure { + Timber.e("Failed to open play store subscription page with error: ${it.message}") + } + } + private fun redirectToPricingPage(link: String) { val uriUrl = Uri.parse(link) val launchBrowser = Intent(requireContext(), WebViewActivity::class.java) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt index 9087d05430..55e3da0616 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt @@ -53,6 +53,7 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextIndent import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider @@ -71,24 +72,30 @@ import mega.privacy.android.app.upgradeAccount.model.mapper.LocalisedPriceString import mega.privacy.android.app.upgradeAccount.view.components.MonthlyYearlyTabs import mega.privacy.android.app.upgradeAccount.view.components.ProPlanInfoCard import mega.privacy.android.app.upgradeAccount.view.components.SaveUpToLabel -import mega.privacy.android.app.utils.Constants +import mega.privacy.android.app.utils.Constants.INVALID_VALUE +import mega.privacy.android.app.utils.Constants.PRICING_PAGE_URL +import mega.privacy.android.app.utils.PLAY_STORE_SUBSCRIPTION_URL +import mega.privacy.android.core.ui.controls.text.MegaSpannedClickableText +import mega.privacy.android.core.ui.controls.text.MegaText +import mega.privacy.android.core.ui.model.MegaSpanStyle +import mega.privacy.android.core.ui.model.MegaSpanStyleWithAnnotation import mega.privacy.android.core.ui.model.SpanIndicator import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.theme.Typography import mega.privacy.android.core.ui.theme.extensions.black_white import mega.privacy.android.core.ui.theme.extensions.black_yellow_700 +import mega.privacy.android.core.ui.theme.extensions.body4 import mega.privacy.android.core.ui.theme.extensions.grey_020_grey_800 import mega.privacy.android.core.ui.theme.extensions.grey_100_alpha_060_dark_grey import mega.privacy.android.core.ui.theme.extensions.grey_alpha_012_white_alpha_012 import mega.privacy.android.core.ui.theme.extensions.teal_300_teal_200 import mega.privacy.android.core.ui.theme.extensions.yellow_100_yellow_700_alpha_015 import mega.privacy.android.core.ui.theme.subtitle1 +import mega.privacy.android.core.ui.theme.tokens.TextColor import mega.privacy.android.domain.entity.AccountType import mega.privacy.android.domain.entity.Currency import mega.privacy.android.domain.entity.account.CurrencyAmount import mega.privacy.android.legacy.core.ui.controls.appbar.SimpleNoTitleTopAppBar -import mega.privacy.android.legacy.core.ui.controls.text.MegaSpannedClickableText -import mega.privacy.android.legacy.core.ui.model.SpanStyleWithAnnotation import mega.privacy.android.shared.theme.MegaAppTheme internal const val UPGRADE_ACCOUNT_SCREEN_TAG = "upgrade_account_screen:" @@ -101,6 +108,12 @@ internal const val PRO_PLAN_CARD_TAG = "upgrade_account_screen:card_pro_plan_" internal const val PRICING_PAGE_LINK_TAG = "upgrade_account_screen:text_pricing_page_link" internal const val BUY_BUTTON_TAG = "upgrade_account_screen:button_buy_pro_plan_" internal const val UPGRADE_WARNING_BANNER_TAG = "upgrade_account_screen:upgrade_warning_banner" +internal const val GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG = + "upgrade_account_screen:text_link_google_play_store_subscription" +internal const val SUBSCRIPTION_DETAILS_TITLE_TAG = + "upgrade_account_screen:text_subscription_details_title" +internal const val SUBSCRIPTION_DETAILS_DESCRIPTION_TAG = + "upgrade_account_screen:text_subscription_details_description" /** * Screen is shown when user taps on Upgrade button @@ -113,6 +126,7 @@ fun UpgradeAccountView( onBackPressed: () -> Unit, onBuyClicked: () -> Unit, onTOSClicked: () -> Unit, + onPlayStoreLinkClicked: (String) -> Unit, onPricingPageClicked: (String) -> Unit, onChoosingMonthlyYearlyPlan: (isMonthly: Boolean) -> Unit, onChoosingPlanType: (chosenPlan: AccountType) -> Unit, @@ -280,6 +294,7 @@ fun UpgradeAccountView( } FeaturesOfPlans(showNoAdsFeature = state.showNoAdsFeature) + SubscriptionDetails(onLinkClick = onPlayStoreLinkClicked) Text( text = stringResource(id = R.string.account_upgrade_account_terms_of_service_link), @@ -530,7 +545,7 @@ private fun FeaturesOfPlans( start = 24.dp, top = 12.dp, end = 24.dp, - bottom = 50.dp + bottom = 30.dp ) ) { Text( @@ -608,6 +623,44 @@ private fun FeaturesOfPlans( } } +@Composable +private fun SubscriptionDetails( + onLinkClick: (link: String) -> Unit, +) { + Column( + modifier = Modifier + .padding( + start = 24.dp, + end = 24.dp, + bottom = 50.dp + ) + .testTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + ) { + MegaText( + modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_TITLE_TAG), + text = stringResource(id = R.string.account_upgrade_account_description_subscription_title), + style = MaterialTheme.typography.body2, + textColor = TextColor.Primary, + ) + Spacer(modifier = Modifier.height(12.dp)) + MegaSpannedClickableText( + modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG), + value = stringResource(id = R.string.account_upgrade_subscription_details), + styles = hashMapOf( + SpanIndicator('A') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(textDecoration = TextDecoration.None), + color = TextColor.Accent, + ), PLAY_STORE_SUBSCRIPTION_URL + ) + ), + onAnnotationClick = onLinkClick, + baseStyle = MaterialTheme.typography.body4, + color = TextColor.Primary + ) + } +} + @Composable private fun PricingPageLinkText( onLinkClick: (link: String) -> Unit, @@ -619,17 +672,18 @@ private fun PricingPageLinkText( value = stringResource( id = R.string.account_upgrade_account_pricing_page_link_text ), - styles = mapOf( - SpanIndicator('A') to SpanStyleWithAnnotation( - SpanStyle( - fontWeight = FontWeight.W500, - color = MaterialTheme.colors.teal_300_teal_200 + styles = hashMapOf( + SpanIndicator('A') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(fontWeight = FontWeight.W500), + color = TextColor.Accent, ), - Constants.PRICING_PAGE_URL + PRICING_PAGE_URL ) ), onAnnotationClick = onLinkClick, - baseStyle = MaterialTheme.typography.subtitle2.copy(color = MaterialTheme.colors.black_white), + baseStyle = MaterialTheme.typography.subtitle2, + color = TextColor.Primary ) } @@ -645,6 +699,7 @@ fun PreviewUpgradeAccountView( onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -674,7 +729,7 @@ private class UpgradeAccountPreviewProvider : showBillingWarning = false, showBuyNewSubscriptionDialog = false, currentPayment = UpgradePayment( - upgradeType = Constants.INVALID_VALUE, + upgradeType = INVALID_VALUE, currentPayment = null, ), ) diff --git a/app/src/main/java/mega/privacy/android/app/utils/URLUtil.kt b/app/src/main/java/mega/privacy/android/app/utils/URLUtil.kt index d799e892e6..751111326f 100644 --- a/app/src/main/java/mega/privacy/android/app/utils/URLUtil.kt +++ b/app/src/main/java/mega/privacy/android/app/utils/URLUtil.kt @@ -7,6 +7,12 @@ package mega.privacy.android.app.utils const val PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=mega.privacy.android.app&referrer=meganzmobileapps" +/** + * Subscription page URL in Google Play Store for user to manage their subscriptions + */ +const val PLAY_STORE_SUBSCRIPTION_URL = + "https://play.google.com/store/account/subscriptions" + /** * Landing Page / Download URL for MEGA app in Apple App Store */ @@ -14,7 +20,8 @@ const val APP_STORE_URL = "https://apps.apple.com/app/mega/id706857885" private val whitelistedURL = listOf( PLAY_STORE_URL, - APP_STORE_URL + APP_STORE_URL, + PLAY_STORE_SUBSCRIPTION_URL, ) /** diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b007c60c83..1c5b2e5945 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5243,4 +5243,8 @@ Start download Always download and don’t ask again + + Subscription details + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt index fed17bff97..6aab0a3527 100644 --- a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt @@ -24,8 +24,11 @@ import mega.privacy.android.app.upgradeAccount.view.BILLING_WARNING_TAG import mega.privacy.android.app.upgradeAccount.view.BUY_BUTTON_TAG import mega.privacy.android.app.upgradeAccount.view.BuyNewSubscriptionDialog import mega.privacy.android.app.upgradeAccount.view.EMPTY_CARD_TAG +import mega.privacy.android.app.upgradeAccount.view.GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG import mega.privacy.android.app.upgradeAccount.view.PRICING_PAGE_LINK_TAG import mega.privacy.android.app.upgradeAccount.view.PRO_PLAN_CARD_TAG +import mega.privacy.android.app.upgradeAccount.view.SUBSCRIPTION_DETAILS_DESCRIPTION_TAG +import mega.privacy.android.app.upgradeAccount.view.SUBSCRIPTION_DETAILS_TITLE_TAG import mega.privacy.android.app.upgradeAccount.view.UPGRADE_ACCOUNT_SCREEN_TAG import mega.privacy.android.app.upgradeAccount.view.UPGRADE_WARNING_BANNER_TAG import mega.privacy.android.app.upgradeAccount.view.UpgradeAccountView @@ -135,6 +138,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -171,6 +175,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -206,6 +211,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -235,6 +241,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -264,6 +271,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -290,6 +298,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -320,6 +329,7 @@ class UpgradeAccountViewTest { onBuyClicked = onBuyClicked, onBackPressed = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -351,6 +361,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -379,6 +390,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -403,6 +415,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -428,6 +441,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -454,6 +468,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -480,6 +495,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -513,6 +529,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, onChoosingPlanType = {}, @@ -586,6 +603,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, onChoosingMonthlyYearlyPlan = {}, @@ -613,6 +631,7 @@ class UpgradeAccountViewTest { onBackPressed = {}, onBuyClicked = {}, onTOSClicked = {}, + onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, onChoosingMonthlyYearlyPlan = {}, @@ -627,6 +646,36 @@ class UpgradeAccountViewTest { composeRule.onNodeWithTag(BUY_BUTTON_TAG).assertDoesNotExist() } + @Test + fun `test that subscription details is shown correctly`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.PRO_I, + showBillingWarning = false, + isPaymentMethodAvailable = true + ), + onBackPressed = {}, + onBuyClicked = {}, + onTOSClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG).assertExists() + + } + private fun getUpgradeAccountState( localisedSubscriptionList: List = expectedLocalisedSubscriptionsList, accountType: AccountType, diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/IsUrlWhitelistedUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/IsUrlWhitelistedUseCase.kt index e52d0f5c3f..7353f15044 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/IsUrlWhitelistedUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/IsUrlWhitelistedUseCase.kt @@ -8,7 +8,8 @@ import javax.inject.Inject class IsUrlWhitelistedUseCase @Inject constructor() { private val whitelistedUrlList = listOf( PLAY_STORE_URL, - APP_STORE_URL + APP_STORE_URL, + PLAY_STORE_SUBSCRIPTION_URL, ) /** @@ -26,6 +27,12 @@ class IsUrlWhitelistedUseCase @Inject constructor() { const val PLAY_STORE_URL = "https://play.google.com/store/apps/details?id=mega.privacy.android.app&referrer=meganzmobileapps" + /** + * Subscription page URL in Google Play Store for user to manage their subscriptions + */ + const val PLAY_STORE_SUBSCRIPTION_URL = + "https://play.google.com/store/account/subscriptions" + /** * Landing Page / Download URL for MEGA app in Apple App Store */ From cec8b312019c5c7af83b80c9b90408ece564f5fc Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Thu, 1 Feb 2024 05:47:13 +1300 Subject: [PATCH 027/261] Pre-release v11.5 --- app/src/main/res/values-ar/strings.xml | 16 +++++++++ app/src/main/res/values-de/strings.xml | 16 +++++++++ app/src/main/res/values-es/strings.xml | 16 +++++++++ app/src/main/res/values-fr/strings.xml | 16 +++++++++ app/src/main/res/values-in/strings.xml | 16 +++++++++ app/src/main/res/values-it/strings.xml | 28 +++++++++++---- app/src/main/res/values-ja/strings.xml | 16 +++++++++ app/src/main/res/values-ko/strings.xml | 16 +++++++++ app/src/main/res/values-nl/strings.xml | 16 +++++++++ app/src/main/res/values-pl/strings.xml | 16 +++++++++ app/src/main/res/values-pt/strings.xml | 16 +++++++++ app/src/main/res/values-ro/strings.xml | 16 +++++++++ app/src/main/res/values-ru/strings.xml | 16 +++++++++ app/src/main/res/values-th/strings.xml | 16 +++++++++ app/src/main/res/values-vi/strings.xml | 16 +++++++++ app/src/main/res/values-zh-rCN/strings.xml | 16 +++++++++ app/src/main/res/values-zh-rTW/strings.xml | 20 +++++++++-- .../strings_device_center_feature.xml | 2 +- .../res/values-ar/strings_sync_feature.xml | 12 +++---- .../res/values-de/strings_sync_feature.xml | 10 +++--- .../res/values-es/strings_sync_feature.xml | 12 +++---- .../res/values-fr/strings_sync_feature.xml | 10 +++--- .../res/values-in/strings_sync_feature.xml | 12 +++---- .../res/values-it/strings_sync_feature.xml | 34 +++++++++---------- .../res/values-ja/strings_sync_feature.xml | 6 ++-- .../res/values-ko/strings_sync_feature.xml | 10 +++--- .../res/values-nl/strings_sync_feature.xml | 12 +++---- .../res/values-pl/strings_sync_feature.xml | 10 +++--- .../res/values-pt/strings_sync_feature.xml | 6 ++-- .../res/values-ro/strings_sync_feature.xml | 10 +++--- .../res/values-ru/strings_sync_feature.xml | 10 +++--- .../res/values-th/strings_sync_feature.xml | 10 +++--- .../res/values-vi/strings_sync_feature.xml | 12 +++---- .../values-zh-rCN/strings_sync_feature.xml | 10 +++--- .../values-zh-rTW/strings_sync_feature.xml | 10 +++--- .../main/res/values/strings_sync_feature.xml | 12 +++---- 36 files changed, 385 insertions(+), 113 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 8dbc4d6e13..9768bedeff 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6188,4 +6188,20 @@ + + كتم + + Mute all + + All muted + + You’ve muted %s + + You’ve muted all participants + + You’ve been muted by %s + + تفاصيل الاشتراك + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 497184c25d..a19ef61573 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5252,4 +5252,20 @@ + + Stummschalten + + Alle stummschalten + + Alle stummgeschaltet + + You’ve muted %s + + Sie haben alle Teilnehmer stummgeschaltet + + You’ve been muted by %s + + Abonnementdetails + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index fe04661bb3..bb4070d999 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5487,4 +5487,20 @@ + + Silenciar + + Silenciar a todos + + Todos silenciados + + You’ve muted %s + + Has silenciado a todos los participantes + + You’ve been muted by %s + + Información sobre la suscripción + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ 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 f6989c7f69..f929c34cd1 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5487,4 +5487,20 @@ + + Couper le micro + + Désactiver tous les micros + + Tous les micros ont été désactivés + + Vous avez désactivé le micro de %s + + Vous avez désactivé le micro de tous les participants + + Votre micro a été coupé par %s + + Détails de l’abonnement + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index beb196eaa9..d35ddd2a2a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -5017,4 +5017,20 @@ + + Matikan Suara + + Bisukan semua + + Semua dibisukan + + You’ve muted %s + + Anda telah membisukan semua peserta + + You’ve been muted by %s + + Detail langganan + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index cf48b84f57..5a503df84b 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5458,17 +5458,17 @@ Chiama tutti - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. + Questa app ha un accesso effettuato su un diverso account MEGA.\nEffettua il logout da questo account, ed effettua il login sul tuo account MEGA VPN. - MEGA needs access to your camera to capture photos and videos. + MEGA ha bisogno di accedere alla tua fotocamera per scattare foto e registrare video. - You denied MEGA access to your location. If you’d like to share your location, allow MEGA permission to do so. + Hai negato a MEGA l\’accesso alla tua posizione. Se ti piacerebbe condividere la tua posizione, permetti a MEGA di fare ciò. - Large download + Grande download - Start download + Avvia download - Always download and don’t ask again + Scarica sempre e non chiedere nuovamente @@ -5487,4 +5487,20 @@ + + Muta + + Muta tutti i partecipanti + + Tutti mutati + + You’ve muted %s + + Hai mutato tutti i partecipanti + + You’ve been muted by %s + + Dettagli dell\’abbonamento + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 7e1571345d..8db795b9cd 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5017,4 +5017,20 @@ + + ミュート + + すべてミュート + + すべてミュート + + %sさんをミュートしました + + すべての参加者をミュートにしました + + %sさんにミュートされました + + サブスクリプションの詳細 + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 9884c5f6db..c5a7822a6b 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -5017,4 +5017,20 @@ + + 조용히 + + 모두 음소거 + + 모두 음소거됨 + + You’ve muted %s + + 당신이 모든 참여자를 음소거 하였습니다 + + You’ve been muted by %s + + 구독 세부정보 + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 1508f651a5..b6fc695795 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5252,4 +5252,20 @@ + + Dempen + + Alles dempen + + Alles gedempt + + U heeft %s gedempt + + U heeft alle deelnemers gedempt + + U bent gedempt door %s + + Abonnement details + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index aa61482306..b8368f678f 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5722,4 +5722,20 @@ + + Wycisz + + Wycisz wszystkich + + Wszyscy wyciszeni + + You’ve muted %s + + Wyciszyłeś wszystkich uczestników + + You’ve been muted by %s + + Szczegóły subskrypcji + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c8a4e1beff..fec5308e6c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5487,4 +5487,20 @@ + + Silenciar + + Silenciar a todos + + Todos foram silenciados + + Você silenciou %s + + Você silenciou todos os participantes + + Você foi silenciado por %s + + Informações da assinatura + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index dd14469bcb..e490ababd7 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5487,4 +5487,20 @@ + + Pune pe mut + + Amuțire toate + + Toate microfoanele au fost dezactivate + + Ați dezactivat microfonul lui %s + + Ați dezactivat microfonul pentru toți participanții + + Microfonul dvs. a fost dezactivat de %s + + Detaliile abonamentului + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0800424a60..28a44bcdea 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5722,4 +5722,20 @@ + + Приглушить + + Приглушить всех + + Приглушены все + + You’ve muted %s + + Вы приглушили всех участников + + You’ve been muted by %s + + Подробная информация о подписке + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 4b03753fa6..a50554cc38 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -5017,4 +5017,20 @@ + + ปิดเสียง + + ปิดเสียงทั้งหมด + + ปิดเสียงทุกคนแล้ว + + คุณปิดเสียง %s แล้ว + + คุณได้ปิดเสียงผู้เข้าร่วมทั้งหมดแล้ว + + %s ได้ปิดเสียงคุณ + + รายละเอียดการสมัครใช้งาน + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index cb0ff8f934..30d88277e7 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -5018,4 +5018,20 @@ + + Tắt Tiếng + + Tắt tiếng tất cả + + Đã tắt tiếng tất cả + + You’ve muted %s + + Bạn đã tắt tiếng tất cả các người tham gia + + You’ve been muted by %s + + Chi tiết gói đăng ký + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9c6e03b1ec..7484829c8b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5017,4 +5017,20 @@ + + 静音 + + 全部静音 + + 已全部静音 + + You’ve muted %s + + 您已将所有参与者设为静音 + + You’ve been muted by %s + + 订阅详情 + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c3a6c3a180..7e2a54c774 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4954,9 +4954,9 @@ [A]瞭解更多[/A] - %1$s已開始錄影 + %1$s已開始錄製 - %1$s已停止錄影 + %1$s已停止錄製 相簿 @@ -5017,4 +5017,20 @@ + + 靜音 + + 全部靜音 + + 已全部靜音 + + 您已將%s設為靜音 + + 您已將所有與會者設為靜音 + + %s已將您設為靜音 + + 訂閱詳情 + + Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen.You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index 366c16b814..66f446c85c 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported. + MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato. The folder you chose can’t be synced diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 1adaa2aa8d..f2116fbd63 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -51,13 +51,13 @@ Sync options - Clear solved issues + Clear resolved issues Two-way sync Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rename all items @@ -87,7 +87,7 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + No resolved issues No issues @@ -167,7 +167,7 @@ Issues - Solved issues + Resolved issues Set up a sync @@ -177,7 +177,7 @@ تحديد - A single file or folder had an issue that needs your decision to solve + A file or folder has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -197,7 +197,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index a45d81cac7..fd5ccd4506 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -35,13 +35,13 @@ Synchronisierungsoptionen - Gelöste Probleme entfernen + Clear resolved issues Zwei-Wege-Synchronisierung Conflict A - Es gibt mehrere Dateinamen auf der einen Seite, denen auf der anderen Seite ein einziger Name entsprechen würde. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Alle Elemente umbenennen @@ -71,7 +71,7 @@ Allow MEGA to read, modify or delete all files on this device. - Keine gelösten Probleme + No resolved issues No issues @@ -161,7 +161,7 @@ Auswählen - Ein Problem mit einer Datei oder einem Ordner erfordert Ihren Eingriff + A file or folder has an issue that needs your decision to resolve it Es wird auf den Abschluss anderer Prozesse gewartet @@ -181,7 +181,7 @@ Diese Datei hat Kopien, die im Konflikt stehen - Es gibt mehrere Dateinamen auf der einen Seite, denen auf der anderen Seite ein einziger Name entsprechen würde + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Ein Verschieben oder Umbenennen wurde auf MEGA erkannt, konnte jedoch lokal nicht repliziert werden. diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index 01476a0e72..0124140c81 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -39,13 +39,13 @@ Sync options - Clear solved issues + Clear resolved issues Two-way sync Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Renombrar todos los elementos @@ -75,7 +75,7 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + No resolved issues No issues @@ -155,7 +155,7 @@ Issues - Solved issues + Resolved issues Set up a sync @@ -165,7 +165,7 @@ Seleccionar - A single file or folder had an issue that needs your decision to solve + A file or folder has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -185,7 +185,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index 000734fb8c..f51c4f0cda 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -39,13 +39,13 @@ Options de synchronisation - Effacer les problèmes résolus + Clear resolved issues Synchronisation bidirectionnelle Conflict A - Plusieurs noms de fichiers d’un côté deviendraient tous le même nom unique de l’autre côté + Plusieurs éléments du même nom d’un côté de votre synchronisation deviendraient le même élément de l’autre côté de votre synchronisation Renommer tous les éléments @@ -75,7 +75,7 @@ Allow MEGA to read, modify or delete all files on this device. - Aucun problème résolu + No resolved issues Aucun blocage @@ -165,7 +165,7 @@ Choisir - Un fichier ou dossier présente un problème qui doit être résolu par vous. + A file or folder has an issue that needs your decision to resolve it Attente de la fin d’autres processus @@ -185,7 +185,7 @@ Ce fichier a des copies contradictoires - Plusieurs noms de fichiers d’un côté deviendraient tous le même nom unique de l’autre côté + Plusieurs éléments du même nom d’un côté de votre synchronisation deviendraient le même élément de l’autre côté de votre synchronisation Un déplacement ou un renommage a été détecté sur MEGA, mais n’a pas pu être reproduit localement. diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index 2c86857c1f..dcbd4034c2 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -31,13 +31,13 @@ Sync options - Clear solved issues + Clear resolved issues Two-way sync Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rename all items @@ -67,7 +67,7 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + No resolved issues No issues @@ -147,7 +147,7 @@ Issues - Solved issues + Resolved issues Set up a sync @@ -157,7 +157,7 @@ Pilih - A single file or folder had an issue that needs your decision to solve + A file or folder has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -177,7 +177,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index a3df9d5bf9..a90d7774e9 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -7,9 +7,9 @@ Sincronizza - Syncs [A](%1$d)[/A] + Sincronizzazioni [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to grant access. + Abbiamo bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per dare l\’accesso Per sincronizzare in modo continuo i tuoi file e le tue cartelle, permetti a MEGA di operare in background. @@ -39,23 +39,23 @@ Opzioni di sincronizzazione - Svuota i problemi risolti + Clear resolved issues Sincronizzazione a doppio senso Conflict A - Ci sono più nomi dei file da un lato che diverrebbero tutti lo stesso nome dall\’altro lato. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rinomina tutti gli oggetti Unisci le cartelle - Choose local file + Scegli il file locale - Choose remote file + Scegli il file remoto - Choose the last modified file + Scegli l\’ultimo file modificato Conflitti risolti @@ -67,17 +67,17 @@ Accedi a tutti i file - Battery optimisation + Ottimizzazione della batteria - Don’t allow + Non permettere Permetti Allow MEGA to read, modify or delete all files on this device. - Nessun problema risolto + No resolved issues - No issues + Nessun problema Dai un nome alla sincronizzazione @@ -103,7 +103,7 @@ Pausa - Resume + Riprendi Rimuovi @@ -113,7 +113,7 @@ Dovrai impostare una cartella locale su tuo\ndispositivo che sarà sincronizzata con una cartella scelta sul\ntuo Cloud Drive. - Monitoring syncs + Monitorizzazione delle sincronizzazioni Opzioni della sincronizzazione cambiate in: solo Wi-Fi @@ -121,7 +121,7 @@ No reason - File or folder issue + Problema di file o cartella Impossibile spostare o rinominare @@ -143,7 +143,7 @@ L\’oggetto remoto e l\’oggetto locale sono cambiati dopo l\’ultima sincronizzazione - File or folder conflict + Conflitto di file o cartella Conflitto del nome di file o cartella @@ -165,7 +165,7 @@ Seleziona - Un file o una cartella ha un problema che necessita della tua decisione per essere risolto + A file or folder has an issue that needs your decision to resolve it In attesa del completamento di altri processi @@ -185,7 +185,7 @@ Il file ha delle copie in conflitto - Ci sono più nomi dei file da un lato che diverrebbero tutti lo stesso nome dall\’altro lato. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync MEGA ha riscontrato uno spostamento o una rinominazione, ma non riesce a ripeterla localmente. diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index d6146eb455..1a9ac8ef38 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -37,7 +37,7 @@ Conflict A - 一方では複数のファイル名がありますが、もう一方ではすべて同じ1つの名前になります。 + 同期の一方の側に同じ名前の複数の項目がありますが、同期のもう一方の側ではすべて同じ1つの項目になります。 すべての項目の名前を変更する @@ -157,7 +157,7 @@ 選ぶ - 単一のファイルまたはフォルダに解決する決定が必要な問題がありました + あるファイルやフォルダに問題があり、それを解決するにはあなたの決定が必要です。 他のプロセスが完了するのを待っています @@ -177,7 +177,7 @@ このファイルには競合するコピーがあります - 一方では複数のファイル名がありますが、もう一方ではすべて同じ1つの名前になります + 同期の一方の側に同じ名前の複数の項目がありますが、同期のもう一方の側ではすべて同じ1つの項目になります。 MEGAで移動または名前変更が検出されましたが、ローカルで複製できませんでした。 diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 6aa65168a0..9e13d0dac5 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -31,13 +31,13 @@ 동기화 옵션 - 해결된 문제 지우기 + Clear resolved issues 양방향 동기화 Conflict A - 한쪽에서 여러 이름을 가지고 있는 경우가 있지만, 다른 쪽에서는 모두 같은 이름이 될 것입니다. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync 모든 항목 이름 변경 @@ -67,7 +67,7 @@ Allow MEGA to read, modify or delete all files on this device. - 해결된 문제 없음 + No resolved issues No issues @@ -157,7 +157,7 @@ 선택 - 한 개의 파일 또는 폴더에 문제가 있고 해결하기 위해 당신의 결정이 필요합니다 + A file or folder has an issue that needs your decision to resolve it 다른 프로세스가 완료되기를 기다리는 중입니다. @@ -177,7 +177,7 @@ 이 파일은 충돌하는 사본이 있습니다 - 한쪽에서 여러 이름을 가지고 있는 경우가 있지만, 다른 쪽에서는 모두 같은 이름이 될 것입니다 + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync MEGA에서 이동 또는 이름 변경을 감지하였지만, 로컬에 반영할 수 없었습니다 diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index 7476e93c15..421bdd41a8 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -35,13 +35,13 @@ Synchronisatie opties - Opgeloste problemen wissen + Clear resolved issues Tweezijdige synchronisatie Conflict A - Er zijn meerdere bestandsnamen aan de ene kant die aan de andere kant allemaal dezelfde naam zouden worden. + Er zijn meerdere items met dezelfde naam aan één kant van uw synchronisatie die allemaal één dezelfde bestand worden aan de andere kant van uw synchronisatie Hernoem alle items @@ -71,9 +71,9 @@ Allow MEGA to read, modify or delete all files on this device. - Geen opgeloste problemen + No resolved issues - No issues + Geen problemen Geef de synchronisatie een naam @@ -161,7 +161,7 @@ Selecteer - Er was een probleem met één bestand of map dat door u moet worden opgelost + A file or folder has an issue that needs your decision to resolve it Wachten tot andere processen zijn voltooid @@ -181,7 +181,7 @@ Dit bestand bevat conflicterende kopieën - Er zijn meerdere bestandsnamen aan de ene kant die aan de andere kant allemaal dezelfde naam zouden worden + Er zijn meerdere items met dezelfde naam aan één kant van uw synchronisatie die allemaal één dezelfde bestand worden aan de andere kant van uw synchronisatie Er is een verplaatsing of hernoeming gedetecteerd in MEGA, maar deze kon niet lokaal worden gerepliceerd. diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index 0ee3be5404..5e3f1fed1d 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -43,13 +43,13 @@ Opcje synchronizacji - Wyczyść rozwiązane problemy + Clear resolved issues Synchronizacja dwukierunkowa Conflict A - Istnieje wiele nazw plików po jednej stronie, które stałyby się tą samą pojedynczą nazwą po drugiej stronie. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Zmień nazwę wszystkich elementów @@ -79,7 +79,7 @@ Allow MEGA to read, modify or delete all files on this device. - Brak rozwiązanych problemów + No resolved issues Brak problemów @@ -169,7 +169,7 @@ Wybierz - W pojedynczym pliku lub katalogu wystąpił problem, którego rozwiązanie wymaga Twojej decyzji + A file or folder has an issue that needs your decision to resolve it Oczekiwanie na zakończenie innych procesów @@ -189,7 +189,7 @@ Ten plik ma sprzeczne kopie - Istnieje wiele nazw plików po jednej stronie, które stałyby się tą samą pojedynczą nazwą po drugiej stronie + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Przeniesienie lub zmiana nazwy zostały wykryte w MEGA, ale nie mogły zostać odtworzone lokalnie. diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index b794ceaa93..b0fadb04fe 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -45,7 +45,7 @@ Conflict A - Há vários nomes de arquivo em um lado que se tornariam todos o mesmo nome no outro lado. + Há vários itens com o mesmo nome em um lado da sincronização que se tornariam todos o mesmo item no outro lado da sincronização. Renomear todos os itens @@ -165,7 +165,7 @@ Selecionar - Um arquivo ou uma pasta teve um problema que precisa ser solucionado por você + Há um problema com um arquivo ou uma pasta que precisa de uma decisão sua para ser resolvido Esperando a conclusão de outros processos @@ -185,7 +185,7 @@ Este arquivo tem cópias conflitantes - Há vários nomes de arquivo em um lado que se tornariam todos o mesmo nome no outro lado + Há vários itens com o mesmo nome em um lado da sincronização que se tornariam todos o mesmo item no outro lado da sincronização. Uma movimentação ou renomeação foi detectada no MEGA, mas não foi possível replicá-la no dispositivo local. diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index d36412a2e4..096caf3d0f 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -39,13 +39,13 @@ Opțiuni de sincronizare - Ștergeți problemele rezolvate + Clear resolved issues Sincronizarea bidirecțională Conflict A - Există mai multe nume de fișiere pe o parte care ar deveni același nume unic pe cealaltă parte. + Există mai multe elemente cu același nume pe o parte a sincronizării dvs. care ar deveni toate același element unic pe cealaltă parte a sincronizării Redenumiți toate elementele @@ -75,7 +75,7 @@ Allow MEGA to read, modify or delete all files on this device. - Nicio problemă rezolvată + No resolved issues Nicio problemă @@ -165,7 +165,7 @@ Selectează - Un singur fișier sau folder a avut o problemă care necesită rezolvarea deciziei dvs. + A file or folder has an issue that needs your decision to resolve it În așteptarea finalizării altor procese @@ -185,7 +185,7 @@ Acest fișier are copii conflictuale - Există mai multe nume de fișiere pe o parte care ar deveni același nume unic pe cealaltă parte + Există mai multe elemente cu același nume pe o parte a sincronizării dvs. care ar deveni toate același element unic pe cealaltă parte a sincronizării O mutare sau redenumire a fost detectată în MEGA, dar nu a putut fi replicată local. diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index 601b6747fe..45e3802c70 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -43,13 +43,13 @@ Параметры синхронизации - Удалить решённые проблемы + Clear resolved issues Двухсторонняя синхронизация Conflict A - На одной стороне есть несколько названий файлов, которые на другой строне станут одинаковыми. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Переименовать все элементы @@ -79,7 +79,7 @@ Allow MEGA to read, modify or delete all files on this device. - Нет решённых проблем + No resolved issues Нет проблем @@ -169,7 +169,7 @@ Выбрать - С одним файлом или папкой возникла проблема, для решения которой требуется ваше решение + A file or folder has an issue that needs your decision to resolve it Ожидание завершения других процессов @@ -189,7 +189,7 @@ У этого файла есть конфликтующие копии - На одной стороне есть несколько названий файлов, которые на другой строне станут одинаковыми + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync В MEGA обнаружено перемещение или переименование, но его не удалось воспроизвести локально. diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index 3494753b48..046ae2cf37 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -9,7 +9,7 @@ ซิงค์ [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to grant access. + เราจำเป็นต้องเข้าถึงไฟล์ในเครื่องของคุณ เพื่อซิงค์รายการเหล่านั้นกับอุปกรณ์อื่น ๆ แตะที่นี่เพื่ออนุญาตให้เราเข้าถึง เพื่อให้การซิงค์ไฟล์และโฟลเดอร์ของคุณเป็นไปอย่างต่อเนื่อง คุณต้องอนุญาตให้ MEGA ทำงานในเบื้องหลัง @@ -37,7 +37,7 @@ Conflict A - ไฟล์เหล่านี้มีชื่อหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว + พบหลายรายการที่มีชื่อซ้ำกันหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว เปลี่ยนชื่อรายการทั้งหมด @@ -69,7 +69,7 @@ ปัญหาทั้งหมดได้รับการแก้ไขแล้ว - No issues + ยังไม่พบปัญหาใด ๆ ชื่อการซิงค์ @@ -157,7 +157,7 @@ เลือก - ไฟล์หรือโฟลเดอร์บางไฟล์มีปัญหา คุณต้องตัดสินใจว่าจะแก้ไขอย่างไร + ไฟล์หรือโฟลเดอร์มีปัญหาที่ต้องแก้ไข คุณต้องตัดสินใจว่าจะดำเนินการอย่างไร รอให้กระบวนการอื่นเสร็จสิ้นก่อน @@ -177,7 +177,7 @@ ไฟล์นี้มีสำเนาที่ขัดแย้งกัน - ไฟล์เหล่านี้มีชื่อหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว + พบหลายรายการที่มีชื่อซ้ำกันหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว มีการย้ายหรือเปลี่ยนชื่อไฟล์ใน MEGA แต่ไม่สามารถซิงค์กับอุปกรณ์ของคุณได้ diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index e5b4399fc3..3c6d755a84 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -31,13 +31,13 @@ Sync options - Clear solved issues + Clear resolved issues Two-way sync Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rename all items @@ -67,7 +67,7 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + No resolved issues No issues @@ -147,7 +147,7 @@ Issues - Solved issues + Resolved issues Set up a sync @@ -157,7 +157,7 @@ Chọn - A single file or folder had an issue that needs your decision to solve + A file or folder has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -177,7 +177,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index 51396fe2ee..b8f8e72019 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -31,13 +31,13 @@ 同步选项 - 清除已解决的问题 + Clear resolved issues 双向同步 Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync 重命名所有项目 @@ -67,7 +67,7 @@ Allow MEGA to read, modify or delete all files on this device. - 没有已解决问题 + No resolved issues No issues @@ -157,7 +157,7 @@ 选择 - 单个文件或文件夹存在需要您决定才能解决的问题 + A file or folder has an issue that needs your decision to resolve it 正在等待其它进程完成 @@ -177,7 +177,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 27ec0e0886..5e6daf5eb1 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -31,13 +31,13 @@ 同步選項 - 清除已解決的問題 + Clear resolved issues 雙向同步 Conflict A - 在一側有多個檔案名稱,這些檔名在另一側都會變成同一個名稱。 + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync 重新命名所有項目 @@ -67,7 +67,7 @@ Allow MEGA to read, modify or delete all files on this device. - 沒有已解決問題 + No resolved issues 沒有問題 @@ -157,7 +157,7 @@ 選擇 - 單一檔案或資料夾存在需要您的決定才能解決的問題單個檔案或資料夾存在需要您決定解決的問題 + A file or folder has an issue that needs your decision to resolve it 正在等待其它程序完成 @@ -177,7 +177,7 @@ 此檔案有衝突的副本 - 在一側有多個檔案名稱,這些檔名在另一側都會變成同一個名稱 + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync 在MEGA中偵測到移動或重新命名的變動,但無法在本地複製。 diff --git a/feature/sync/src/main/res/values/strings_sync_feature.xml b/feature/sync/src/main/res/values/strings_sync_feature.xml index eed1573a12..2972b24c02 100644 --- a/feature/sync/src/main/res/values/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values/strings_sync_feature.xml @@ -35,13 +35,13 @@ Sync options - Clear solved issues + Clear resolved issues Two-way sync Conflict A - There are multiple file names on one side that would all become the same single name on the other side. + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rename all items @@ -71,7 +71,7 @@ Allow MEGA to read, modify or delete all files on this device. - No solved issues + No resolved issues No issues @@ -151,7 +151,7 @@ Issues - Solved issues + Resolved issues Set up a sync @@ -161,7 +161,7 @@ Select - A single file or folder had an issue that needs your decision to solve + A file or folder has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -181,7 +181,7 @@ This file has conflicting copies - There are multiple file names on one side that would all become the same single name on the other side + There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync A move or rename was detected in MEGA, but couldn’t be replicated locally. From df2d717c4e8d69a3d1231a19875a8a617dfedaa6 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Wed, 21 Feb 2024 13:08:58 +1300 Subject: [PATCH 028/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 1be3b2b3d9..5c9ab5dc50 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240117.013801" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 77cb973d4c414b9daaa1d208728441fd14078715 Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Wed, 21 Feb 2024 22:57:05 +1300 Subject: [PATCH 029/261] CC-6287: Remove Image Preview feature flag --- .../app/presentation/photos/PhotosFragment.kt | 26 +++----- .../albumcontent/AlbumContentFragment.kt | 42 +++++-------- .../importlink/AlbumImportPreviewProvider.kt | 59 ++++++------------- .../mediadiscovery/MediaDiscoveryActivity.kt | 37 ++++-------- 4 files changed, 55 insertions(+), 109 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/PhotosFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/PhotosFragment.kt index 30a53ac62a..efb8d5048b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/PhotosFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/PhotosFragment.kt @@ -696,24 +696,14 @@ class PhotosFragment : Fragment() { private fun openPhoto(photo: Photo) { lifecycleScope.launch { - if (getFeatureFlagUseCase(AppFeatures.ImagePreview)) { - val intent = ImagePreviewActivity.createIntent( - context = requireContext(), - imageSource = ImagePreviewFetcherSource.TIMELINE, - menuOptionsSource = ImagePreviewMenuSource.TIMELINE, - anchorImageNodeId = NodeId(photo.id), - showScreenLabel = true, - ) - startActivity(intent) - } else { - val intent = ImageViewerActivity.getIntentForTimeline( - requireContext(), - currentNodeHandle = photo.id, - ) - - startActivity(intent) - managerActivity.overridePendingTransition(0, 0) - } + val intent = ImagePreviewActivity.createIntent( + context = requireContext(), + imageSource = ImagePreviewFetcherSource.TIMELINE, + menuOptionsSource = ImagePreviewMenuSource.TIMELINE, + anchorImageNodeId = NodeId(photo.id), + showScreenLabel = false, + ) + startActivity(intent) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentFragment.kt index b2f5ee4be7..8398d50d77 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentFragment.kt @@ -30,7 +30,6 @@ import kotlinx.coroutines.withContext import mega.privacy.android.analytics.Analytics import mega.privacy.android.app.R import mega.privacy.android.app.featuretoggle.AppFeatures -import mega.privacy.android.app.imageviewer.ImageViewerActivity import mega.privacy.android.app.main.ManagerActivity import mega.privacy.android.app.presentation.extensions.isDarkMode import mega.privacy.android.app.presentation.imagepreview.ImagePreviewActivity @@ -191,34 +190,25 @@ class AlbumContentFragment : Fragment() { private fun openPhotoPreview(anchorPhoto: Photo, photos: List) { albumContentViewModel.state.value.uiAlbum?.id?.let { currentAlbum -> lifecycleScope.launch { - if (getFeatureFlagValueUseCase(AppFeatures.ImagePreview)) { - val params = buildMap { - this[AlbumContentImageNodeFetcher.ALBUM_TYPE] = currentAlbum.getAlbumType() + val params = buildMap { + this[AlbumContentImageNodeFetcher.ALBUM_TYPE] = currentAlbum.getAlbumType() - if (currentAlbum is UserAlbum) { - this[AlbumContentImageNodeFetcher.CUSTOM_ALBUM_ID] = currentAlbum.id.id - } - - this[AlbumContentImageNodeFetcher.ALBUM_SORT_TYPE] = - albumContentViewModel.state.value.currentSort + if (currentAlbum is UserAlbum) { + this[AlbumContentImageNodeFetcher.CUSTOM_ALBUM_ID] = currentAlbum.id.id } - val intent = ImagePreviewActivity.createIntent( - context = requireContext(), - imageSource = ImagePreviewFetcherSource.ALBUM_CONTENT, - menuOptionsSource = ImagePreviewMenuSource.ALBUM_CONTENT, - anchorImageNodeId = NodeId(anchorPhoto.id), - params = params, - ) - startActivity(intent) - } else { - val intent = ImageViewerActivity.getIntentForChildren( - requireContext(), - photos.map { it.id }.toLongArray(), - anchorPhoto.id, - ) - startActivity(intent) - managerActivity.overridePendingTransition(0, 0) + + this[AlbumContentImageNodeFetcher.ALBUM_SORT_TYPE] = + albumContentViewModel.state.value.currentSort } + val intent = ImagePreviewActivity.createIntent( + context = requireContext(), + imageSource = ImagePreviewFetcherSource.ALBUM_CONTENT, + menuOptionsSource = ImagePreviewMenuSource.ALBUM_CONTENT, + anchorImageNodeId = NodeId(anchorPhoto.id), + params = params, + showScreenLabel = false, + ) + startActivity(intent) } } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/importlink/AlbumImportPreviewProvider.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/importlink/AlbumImportPreviewProvider.kt index 46e610029c..7b5bf63068 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/importlink/AlbumImportPreviewProvider.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/importlink/AlbumImportPreviewProvider.kt @@ -10,8 +10,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import mega.privacy.android.app.MimeTypeList import mega.privacy.android.app.domain.usecase.GetNodeByHandle -import mega.privacy.android.app.featuretoggle.AppFeatures -import mega.privacy.android.app.imageviewer.ImageViewerActivity import mega.privacy.android.app.presentation.imagepreview.ImagePreviewActivity import mega.privacy.android.app.presentation.imagepreview.fetcher.MediaDiscoveryImageNodeFetcher.Companion.IS_RECURSIVE import mega.privacy.android.app.presentation.imagepreview.fetcher.MediaDiscoveryImageNodeFetcher.Companion.PARENT_ID @@ -101,29 +99,19 @@ class AlbumImportPreviewProvider @Inject constructor( folderNodeId: Long?, ) { (activity as LifecycleOwner).lifecycleScope.launch { - if (getFeatureFlagValueUseCase(AppFeatures.ImagePreview)) { - folderNodeId?.let { parentID -> - monitorSubFolderMediaDiscoverySettingsUseCase().collectLatest { recursive -> - ImagePreviewActivity.createIntent( - context = activity, - imageSource = ImagePreviewFetcherSource.MEDIA_DISCOVERY, - menuOptionsSource = ImagePreviewMenuSource.MEDIA_DISCOVERY, - anchorImageNodeId = NodeId(photo.id), - params = mapOf(PARENT_ID to parentID, IS_RECURSIVE to recursive), - ).run { - activity.startActivity(this) - } + folderNodeId?.let { parentID -> + monitorSubFolderMediaDiscoverySettingsUseCase().collectLatest { recursive -> + ImagePreviewActivity.createIntent( + context = activity, + imageSource = ImagePreviewFetcherSource.MEDIA_DISCOVERY, + menuOptionsSource = ImagePreviewMenuSource.MEDIA_DISCOVERY, + anchorImageNodeId = NodeId(photo.id), + params = mapOf(PARENT_ID to parentID, IS_RECURSIVE to recursive), + showScreenLabel = false, + ).run { + activity.startActivity(this) } } - } else { - ImageViewerActivity.getIntentForChildren( - activity, - photoIds.toLongArray(), - photo.id, - ).run { - activity.startActivity(this) - } - activity.overridePendingTransition(0, 0) } } } @@ -132,23 +120,14 @@ class AlbumImportPreviewProvider @Inject constructor( activity: Activity, photo: Photo, ) = (activity as LifecycleOwner).lifecycleScope.launch { - if (getFeatureFlagValueUseCase(AppFeatures.ImagePreview)) { - val intent = ImagePreviewActivity.createIntent( - context = activity, - imageSource = ImagePreviewFetcherSource.ALBUM_SHARING, - menuOptionsSource = ImagePreviewMenuSource.ALBUM_SHARING, - anchorImageNodeId = NodeId(photo.id), - ) - activity.startActivity(intent) - } else { - ImageViewerActivity.getIntentForAlbumSharing( - activity, - photo.id, - ).run { - activity.startActivity(this) - } - activity.overridePendingTransition(0, 0) - } + val intent = ImagePreviewActivity.createIntent( + context = activity, + imageSource = ImagePreviewFetcherSource.ALBUM_SHARING, + menuOptionsSource = ImagePreviewMenuSource.ALBUM_SHARING, + anchorImageNodeId = NodeId(photo.id), + showScreenLabel = false, + ) + activity.startActivity(intent) } /** diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryActivity.kt index 57c8a4fbad..7ade5028ed 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryActivity.kt @@ -25,8 +25,6 @@ import mega.privacy.android.app.MimeTypeList import mega.privacy.android.app.R import mega.privacy.android.app.activities.contract.NameCollisionActivityContract import mega.privacy.android.app.components.saver.NodeSaver -import mega.privacy.android.app.featuretoggle.AppFeatures -import mega.privacy.android.app.imageviewer.ImageViewerActivity import mega.privacy.android.app.interfaces.PermissionRequester import mega.privacy.android.app.interfaces.SnackbarShower import mega.privacy.android.app.main.FileExplorerActivity @@ -266,29 +264,18 @@ class MediaDiscoveryActivity : BaseActivity(), PermissionRequester, SnackbarShow private fun openPhoto(photo: Photo) { lifecycleScope.launch { - if (getFeatureFlagValueUseCase(AppFeatures.ImagePreview)) { - ImagePreviewActivity.createIntent( - context = this@MediaDiscoveryActivity, - imageSource = ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY, - menuOptionsSource = ImagePreviewMenuSource.FOLDER_LINK, - anchorImageNodeId = NodeId(photo.id), - isForeign = true, - params = mapOf( - FolderLinkMediaDiscoveryImageNodeFetcher.PARENT_ID to mediaHandle, - ), - ).run { - startActivity(this) - } - } else { - ImageViewerActivity.getIntentForChildren( - this@MediaDiscoveryActivity, - mediaDiscoveryViewModel.getAllPhotoIds().toLongArray(), - photo.id, - fromFolderLink = true, - ).run { - startActivity(this) - } - overridePendingTransition(0, 0) + ImagePreviewActivity.createIntent( + context = this@MediaDiscoveryActivity, + imageSource = ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY, + menuOptionsSource = ImagePreviewMenuSource.FOLDER_LINK, + anchorImageNodeId = NodeId(photo.id), + isForeign = true, + params = mapOf( + FolderLinkMediaDiscoveryImageNodeFetcher.PARENT_ID to mediaHandle, + ), + showScreenLabel = false, + ).run { + startActivity(this) } } } From 0863fe853c88f10abd7143570de40d06665f20bc Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Thu, 22 Feb 2024 14:36:25 +1300 Subject: [PATCH 030/261] CC-6287: Fix Image Preview UI test failed issue --- .../view/ImagePreviewBottomSheet.kt | 37 +++++++++-- .../imagepreview/view/ImagePreviewScreen.kt | 19 +++++- .../imagepreview/view/TestTagConstants.kt | 65 +++++++++++++++++++ 3 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/TestTagConstants.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt index 9ad3222389..cf6a41ca4e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.MaterialTheme import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -24,6 +23,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -37,13 +37,12 @@ import mega.privacy.android.app.utils.MegaNodeUtil import mega.privacy.android.app.utils.MegaNodeUtil.getInfoText import mega.privacy.android.core.R.drawable.link_ic import mega.privacy.android.core.ui.controls.sheets.BottomSheet -import mega.privacy.android.core.ui.theme.extensions.textColorPrimary -import mega.privacy.android.core.ui.theme.extensions.textColorSecondary +import mega.privacy.android.core.ui.controls.text.MiddleEllipsisText +import mega.privacy.android.core.ui.theme.tokens.TextColor import mega.privacy.android.domain.entity.imageviewer.ImageResult import mega.privacy.android.domain.entity.node.ImageNode import mega.privacy.android.legacy.core.ui.controls.controlssliders.MegaSwitch import mega.privacy.android.legacy.core.ui.controls.lists.MenuActionListTile -import mega.privacy.android.legacy.core.ui.controls.text.MiddleEllipsisText import nz.mega.sdk.MegaNode @OptIn(ExperimentalMaterialApi::class) @@ -198,6 +197,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.general_info), onActionClicked = onClickInfo, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_INFO), ) } if (isFavouriteMenuVisible) { @@ -216,6 +216,7 @@ internal fun ImagePreviewBottomSheet( }, onActionClicked = onClickFavourite, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_FAVOURITE), ) } @@ -245,6 +246,7 @@ internal fun ImagePreviewBottomSheet( } } }, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_LABEL), ) } @@ -256,6 +258,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.dispute_takendown_file), onActionClicked = onClickDispute, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_DISPUTE), ) } @@ -265,6 +268,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.external_play), onActionClicked = onClickOpenWith, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_OPEN_WITH), ) } @@ -276,6 +280,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.forward_menu_item), onActionClicked = onClickForward, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_FORWARD), ) } @@ -285,6 +290,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.general_save_to_device), onActionClicked = onClickSaveToDevice, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SAVE_TO_DEVICE), ) } @@ -294,6 +300,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.general_import), onActionClicked = onClickImport, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_IMPORT), ) } @@ -302,6 +309,9 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.file_properties_available_offline), icon = painterResource(id = R.drawable.ic_save_offline), addSeparator = false, + modifier = Modifier.testTag( + IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_AVAILABLE_OFFLINE + ), ) { MegaSwitch( checked = isAvailableOffline, @@ -325,6 +335,7 @@ internal fun ImagePreviewBottomSheet( }, onActionClicked = onClickGetLink, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_GET_LINK), ) } @@ -334,6 +345,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.context_remove_link_menu), onActionClicked = onClickRemoveLink, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE_LINK), ) } @@ -343,6 +355,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.context_send_file_to_chat), onActionClicked = onClickSendToChat, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SEND_TO_CHAT), ) } @@ -352,6 +365,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.general_share), onActionClicked = onClickShare, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SHARE), ) } @@ -363,6 +377,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.context_rename), onActionClicked = onClickRename, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_RENAME), ) } @@ -372,6 +387,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.general_move), onActionClicked = onClickMove, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_MOVE), ) } @@ -383,6 +399,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.context_copy), onActionClicked = onClickCopy, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_COPY), ) } @@ -392,6 +409,7 @@ internal fun ImagePreviewBottomSheet( text = stringResource(id = R.string.context_restore), onActionClicked = onClickRestore, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_RESTORE), ) } @@ -402,6 +420,7 @@ internal fun ImagePreviewBottomSheet( isDestructive = true, onActionClicked = onClickRemove, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE), ) } @@ -412,6 +431,7 @@ internal fun ImagePreviewBottomSheet( onActionClicked = { onSwitchAvailableOffline(false) }, isDestructive = true, addSeparator = false, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE_OFFLINE), ) } @@ -422,6 +442,9 @@ internal fun ImagePreviewBottomSheet( onActionClicked = onClickMoveToRubbishBin, addSeparator = false, isDestructive = true, + modifier = Modifier.testTag( + IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_MOVE_TO_RUBBISH_BIN + ), ) } } @@ -464,11 +487,13 @@ private fun ImagePreviewMenuActionHeader( ) { MiddleEllipsisText( text = imageNode.name, - color = MaterialTheme.colors.textColorPrimary, + color = TextColor.Primary, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_HEADER_TEXT_NAME), ) MiddleEllipsisText( text = imageInfo.orEmpty(), - color = MaterialTheme.colors.textColorSecondary, + color = TextColor.Secondary, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_SHEET_HEADER_TEXT_INFO), ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewScreen.kt index 3f532c2fe5..6c6362710f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewScreen.kt @@ -1,4 +1,7 @@ -@file:OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class) +@file:OptIn( + ExperimentalFoundationApi::class, ExperimentalMaterialApi::class, + ExperimentalComposeUiApi::class +) package mega.privacy.android.app.presentation.imagepreview.view @@ -44,13 +47,17 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -235,6 +242,8 @@ internal fun ImagePreviewScreen( } Scaffold( + modifier = Modifier + .semantics { testTagsAsResourceId = true }, scaffoldState = scaffoldState, snackbarHost = { snackBarHostState -> SnackbarHost( @@ -599,6 +608,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_arrow_back_white), contentDescription = "Image Preview Back", tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_BACK), ) } }, @@ -629,6 +639,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_slideshow), contentDescription = null, tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_SLIDESHOW), ) } } @@ -639,6 +650,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_download_white), contentDescription = null, tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_SAVE_TO_DEVICE), ) } } @@ -649,6 +661,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_link), contentDescription = null, tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_MANAGE_LINK), ) } } @@ -659,6 +672,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_send_to_contact), contentDescription = null, tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_SEND_TO), ) } } @@ -669,6 +683,7 @@ private fun ImagePreviewTopBar( painter = painterResource(id = R.drawable.ic_dots_vertical_white), contentDescription = null, tint = MaterialTheme.colors.black_white, + modifier = Modifier.testTag(IMAGE_PREVIEW_APP_BAR_MORE), ) } } @@ -695,10 +710,12 @@ private fun ImagePreviewBottomBar( MiddleEllipsisText( text = imageName, color = TextColor.Secondary, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_BAR_TEXT_IMAGE_NAME), ) MiddleEllipsisText( text = imageIndex, color = TextColor.Secondary, + modifier = Modifier.testTag(IMAGE_PREVIEW_BOTTOM_BAR_TEXT_IMAGE_COUNT), ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/TestTagConstants.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/TestTagConstants.kt new file mode 100644 index 0000000000..a1ff5c29a7 --- /dev/null +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/TestTagConstants.kt @@ -0,0 +1,65 @@ +package mega.privacy.android.app.presentation.imagepreview.view + +/** AppBar options test tags */ +internal const val IMAGE_PREVIEW_APP_BAR_BACK = "image_preview_app_bar:icon_back" +internal const val IMAGE_PREVIEW_APP_BAR_SLIDESHOW = "image_preview_app_bar:icon_slideshow" +internal const val IMAGE_PREVIEW_APP_BAR_SAVE_TO_DEVICE = + "image_preview_app_bar:icon_save_to_device" +internal const val IMAGE_PREVIEW_APP_BAR_MANAGE_LINK = "image_preview_app_bar:icon_manage_link" +internal const val IMAGE_PREVIEW_APP_BAR_SEND_TO = "image_preview_app_bar:icon_send_to" +internal const val IMAGE_PREVIEW_APP_BAR_MORE = "image_preview_app_bar:icon_more" +/** AppBar options test tags */ + +/** BottomBar options test tags */ +internal const val IMAGE_PREVIEW_BOTTOM_BAR_TEXT_IMAGE_NAME = + "image_preview_bottom_bar:middle_ellipsis_text_name" +internal const val IMAGE_PREVIEW_BOTTOM_BAR_TEXT_IMAGE_COUNT = + "image_preview_bottom_bar:middle_ellipsis_text_count" +/** BottomBar options test tags */ + +/** BottomSheet options test tags */ +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_INFO = + "image_preview_bottom_sheet_option:menu_action_list_tile_info" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_FAVOURITE = + "image_preview_bottom_sheet_option:menu_action_list_tile_favourite" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_LABEL = + "image_preview_bottom_sheet_option:menu_action_list_tile_label" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_DISPUTE = + "image_preview_bottom_sheet_option:menu_action_list_tile_dispute" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_OPEN_WITH = + "image_preview_bottom_sheet_option:menu_action_list_tile_open_with" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_FORWARD = + "image_preview_bottom_sheet_option:menu_action_list_tile_forward" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SAVE_TO_DEVICE = + "image_preview_bottom_sheet_option:menu_action_list_tile_save_to_device" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_IMPORT = + "image_preview_bottom_sheet_option:menu_action_list_tile_import" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_AVAILABLE_OFFLINE = + "image_preview_bottom_sheet_option:menu_action_list_tile_available_offline" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_GET_LINK = + "image_preview_bottom_sheet_option:menu_action_list_tile_get_link" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE_LINK = + "image_preview_bottom_sheet_option:menu_action_list_tile_remove_link" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SEND_TO_CHAT = + "image_preview_bottom_sheet_option:menu_action_list_tile_send_to_chat" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_SHARE = + "image_preview_bottom_sheet_option:menu_action_list_tile_share" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_RENAME = + "image_preview_bottom_sheet_option:menu_action_list_tile_rename" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_MOVE = + "image_preview_bottom_sheet_option:menu_action_list_tile_move" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_COPY = + "image_preview_bottom_sheet_option:menu_action_list_tile_copy" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_RESTORE = + "image_preview_bottom_sheet_option:menu_action_list_tile_restore" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE = + "image_preview_bottom_sheet_option:menu_action_list_tile_remove" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_REMOVE_OFFLINE = + "image_preview_bottom_sheet_option:menu_action_list_tile_remove_offline" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_OPTION_MOVE_TO_RUBBISH_BIN = + "image_preview_bottom_sheet_option:menu_action_list_tile_move_to_rubbish_bin" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_HEADER_TEXT_NAME = + "image_preview_bottom_sheet_header:middle_ellipsis_text_name" +internal const val IMAGE_PREVIEW_BOTTOM_SHEET_HEADER_TEXT_INFO = + "image_preview_bottom_sheet_header:middle_ellipsis_text_info" +/** BottomSheet options test tags */ From ab988ee16e1c594158ba45094438d34a4b6f7859 Mon Sep 17 00:00:00 2001 From: Michal Wojciechowski Date: Wed, 28 Feb 2024 10:49:20 +1300 Subject: [PATCH 031/261] Feature/gitleaks secret scanning pipeline added --- .gitlab-ci.yml | 13 + .gitleaks/gitleaks.toml | 2847 +++++++++++++++++++++++++++++++++++++++ .gitleaksignore | 157 +++ 3 files changed, 3017 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 .gitleaks/gitleaks.toml create mode 100644 .gitleaksignore diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000..1930eb6359 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,13 @@ +variables: + GIT_STRATEGY: clone + +stages: + - scan + +scan: + stage: scan + image: + name: mega-docker.artifactory.developers.mega.co.nz:8443/gitleaks:v8.18.2-mega-1.0 + entrypoint: [""] + script: + - gitleaks detect -v --redact -c .gitleaks/gitleaks.toml diff --git a/.gitleaks/gitleaks.toml b/.gitleaks/gitleaks.toml new file mode 100644 index 0000000000..9c1d21b425 --- /dev/null +++ b/.gitleaks/gitleaks.toml @@ -0,0 +1,2847 @@ +# This file has been auto-generated. Do not edit manually. +# If you would like to contribute new rules, please use +# cmd/generate/config/main.go and follow the contributing guidelines +# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md + +# This is the default gitleaks configuration file. +# Rules and allowlists are defined within this file. +# Rules instruct gitleaks on what should be considered a secret. +# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. + +title = "gitleaks config" + +[allowlist] +description = "global allow lists" +paths = [ + '''gitleaks.toml''', + '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket|vsidx|v2|suo|wsuo|.dll|pdb|exe)$''', + '''(go.mod|go.sum)$''', + '''gradle.lockfile''', + '''node_modules''', + '''package-lock.json''', + '''yarn.lock''', + '''pnpm-lock.yaml''', + '''Database.refactorlog''', + '''vendor''', +] + +[[rules]] +id = "adafruit-api-key" +description = "Identified a potential Adafruit API Key, which could lead to unauthorized access to Adafruit services and sensitive data exposure." +regex = '''(?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "adafruit", +] + +[[rules]] +id = "adobe-client-id" +description = "Detected a pattern that resembles an Adobe OAuth Web Client ID, posing a risk of compromised Adobe integrations and data breaches." +regex = '''(?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "adobe", +] + +[[rules]] +id = "adobe-client-secret" +description = "Discovered a potential Adobe Client Secret, which, if exposed, could allow unauthorized Adobe service access and data manipulation." +regex = '''(?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "p8e-", +] + +[[rules]] +id = "age secret key" +description = "Discovered a potential Age encryption tool secret key, risking data decryption and unauthorized access to sensitive information." +regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}''' +keywords = [ + "age-secret-key-1", +] + +[[rules]] +id = "airtable-api-key" +description = "Uncovered a possible Airtable API Key, potentially compromising database access and leading to data leakage or alteration." +regex = '''(?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "airtable", +] + +[[rules]] +id = "algolia-api-key" +description = "Identified an Algolia API Key, which could result in unauthorized search operations and data exposure on Algolia-managed platforms." +regex = '''(?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "algolia", +] + +[[rules]] +id = "alibaba-access-key-id" +description = "Detected an Alibaba Cloud AccessKey ID, posing a risk of unauthorized cloud resource access and potential data compromise." +regex = '''(?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ltai", +] + +[[rules]] +id = "alibaba-secret-key" +description = "Discovered a potential Alibaba Cloud Secret Key, potentially allowing unauthorized operations and data access within Alibaba Cloud." +regex = '''(?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "alibaba", +] + +[[rules]] +id = "asana-client-id" +description = "Discovered a potential Asana Client ID, risking unauthorized access to Asana projects and sensitive task information." +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "asana", +] + +[[rules]] +id = "asana-client-secret" +description = "Identified an Asana Client Secret, which could lead to compromised project management integrity and unauthorized access." +regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "asana", +] + +[[rules]] +id = "atlassian-api-token" +description = "Detected an Atlassian API token, posing a threat to project management and collaboration tool security and data confidentiality." +regex = '''(?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "atlassian","confluence","jira", +] + +[[rules]] +id = "authress-service-client-access-key" +description = "Uncovered a possible Authress Service Client Access Key, which may compromise access control services and sensitive data." +regex = '''(?i)\b((?:sc|ext|scauth|authress)_[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.acc[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sc_","ext_","scauth_","authress_", +] + +[[rules]] +id = "aws-access-token" +description = "Identified a pattern that may indicate AWS credentials, risking unauthorized cloud resource access and data breaches on AWS platforms." +regex = '''(?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}''' +keywords = [ + "akia","asia","abia","acca", +] + +[[rules]] +id = "beamer-api-token" +description = "Detected a Beamer API token, potentially compromising content management and exposing sensitive notifications and updates." +regex = '''(?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "beamer", +] + +[[rules]] +id = "bitbucket-client-id" +description = "Discovered a potential Bitbucket Client ID, risking unauthorized repository access and potential codebase exposure." +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "bitbucket", +] + +[[rules]] +id = "bitbucket-client-secret" +description = "Discovered a potential Bitbucket Client Secret, posing a risk of compromised code repositories and unauthorized access." +regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "bitbucket", +] + +[[rules]] +id = "bittrex-access-key" +description = "Identified a Bittrex Access Key, which could lead to unauthorized access to cryptocurrency trading accounts and financial loss." +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "bittrex", +] + +[[rules]] +id = "bittrex-secret-key" +description = "Detected a Bittrex Secret Key, potentially compromising cryptocurrency transactions and financial security." +regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "bittrex", +] + +[[rules]] +id = "clojars-api-token" +description = "Uncovered a possible Clojars API token, risking unauthorized access to Clojure libraries and potential code manipulation." +regex = '''(?i)(CLOJARS_)[a-z0-9]{60}''' +keywords = [ + "clojars", +] + +[[rules]] +id = "codecov-access-token" +description = "Found a pattern resembling a Codecov Access Token, posing a risk of unauthorized access to code coverage reports and sensitive data." +regex = '''(?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "codecov", +] + +[[rules]] +id = "coinbase-access-token" +description = "Detected a Coinbase Access Token, posing a risk of unauthorized access to cryptocurrency accounts and financial transactions." +regex = '''(?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "coinbase", +] + +[[rules]] +id = "confluent-access-token" +description = "Identified a Confluent Access Token, which could compromise access to streaming data platforms and sensitive data flow." +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "confluent", +] + +[[rules]] +id = "confluent-secret-key" +description = "Found a Confluent Secret Key, potentially risking unauthorized operations and data access within Confluent services." +regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "confluent", +] + +[[rules]] +id = "contentful-delivery-api-token" +description = "Discovered a Contentful delivery API token, posing a risk to content management systems and data integrity." +regex = '''(?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "contentful", +] + +[[rules]] +id = "databricks-api-token" +description = "Uncovered a Databricks API token, which may compromise big data analytics platforms and sensitive data processing." +regex = '''(?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dapi", +] + +[[rules]] +id = "datadog-access-token" +description = "Detected a Datadog Access Token, potentially risking monitoring and analytics data exposure and manipulation." +regex = '''(?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "datadog", +] + +[[rules]] +id = "defined-networking-api-token" +description = "Identified a Defined Networking API token, which could lead to unauthorized network operations and data breaches." +regex = '''(?i)(?:dnkey)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dnkey", +] + +[[rules]] +id = "digitalocean-access-token" +description = "Found a DigitalOcean OAuth Access Token, risking unauthorized cloud resource access and data compromise." +regex = '''(?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "doo_v1_", +] + +[[rules]] +id = "digitalocean-pat" +description = "Discovered a DigitalOcean Personal Access Token, posing a threat to cloud infrastructure security and data privacy." +regex = '''(?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dop_v1_", +] + +[[rules]] +id = "digitalocean-refresh-token" +description = "Uncovered a DigitalOcean OAuth Refresh Token, which could allow prolonged unauthorized access and resource manipulation." +regex = '''(?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dor_v1_", +] + +[[rules]] +id = "discord-api-token" +description = "Detected a Discord API key, potentially compromising communication channels and user data privacy on Discord." +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "discord", +] + +[[rules]] +id = "discord-client-id" +description = "Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications." +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "discord", +] + +[[rules]] +id = "discord-client-secret" +description = "Discovered a potential Discord client secret, risking compromised Discord bot integrations and data leaks." +regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "discord", +] + +[[rules]] +id = "doppler-api-token" +description = "Discovered a Doppler API token, posing a risk to environment and secrets management security." +regex = '''(dp\.pt\.)(?i)[a-z0-9]{43}''' +keywords = [ + "doppler", +] + +[[rules]] +id = "droneci-access-token" +description = "Detected a Droneci Access Token, potentially compromising continuous integration and deployment workflows." +regex = '''(?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "droneci", +] + +[[rules]] +id = "dropbox-api-token" +description = "Identified a Dropbox API secret, which could lead to unauthorized file access and data breaches in Dropbox storage." +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +id = "dropbox-long-lived-api-token" +description = "Found a Dropbox long-lived API token, risking prolonged unauthorized access to cloud storage and sensitive data." +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +id = "dropbox-short-lived-api-token" +description = "Discovered a Dropbox short-lived API token, posing a risk of temporary but potentially harmful data access and manipulation." +regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "dropbox", +] + +[[rules]] +id = "duffel-api-token" +description = "Uncovered a Duffel API token, which may compromise travel platform integrations and sensitive customer data." +regex = '''duffel_(test|live)_(?i)[a-z0-9_\-=]{43}''' +keywords = [ + "duffel", +] + +[[rules]] +id = "dynatrace-api-token" +description = "Detected a Dynatrace API token, potentially risking application performance monitoring and data exposure." +regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}''' +keywords = [ + "dynatrace", +] + +[[rules]] +id = "easypost-api-token" +description = "Identified an EasyPost API token, which could lead to unauthorized postal and shipment service access and data exposure." +regex = '''\bEZAK(?i)[a-z0-9]{54}''' +keywords = [ + "ezak", +] + +[[rules]] +id = "easypost-test-api-token" +description = "Detected an EasyPost test API token, risking exposure of test environments and potentially sensitive shipment data." +regex = '''\bEZTK(?i)[a-z0-9]{54}''' +keywords = [ + "eztk", +] + +[[rules]] +id = "etsy-access-token" +description = "Found an Etsy Access Token, potentially compromising Etsy shop management and customer data." +regex = '''(?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "etsy", +] + +[[rules]] +id = "facebook" +description = "Discovered a Facebook Access Token, posing a risk of unauthorized access to Facebook accounts and personal data exposure." +regex = '''(?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "facebook", +] + +[[rules]] +id = "fastly-api-token" +description = "Uncovered a Fastly API key, which may compromise CDN and edge cloud services, leading to content delivery and security issues." +regex = '''(?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "fastly", +] + +[[rules]] +id = "finicity-api-token" +description = "Detected a Finicity API token, potentially risking financial data access and unauthorized financial operations." +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "finicity", +] + +[[rules]] +id = "finicity-client-secret" +description = "Identified a Finicity Client Secret, which could lead to compromised financial service integrations and data breaches." +regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "finicity", +] + +[[rules]] +id = "finnhub-access-token" +description = "Found a Finnhub Access Token, risking unauthorized access to financial market data and analytics." +regex = '''(?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "finnhub", +] + +[[rules]] +id = "flickr-access-token" +description = "Discovered a Flickr Access Token, posing a risk of unauthorized photo management and potential data leakage." +regex = '''(?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "flickr", +] + +[[rules]] +id = "flutterwave-encryption-key" +description = "Uncovered a Flutterwave Encryption Key, which may compromise payment processing and sensitive financial information." +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{12}''' +keywords = [ + "flwseck_test", +] + +[[rules]] +id = "flutterwave-public-key" +description = "Detected a Finicity Public Key, potentially exposing public cryptographic operations and integrations." +regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwpubk_test", +] + +[[rules]] +id = "flutterwave-secret-key" +description = "Identified a Flutterwave Secret Key, risking unauthorized financial transactions and data breaches." +regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X''' +keywords = [ + "flwseck_test", +] + +[[rules]] +id = "frameio-api-token" +description = "Found a Frame.io API token, potentially compromising video collaboration and project management." +regex = '''fio-u-(?i)[a-z0-9\-_=]{64}''' +keywords = [ + "fio-u-", +] + +[[rules]] +id = "freshbooks-access-token" +description = "Discovered a Freshbooks Access Token, posing a risk to accounting software access and sensitive financial data exposure." +regex = '''(?i)(?:freshbooks)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "freshbooks", +] + +[[rules]] +id = "gcp-api-key" +description = "Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches." +regex = '''(?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "aiza", +] + +[[rules]] +id = "generic-api-key" +description = "Detected a Generic API Key, potentially exposing access to various services and sensitive operations." +regex = '''(?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-z\-_.=]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +entropy = 3.5 +keywords = [ + "key","api","token","secret","client","passwd","password","auth","access", +] + +[rules.allowlist] +stopwords = [ + "000000", + "aaaaaa", + "about", + "abstract", + "academy", + "acces", + "account", + "act-", + "act.", + "act_", + "action", + "active", + "actively", + "activity", + "adapter", + "add-", + "add.", + "add_", + "add-on", + "addon", + "addres", + "admin", + "adobe", + "advanced", + "adventure", + "agent", + "agile", + "air-", + "air.", + "air_", + "ajax", + "akka", + "alert", + "alfred", + "algorithm", + "all-", + "all.", + "all_", + "alloy", + "alpha", + "amazon", + "amqp", + "analysi", + "analytic", + "analyzer", + "android", + "angular", + "angularj", + "animate", + "animation", + "another", + "ansible", + "answer", + "ant-", + "ant.", + "ant_", + "any-", + "any.", + "any_", + "apache", + "app-", + "app-", + "app.", + "app.", + "app_", + "app_", + "apple", + "arch", + "archive", + "archived", + "arduino", + "array", + "art-", + "art.", + "art_", + "article", + "asp-", + "asp.", + "asp_", + "asset", + "async", + "atom", + "attention", + "audio", + "audit", + "aura", + "auth", + "author", + "author", + "authorize", + "auto", + "automated", + "automatic", + "awesome", + "aws_", + "azure", + "back", + "backbone", + "backend", + "backup", + "bar-", + "bar.", + "bar_", + "base", + "based", + "bash", + "basic", + "batch", + "been", + "beer", + "behavior", + "being", + "benchmark", + "best", + "beta", + "better", + "big-", + "big.", + "big_", + "binary", + "binding", + "bit-", + "bit.", + "bit_", + "bitcoin", + "block", + "blog", + "board", + "book", + "bookmark", + "boost", + "boot", + "bootstrap", + "bosh", + "bot-", + "bot.", + "bot_", + "bower", + "box-", + "box.", + "box_", + "boxen", + "bracket", + "branch", + "bridge", + "browser", + "brunch", + "buffer", + "bug-", + "bug.", + "bug_", + "build", + "builder", + "building", + "buildout", + "buildpack", + "built", + "bundle", + "busines", + "but-", + "but.", + "but_", + "button", + "cache", + "caching", + "cakephp", + "calendar", + "call", + "camera", + "campfire", + "can-", + "can.", + "can_", + "canva", + "captcha", + "capture", + "card", + "carousel", + "case", + "cassandra", + "cat-", + "cat.", + "cat_", + "category", + "center", + "cento", + "challenge", + "change", + "changelog", + "channel", + "chart", + "chat", + "cheat", + "check", + "checker", + "chef", + "ches", + "chinese", + "chosen", + "chrome", + "ckeditor", + "clas", + "classe", + "classic", + "clean", + "cli-", + "cli.", + "cli_", + "client", + "client", + "clojure", + "clone", + "closure", + "cloud", + "club", + "cluster", + "cms-", + "cms_", + "coco", + "code", + "coding", + "coffee", + "color", + "combination", + "combo", + "command", + "commander", + "comment", + "commit", + "common", + "community", + "compas", + "compiler", + "complete", + "component", + "composer", + "computer", + "computing", + "con-", + "con.", + "con_", + "concept", + "conf", + "config", + "config", + "connect", + "connector", + "console", + "contact", + "container", + "contao", + "content", + "contest", + "context", + "control", + "convert", + "converter", + "conway'", + "cookbook", + "cookie", + "cool", + "copy", + "cordova", + "core", + "couchbase", + "couchdb", + "countdown", + "counter", + "course", + "craft", + "crawler", + "create", + "creating", + "creator", + "credential", + "crm-", + "crm.", + "crm_", + "cros", + "crud", + "csv-", + "csv.", + "csv_", + "cube", + "cucumber", + "cuda", + "current", + "currently", + "custom", + "daemon", + "dark", + "dart", + "dash", + "dashboard", + "data", + "database", + "date", + "day-", + "day.", + "day_", + "dead", + "debian", + "debug", + "debug", + "debugger", + "deck", + "define", + "del-", + "del.", + "del_", + "delete", + "demo", + "deploy", + "design", + "designer", + "desktop", + "detection", + "detector", + "dev-", + "dev.", + "dev_", + "develop", + "developer", + "device", + "devise", + "diff", + "digital", + "directive", + "directory", + "discovery", + "display", + "django", + "dns-", + "dns_", + "doc-", + "doc-", + "doc.", + "doc.", + "doc_", + "doc_", + "docker", + "docpad", + "doctrine", + "document", + "doe-", + "doe.", + "doe_", + "dojo", + "dom-", + "dom.", + "dom_", + "domain", + "done", + "don't", + "dot-", + "dot.", + "dot_", + "dotfile", + "download", + "draft", + "drag", + "drill", + "drive", + "driven", + "driver", + "drop", + "dropbox", + "drupal", + "dsl-", + "dsl.", + "dsl_", + "dynamic", + "easy", + "_ec2_", + "ecdsa", + "eclipse", + "edit", + "editing", + "edition", + "editor", + "element", + "emac", + "email", + "embed", + "embedded", + "ember", + "emitter", + "emulator", + "encoding", + "endpoint", + "engine", + "english", + "enhanced", + "entity", + "entry", + "env_", + "episode", + "erlang", + "error", + "espresso", + "event", + "evented", + "example", + "example", + "exchange", + "exercise", + "experiment", + "expire", + "exploit", + "explorer", + "export", + "exporter", + "expres", + "ext-", + "ext.", + "ext_", + "extended", + "extension", + "external", + "extra", + "extractor", + "fabric", + "facebook", + "factory", + "fake", + "fast", + "feature", + "feed", + "fewfwef", + "ffmpeg", + "field", + "file", + "filter", + "find", + "finder", + "firefox", + "firmware", + "first", + "fish", + "fix-", + "fix_", + "flash", + "flask", + "flat", + "flex", + "flexible", + "flickr", + "flow", + "fluent", + "fluentd", + "fluid", + "folder", + "font", + "force", + "foreman", + "fork", + "form", + "format", + "formatter", + "forum", + "foundry", + "framework", + "free", + "friend", + "friendly", + "front-end", + "frontend", + "ftp-", + "ftp.", + "ftp_", + "fuel", + "full", + "fun-", + "fun.", + "fun_", + "func", + "future", + "gaia", + "gallery", + "game", + "gateway", + "gem-", + "gem.", + "gem_", + "gen-", + "gen.", + "gen_", + "general", + "generator", + "generic", + "genetic", + "get-", + "get.", + "get_", + "getenv", + "getting", + "ghost", + "gist", + "git-", + "git.", + "git_", + "github", + "gitignore", + "gitlab", + "glas", + "gmail", + "gnome", + "gnu-", + "gnu.", + "gnu_", + "goal", + "golang", + "gollum", + "good", + "google", + "gpu-", + "gpu.", + "gpu_", + "gradle", + "grail", + "graph", + "graphic", + "great", + "grid", + "groovy", + "group", + "grunt", + "guard", + "gui-", + "gui.", + "gui_", + "guide", + "guideline", + "gulp", + "gwt-", + "gwt.", + "gwt_", + "hack", + "hackathon", + "hacker", + "hacking", + "hadoop", + "haml", + "handler", + "hardware", + "has-", + "has_", + "hash", + "haskell", + "have", + "haxe", + "hello", + "help", + "helper", + "here", + "hero", + "heroku", + "high", + "hipchat", + "history", + "home", + "homebrew", + "homepage", + "hook", + "host", + "hosting", + "hot-", + "hot.", + "hot_", + "house", + "how-", + "how.", + "how_", + "html", + "http", + "hub-", + "hub.", + "hub_", + "hubot", + "human", + "icon", + "ide-", + "ide.", + "ide_", + "idea", + "identity", + "idiomatic", + "image", + "impact", + "import", + "important", + "importer", + "impres", + "index", + "infinite", + "info", + "injection", + "inline", + "input", + "inside", + "inspector", + "instagram", + "install", + "installer", + "instant", + "intellij", + "interface", + "internet", + "interview", + "into", + "intro", + "ionic", + "iphone", + "ipython", + "irc-", + "irc_", + "iso-", + "iso.", + "iso_", + "issue", + "jade", + "jasmine", + "java", + "jbos", + "jekyll", + "jenkin", + "job-", + "job.", + "job_", + "joomla", + "jpa-", + "jpa.", + "jpa_", + "jquery", + "json", + "just", + "kafka", + "karma", + "kata", + "kernel", + "keyboard", + "kindle", + "kit-", + "kit.", + "kit_", + "kitchen", + "knife", + "koan", + "kohana", + "lab-", + "lab-", + "lab.", + "lab.", + "lab_", + "lab_", + "lambda", + "lamp", + "language", + "laravel", + "last", + "latest", + "latex", + "launcher", + "layer", + "layout", + "lazy", + "ldap", + "leaflet", + "league", + "learn", + "learning", + "led-", + "led.", + "led_", + "leetcode", + "les-", + "les.", + "les_", + "level", + "leveldb", + "lib-", + "lib.", + "lib_", + "librarie", + "library", + "license", + "life", + "liferay", + "light", + "lightbox", + "like", + "line", + "link", + "linked", + "linkedin", + "linux", + "lisp", + "list", + "lite", + "little", + "load", + "loader", + "local", + "location", + "lock", + "log-", + "log.", + "log_", + "logger", + "logging", + "logic", + "login", + "logstash", + "longer", + "look", + "love", + "lua-", + "lua.", + "lua_", + "mac-", + "mac.", + "mac_", + "machine", + "made", + "magento", + "magic", + "mail", + "make", + "maker", + "making", + "man-", + "man.", + "man_", + "manage", + "manager", + "manifest", + "manual", + "map-", + "map-", + "map.", + "map.", + "map_", + "map_", + "mapper", + "mapping", + "markdown", + "markup", + "master", + "math", + "matrix", + "maven", + "md5", + "mean", + "media", + "mediawiki", + "meetup", + "memcached", + "memory", + "menu", + "merchant", + "message", + "messaging", + "meta", + "metadata", + "meteor", + "method", + "metric", + "micro", + "middleman", + "migration", + "minecraft", + "miner", + "mini", + "minimal", + "mirror", + "mit-", + "mit.", + "mit_", + "mobile", + "mocha", + "mock", + "mod-", + "mod.", + "mod_", + "mode", + "model", + "modern", + "modular", + "module", + "modx", + "money", + "mongo", + "mongodb", + "mongoid", + "mongoose", + "monitor", + "monkey", + "more", + "motion", + "moved", + "movie", + "mozilla", + "mqtt", + "mule", + "multi", + "multiple", + "music", + "mustache", + "mvc-", + "mvc.", + "mvc_", + "mysql", + "nagio", + "name", + "native", + "need", + "neo-", + "neo.", + "neo_", + "nest", + "nested", + "net-", + "net.", + "net_", + "nette", + "network", + "new-", + "new-", + "new.", + "new.", + "new_", + "new_", + "next", + "nginx", + "ninja", + "nlp-", + "nlp.", + "nlp_", + "node", + "nodej", + "nosql", + "not-", + "not.", + "not_", + "note", + "notebook", + "notepad", + "notice", + "notifier", + "now-", + "now.", + "now_", + "number", + "oauth", + "object", + "objective", + "obsolete", + "ocaml", + "octopres", + "official", + "old-", + "old.", + "old_", + "onboard", + "online", + "only", + "open", + "opencv", + "opengl", + "openshift", + "openwrt", + "option", + "oracle", + "org-", + "org.", + "org_", + "origin", + "original", + "orm-", + "orm.", + "orm_", + "osx-", + "osx_", + "our-", + "our.", + "our_", + "out-", + "out.", + "out_", + "output", + "over", + "overview", + "own-", + "own.", + "own_", + "pack", + "package", + "packet", + "page", + "page", + "panel", + "paper", + "paperclip", + "para", + "parallax", + "parallel", + "parse", + "parser", + "parsing", + "particle", + "party", + "password", + "patch", + "path", + "pattern", + "payment", + "paypal", + "pdf-", + "pdf.", + "pdf_", + "pebble", + "people", + "perl", + "personal", + "phalcon", + "phoenix", + "phone", + "phonegap", + "photo", + "php-", + "php.", + "php_", + "physic", + "picker", + "pipeline", + "platform", + "play", + "player", + "please", + "plu-", + "plu.", + "plu_", + "plug-in", + "plugin", + "plupload", + "png-", + "png.", + "png_", + "poker", + "polyfill", + "polymer", + "pool", + "pop-", + "pop.", + "pop_", + "popcorn", + "popup", + "port", + "portable", + "portal", + "portfolio", + "post", + "power", + "powered", + "powerful", + "prelude", + "pretty", + "preview", + "principle", + "print", + "pro-", + "pro.", + "pro_", + "problem", + "proc", + "product", + "profile", + "profiler", + "program", + "progres", + "project", + "protocol", + "prototype", + "provider", + "proxy", + "public", + "pull", + "puppet", + "pure", + "purpose", + "push", + "pusher", + "pyramid", + "python", + "quality", + "query", + "queue", + "quick", + "rabbitmq", + "rack", + "radio", + "rail", + "railscast", + "random", + "range", + "raspberry", + "rdf-", + "rdf.", + "rdf_", + "react", + "reactive", + "read", + "reader", + "readme", + "ready", + "real", + "reality", + "real-time", + "realtime", + "recipe", + "recorder", + "red-", + "red.", + "red_", + "reddit", + "redi", + "redmine", + "reference", + "refinery", + "refresh", + "registry", + "related", + "release", + "remote", + "rendering", + "repo", + "report", + "request", + "require", + "required", + "requirej", + "research", + "resource", + "response", + "resque", + "rest", + "restful", + "resume", + "reveal", + "reverse", + "review", + "riak", + "rich", + "right", + "ring", + "robot", + "role", + "room", + "router", + "routing", + "rpc-", + "rpc.", + "rpc_", + "rpg-", + "rpg.", + "rpg_", + "rspec", + "ruby-", + "ruby.", + "ruby_", + "rule", + "run-", + "run.", + "run_", + "runner", + "running", + "runtime", + "rust", + "rvm-", + "rvm.", + "rvm_", + "salt", + "sample", + "sample", + "sandbox", + "sas-", + "sas.", + "sas_", + "sbt-", + "sbt.", + "sbt_", + "scala", + "scalable", + "scanner", + "schema", + "scheme", + "school", + "science", + "scraper", + "scratch", + "screen", + "script", + "scroll", + "scs-", + "scs.", + "scs_", + "sdk-", + "sdk.", + "sdk_", + "sdl-", + "sdl.", + "sdl_", + "search", + "secure", + "security", + "see-", + "see.", + "see_", + "seed", + "select", + "selector", + "selenium", + "semantic", + "sencha", + "send", + "sentiment", + "serie", + "server", + "service", + "session", + "set-", + "set.", + "set_", + "setting", + "setting", + "setup", + "sha1", + "sha2", + "sha256", + "share", + "shared", + "sharing", + "sheet", + "shell", + "shield", + "shipping", + "shop", + "shopify", + "shortener", + "should", + "show", + "showcase", + "side", + "silex", + "simple", + "simulator", + "single", + "site", + "skeleton", + "sketch", + "skin", + "slack", + "slide", + "slider", + "slim", + "small", + "smart", + "smtp", + "snake", + "snippet", + "soap", + "social", + "socket", + "software", + "solarized", + "solr", + "solution", + "solver", + "some", + "soon", + "source", + "space", + "spark", + "spatial", + "spec", + "sphinx", + "spine", + "spotify", + "spree", + "spring", + "sprite", + "sql-", + "sql.", + "sql_", + "sqlite", + "ssh-", + "ssh.", + "ssh_", + "stack", + "staging", + "standard", + "stanford", + "start", + "started", + "starter", + "startup", + "stat", + "statamic", + "state", + "static", + "statistic", + "statsd", + "statu", + "steam", + "step", + "still", + "stm-", + "stm.", + "stm_", + "storage", + "store", + "storm", + "story", + "strategy", + "stream", + "streaming", + "string", + "stripe", + "structure", + "studio", + "study", + "stuff", + "style", + "sublime", + "sugar", + "suite", + "summary", + "super", + "support", + "supported", + "svg-", + "svg.", + "svg_", + "svn-", + "svn.", + "svn_", + "swagger", + "swift", + "switch", + "switcher", + "symfony", + "symphony", + "sync", + "synopsi", + "syntax", + "system", + "system", + "tab-", + "tab-", + "tab.", + "tab.", + "tab_", + "tab_", + "table", + "tag-", + "tag-", + "tag.", + "tag.", + "tag_", + "tag_", + "talk", + "target", + "task", + "tcp-", + "tcp.", + "tcp_", + "tdd-", + "tdd.", + "tdd_", + "team", + "tech", + "template", + "term", + "terminal", + "testing", + "tetri", + "text", + "textmate", + "theme", + "theory", + "three", + "thrift", + "time", + "timeline", + "timer", + "tiny", + "tinymce", + "tip-", + "tip.", + "tip_", + "title", + "todo", + "todomvc", + "token", + "tool", + "toolbox", + "toolkit", + "top-", + "top.", + "top_", + "tornado", + "touch", + "tower", + "tracker", + "tracking", + "traffic", + "training", + "transfer", + "translate", + "transport", + "tree", + "trello", + "try-", + "try.", + "try_", + "tumblr", + "tut-", + "tut.", + "tut_", + "tutorial", + "tweet", + "twig", + "twitter", + "type", + "typo", + "ubuntu", + "uiview", + "ultimate", + "under", + "unit", + "unity", + "universal", + "unix", + "update", + "updated", + "upgrade", + "upload", + "uploader", + "uri-", + "uri.", + "uri_", + "url-", + "url.", + "url_", + "usage", + "usb-", + "usb.", + "usb_", + "use-", + "use.", + "use_", + "used", + "useful", + "user", + "using", + "util", + "utilitie", + "utility", + "vagrant", + "validator", + "value", + "variou", + "varnish", + "version", + "via-", + "via.", + "via_", + "video", + "view", + "viewer", + "vim-", + "vim.", + "vim_", + "vimrc", + "virtual", + "vision", + "visual", + "vpn", + "want", + "warning", + "watch", + "watcher", + "wave", + "way-", + "way.", + "way_", + "weather", + "web-", + "web_", + "webapp", + "webgl", + "webhook", + "webkit", + "webrtc", + "website", + "websocket", + "welcome", + "welcome", + "what", + "what'", + "when", + "where", + "which", + "why-", + "why.", + "why_", + "widget", + "wifi", + "wiki", + "win-", + "win.", + "win_", + "window", + "wip-", + "wip.", + "wip_", + "within", + "without", + "wizard", + "word", + "wordpres", + "work", + "worker", + "workflow", + "working", + "workshop", + "world", + "wrapper", + "write", + "writer", + "writing", + "written", + "www-", + "www.", + "www_", + "xamarin", + "xcode", + "xml-", + "xml.", + "xml_", + "xmpp", + "xxxxxx", + "yahoo", + "yaml", + "yandex", + "yeoman", + "yet-", + "yet.", + "yet_", + "yii-", + "yii.", + "yii_", + "youtube", + "yui-", + "yui.", + "yui_", + "zend", + "zero", + "zip-", + "zip.", + "zip_", + "zsh-", + "zsh.", + "zsh_", +] + +[[rules]] +id = "github-app-token" +description = "Identified a GitHub App Token, which may compromise GitHub application integrations and source code security." +regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' +keywords = [ + "ghu_","ghs_", +] + +[[rules]] +id = "github-fine-grained-pat" +description = "Found a GitHub Fine-Grained Personal Access Token, risking unauthorized repository access and code manipulation." +regex = '''github_pat_[0-9a-zA-Z_]{82}''' +keywords = [ + "github_pat_", +] + +[[rules]] +id = "github-oauth" +description = "Discovered a GitHub OAuth Access Token, posing a risk of compromised GitHub account integrations and data leaks." +regex = '''gho_[0-9a-zA-Z]{36}''' +keywords = [ + "gho_", +] + +[[rules]] +id = "github-pat" +description = "Uncovered a GitHub Personal Access Token, potentially leading to unauthorized repository access and sensitive content exposure." +regex = '''ghp_[0-9a-zA-Z]{36}''' +keywords = [ + "ghp_", +] + +[[rules]] +id = "github-refresh-token" +description = "Detected a GitHub Refresh Token, which could allow prolonged unauthorized access to GitHub services." +regex = '''ghr_[0-9a-zA-Z]{36}''' +keywords = [ + "ghr_", +] + +[[rules]] +id = "gitlab-pat" +description = "Identified a GitLab Personal Access Token, risking unauthorized access to GitLab repositories and codebase exposure." +regex = '''glpat-[0-9a-zA-Z\-\_]{20}''' +keywords = [ + "glpat-", +] + +[[rules]] +id = "gitlab-ptt" +description = "Found a GitLab Pipeline Trigger Token, potentially compromising continuous integration workflows and project security." +regex = '''glptt-[0-9a-f]{40}''' +keywords = [ + "glptt-", +] + +[[rules]] +id = "gitlab-rrt" +description = "Discovered a GitLab Runner Registration Token, posing a risk to CI/CD pipeline integrity and unauthorized access." +regex = '''GR1348941[0-9a-zA-Z\-\_]{20}''' +keywords = [ + "gr1348941", +] + +[[rules]] +id = "gitter-access-token" +description = "Uncovered a Gitter Access Token, which may lead to unauthorized access to chat and communication services." +regex = '''(?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "gitter", +] + +[[rules]] +id = "gocardless-api-token" +description = "Detected a GoCardless API token, potentially risking unauthorized direct debit payment operations and financial data exposure." +regex = '''(?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "live_","gocardless", +] + +[[rules]] +id = "grafana-api-key" +description = "Identified a Grafana API key, which could compromise monitoring dashboards and sensitive data analytics." +regex = '''(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "eyjrijoi", +] + +[[rules]] +id = "grafana-cloud-api-token" +description = "Found a Grafana cloud API token, risking unauthorized access to cloud-based monitoring services and data exposure." +regex = '''(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "glc_", +] + +[[rules]] +id = "grafana-service-account-token" +description = "Discovered a Grafana service account token, posing a risk of compromised monitoring services and data integrity." +regex = '''(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "glsa_", +] + +[[rules]] +id = "hashicorp-tf-api-token" +description = "Uncovered a HashiCorp Terraform user/org API token, which may lead to unauthorized infrastructure management and security breaches." +regex = '''(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}''' +keywords = [ + "atlasv1", +] + +[[rules]] +id = "hashicorp-tf-password" +description = "Identified a HashiCorp Terraform password field, risking unauthorized infrastructure configuration and security breaches." +regex = '''(?i)(?:administrator_login_password|password)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}("[a-z0-9=_\-]{8,20}")(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "administrator_login_password","password", +] + +[[rules]] +id = "heroku-api-key" +description = "Detected a Heroku API Key, potentially compromising cloud application deployments and operational security." +regex = '''(?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "heroku", +] + +[[rules]] +id = "hubspot-api-key" +description = "Found a HubSpot API Token, posing a risk to CRM data integrity and unauthorized marketing operations." +regex = '''(?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hubspot", +] + +[[rules]] +id = "huggingface-access-token" +description = "Discovered a Hugging Face Access token, which could lead to unauthorized access to AI models and sensitive data." +regex = '''(?:^|[\\'"` >=:])(hf_[a-zA-Z]{34})(?:$|[\\'"` <])''' +entropy = 1 +keywords = [ + "hf_", +] + +[[rules]] +id = "huggingface-organization-api-token" +description = "Uncovered a Hugging Face Organization API token, potentially compromising AI organization accounts and associated data." +regex = '''(?:^|[\\'"` >=:\(,)])(api_org_[a-zA-Z]{34})(?:$|[\\'"` <\),])''' +entropy = 2 +keywords = [ + "api_org_", +] + +[[rules]] +id = "infracost-api-token" +description = "Detected an Infracost API Token, risking unauthorized access to cloud cost estimation tools and financial data." +regex = '''(?i)\b(ico-[a-zA-Z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ico-", +] + +[[rules]] +id = "intercom-api-key" +description = "Identified an Intercom API Token, which could compromise customer communication channels and data privacy." +regex = '''(?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "intercom", +] + +[[rules]] +id = "jfrog-api-key" +description = "Found a JFrog API Key, posing a risk of unauthorized access to software artifact repositories and build pipelines." +regex = '''(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{73})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "jfrog","artifactory","bintray","xray", +] + +[[rules]] +id = "jfrog-identity-token" +description = "Discovered a JFrog Identity Token, potentially compromising access to JFrog services and sensitive software artifacts." +regex = '''(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "jfrog","artifactory","bintray","xray", +] + +[[rules]] +id = "jwt" +description = "Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data." +regex = '''\b(ey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/\\_-]{17,}\.(?:[a-zA-Z0-9\/\\_-]{10,}={0,2})?)(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "ey", +] + +[[rules]] +id = "jwt-base64" +description = "Detected a Base64-encoded JSON Web Token, posing a risk of exposing encoded authentication and data exchange information." +regex = '''\bZXlK(?:(?PaGJHY2lPaU)|(?PaGNIVWlPaU)|(?PaGNIWWlPaU)|(?PaGRXUWlPaU)|(?PaU5qUWlP)|(?PamNtbDBJanBi)|(?PamRIa2lPaU)|(?PbGNHc2lPbn)|(?PbGJtTWlPaU)|(?PcWEzVWlPaU)|(?PcWQyc2lPb)|(?PcGMzTWlPaU)|(?PcGRpSTZJ)|(?PcmFXUWlP)|(?PclpYbGZiM0J6SWpwY)|(?PcmRIa2lPaUp)|(?PdWIyNWpaU0k2)|(?Pd01tTWlP)|(?Pd01uTWlPaU)|(?Pd2NIUWlPaU)|(?PemRXSWlPaU)|(?PemRuUWlP)|(?PMFlXY2lPaU)|(?PMGVYQWlPaUp)|(?PMWNtd2l)|(?PMWMyVWlPaUp)|(?PMlpYSWlPaU)|(?PMlpYSnphVzl1SWpv)|(?PNElqb2)|(?PNE5XTWlP)|(?PNE5YUWlPaU)|(?PNE5YUWpVekkxTmlJNkl)|(?PNE5YVWlPaU)|(?PNmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2}''' +keywords = [ + "zxlk", +] + +[[rules]] +id = "kraken-access-token" +description = "Identified a Kraken Access Token, potentially compromising cryptocurrency trading accounts and financial security." +regex = '''(?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "kraken", +] + +[[rules]] +id = "kucoin-access-token" +description = "Found a Kucoin Access Token, risking unauthorized access to cryptocurrency exchange services and transactions." +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "kucoin", +] + +[[rules]] +id = "kucoin-secret-key" +description = "Discovered a Kucoin Secret Key, which could lead to compromised cryptocurrency operations and financial data breaches." +regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "kucoin", +] + +[[rules]] +id = "launchdarkly-access-token" +description = "Uncovered a Launchdarkly Access Token, potentially compromising feature flag management and application functionality." +regex = '''(?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "launchdarkly", +] + +[[rules]] +id = "linear-api-key" +description = "Detected a Linear API Token, posing a risk to project management tools and sensitive task data." +regex = '''lin_api_(?i)[a-z0-9]{40}''' +keywords = [ + "lin_api_", +] + +[[rules]] +id = "linear-client-secret" +description = "Identified a Linear Client Secret, which may compromise secure integrations and sensitive project management data." +regex = '''(?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "linear", +] + +[[rules]] +id = "linkedin-client-id" +description = "Found a LinkedIn Client ID, risking unauthorized access to LinkedIn integrations and professional data exposure." +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +id = "linkedin-client-secret" +description = "Discovered a LinkedIn Client secret, potentially compromising LinkedIn application integrations and user data." +regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "linkedin","linked-in", +] + +[[rules]] +id = "lob-api-key" +description = "Uncovered a Lob API Key, which could lead to unauthorized access to mailing and address verification services." +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "test_","live_", +] + +[[rules]] +id = "lob-pub-api-key" +description = "Detected a Lob Publishable API Key, posing a risk of exposing mail and print service integrations." +regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "test_pub","live_pub","_pub", +] + +[[rules]] +id = "mailchimp-api-key" +description = "Identified a Mailchimp API key, potentially compromising email marketing campaigns and subscriber data." +regex = '''(?i)(?:mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us20)(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mailchimp", +] + +[[rules]] +id = "mailgun-private-api-token" +description = "Found a Mailgun private API token, risking unauthorized email service operations and data breaches." +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mailgun", +] + +[[rules]] +id = "mailgun-pub-key" +description = "Discovered a Mailgun public validation key, which could expose email verification processes and associated data." +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mailgun", +] + +[[rules]] +id = "mailgun-signing-key" +description = "Uncovered a Mailgun webhook signing key, potentially compromising email automation and data integrity." +regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mailgun", +] + +[[rules]] +id = "mapbox-api-token" +description = "Detected a MapBox API token, posing a risk to geospatial services and sensitive location data exposure." +regex = '''(?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mapbox", +] + +[[rules]] +id = "mattermost-access-token" +description = "Identified a Mattermost Access Token, which may compromise team communication channels and data privacy." +regex = '''(?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "mattermost", +] + +[[rules]] +id = "messagebird-api-token" +description = "Found a MessageBird API token, risking unauthorized access to communication platforms and message data." +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +id = "messagebird-client-id" +description = "Discovered a MessageBird client ID, potentially compromising API integrations and sensitive communication data." +regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "messagebird","message-bird","message_bird", +] + +[[rules]] +id = "microsoft-teams-webhook" +description = "Uncovered a Microsoft Teams Webhook, which could lead to unauthorized access to team collaboration tools and data leaks." +regex = '''https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}''' +keywords = [ + "webhook.office.com","webhookb2","incomingwebhook", +] + +[[rules]] +id = "netlify-access-token" +description = "Detected a Netlify Access Token, potentially compromising web hosting services and site management." +regex = '''(?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "netlify", +] + +[[rules]] +id = "new-relic-browser-api-token" +description = "Identified a New Relic ingest browser API token, risking unauthorized access to application performance data and analytics." +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "nrjs-", +] + +[[rules]] +id = "new-relic-user-api-id" +description = "Found a New Relic user API ID, posing a risk to application monitoring services and data integrity." +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "new-relic","newrelic","new_relic", +] + +[[rules]] +id = "new-relic-user-api-key" +description = "Discovered a New Relic user API Key, which could lead to compromised application insights and performance monitoring." +regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "nrak", +] + +[[rules]] +id = "npm-access-token" +description = "Uncovered an npm access token, potentially compromising package management and code repository access." +regex = '''(?i)\b(npm_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "npm_", +] + +[[rules]] +id = "nytimes-access-token" +description = "Detected a Nytimes Access Token, risking unauthorized access to New York Times APIs and content services." +regex = '''(?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "nytimes","new-york-times","newyorktimes", +] + +[[rules]] +id = "okta-access-token" +description = "Identified an Okta Access Token, which may compromise identity management services and user authentication data." +regex = '''(?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "okta", +] + +[[rules]] +id = "openai-api-key" +description = "Found an OpenAI API Key, posing a risk of unauthorized access to AI services and data manipulation." +regex = '''(?i)\b(sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "t3blbkfj", +] + +[[rules]] +id = "plaid-api-token" +description = "Discovered a Plaid API Token, potentially compromising financial data aggregation and banking services." +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "plaid", +] + +[[rules]] +id = "plaid-client-id" +description = "Uncovered a Plaid Client ID, which could lead to unauthorized financial service integrations and data breaches." +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +entropy = 3.5 +keywords = [ + "plaid", +] + +[[rules]] +id = "plaid-secret-key" +description = "Detected a Plaid Secret key, risking unauthorized access to financial accounts and sensitive transaction data." +regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +entropy = 3.5 +keywords = [ + "plaid", +] + +[[rules]] +id = "planetscale-api-token" +description = "Identified a PlanetScale API token, potentially compromising database management and operations." +regex = '''(?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pscale_tkn_", +] + +[[rules]] +id = "planetscale-oauth-token" +description = "Found a PlanetScale OAuth token, posing a risk to database access control and sensitive data integrity." +regex = '''(?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pscale_oauth_", +] + +[[rules]] +id = "planetscale-password" +description = "Discovered a PlanetScale password, which could lead to unauthorized database operations and data breaches." +regex = '''(?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pscale_pw_", +] + +[[rules]] +id = "postman-api-token" +description = "Uncovered a Postman API token, potentially compromising API testing and development workflows." +regex = '''(?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pmak-", +] + +[[rules]] +id = "prefect-api-token" +description = "Detected a Prefect API token, risking unauthorized access to workflow management and automation services." +regex = '''(?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pnu_", +] + +[[rules]] +id = "private-key" +description = "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption." +regex = '''(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY( BLOCK)?----''' +keywords = [ + "-----begin", +] + +[[rules]] +id = "pulumi-api-token" +description = "Found a Pulumi API token, posing a risk to infrastructure as code services and cloud resource management." +regex = '''(?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "pul-", +] + +[[rules]] +id = "pypi-upload-token" +description = "Discovered a PyPI upload token, potentially compromising Python package distribution and repository integrity." +regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' +keywords = [ + "pypi-ageichlwas5vcmc", +] + +[[rules]] +id = "rapidapi-access-token" +description = "Uncovered a RapidAPI Access Token, which could lead to unauthorized access to various APIs and data services." +regex = '''(?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "rapidapi", +] + +[[rules]] +id = "readme-api-token" +description = "Detected a Readme API token, risking unauthorized documentation management and content exposure." +regex = '''(?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "rdme_", +] + +[[rules]] +id = "rubygems-api-token" +description = "Identified a Rubygem API token, potentially compromising Ruby library distribution and package management." +regex = '''(?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "rubygems_", +] + +[[rules]] +id = "scalingo-api-token" +description = "Found a Scalingo API token, posing a risk to cloud platform services and application deployment security." +regex = '''\btk-us-[a-zA-Z0-9-_]{48}\b''' +keywords = [ + "tk-us-", +] + +[[rules]] +id = "sendbird-access-id" +description = "Discovered a Sendbird Access ID, which could compromise chat and messaging platform integrations." +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sendbird", +] + +[[rules]] +id = "sendbird-access-token" +description = "Uncovered a Sendbird Access Token, potentially risking unauthorized access to communication services and user data." +regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sendbird", +] + +[[rules]] +id = "sendgrid-api-token" +description = "Detected a SendGrid API token, posing a risk of unauthorized email service operations and data exposure." +regex = '''(?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sg.", +] + +[[rules]] +id = "sendinblue-api-token" +description = "Identified a Sendinblue API token, which may compromise email marketing services and subscriber data privacy." +regex = '''(?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "xkeysib-", +] + +[[rules]] +id = "sentry-access-token" +description = "Found a Sentry Access Token, risking unauthorized access to error tracking services and sensitive application data." +regex = '''(?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sentry", +] + +[[rules]] +id = "shippo-api-token" +description = "Discovered a Shippo API token, potentially compromising shipping services and customer order data." +regex = '''(?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "shippo_", +] + +[[rules]] +id = "shopify-access-token" +description = "Uncovered a Shopify access token, which could lead to unauthorized e-commerce platform access and data breaches." +regex = '''shpat_[a-fA-F0-9]{32}''' +keywords = [ + "shpat_", +] + +[[rules]] +id = "shopify-custom-access-token" +description = "Detected a Shopify custom access token, potentially compromising custom app integrations and e-commerce data security." +regex = '''shpca_[a-fA-F0-9]{32}''' +keywords = [ + "shpca_", +] + +[[rules]] +id = "shopify-private-app-access-token" +description = "Identified a Shopify private app access token, risking unauthorized access to private app data and store operations." +regex = '''shppa_[a-fA-F0-9]{32}''' +keywords = [ + "shppa_", +] + +[[rules]] +id = "shopify-shared-secret" +description = "Found a Shopify shared secret, posing a risk to application authentication and e-commerce platform security." +regex = '''shpss_[a-fA-F0-9]{32}''' +keywords = [ + "shpss_", +] + +[[rules]] +id = "sidekiq-secret" +description = "Discovered a Sidekiq Secret, which could lead to compromised background job processing and application data breaches." +regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", +] + +[[rules]] +id = "sidekiq-sensitive-url" +description = "Uncovered a Sidekiq Sensitive URL, potentially exposing internal job queues and sensitive operation details." +regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' +secretGroup = 2 +keywords = [ + "gems.contribsys.com","enterprise.contribsys.com", +] + +[[rules]] +id = "slack-app-token" +description = "Detected a Slack App-level token, risking unauthorized access to Slack applications and workspace data." +regex = '''(?i)(xapp-\d-[A-Z0-9]+-\d+-[a-z0-9]+)''' +keywords = [ + "xapp", +] + +[[rules]] +id = "slack-bot-token" +description = "Identified a Slack Bot token, which may compromise bot integrations and communication channel security." +regex = '''(xoxb-[0-9]{10,13}\-[0-9]{10,13}[a-zA-Z0-9-]*)''' +keywords = [ + "xoxb", +] + +[[rules]] +id = "slack-config-access-token" +description = "Found a Slack Configuration access token, posing a risk to workspace configuration and sensitive data access." +regex = '''(?i)(xoxe.xox[bp]-\d-[A-Z0-9]{163,166})''' +keywords = [ + "xoxe.xoxb-","xoxe.xoxp-", +] + +[[rules]] +id = "slack-config-refresh-token" +description = "Discovered a Slack Configuration refresh token, potentially allowing prolonged unauthorized access to configuration settings." +regex = '''(?i)(xoxe-\d-[A-Z0-9]{146})''' +keywords = [ + "xoxe-", +] + +[[rules]] +id = "slack-legacy-bot-token" +description = "Uncovered a Slack Legacy bot token, which could lead to compromised legacy bot operations and data exposure." +regex = '''(xoxb-[0-9]{8,14}\-[a-zA-Z0-9]{18,26})''' +keywords = [ + "xoxb", +] + +[[rules]] +id = "slack-legacy-token" +description = "Detected a Slack Legacy token, risking unauthorized access to older Slack integrations and user data." +regex = '''(xox[os]-\d+-\d+-\d+-[a-fA-F\d]+)''' +keywords = [ + "xoxo","xoxs", +] + +[[rules]] +id = "slack-legacy-workspace-token" +description = "Identified a Slack Legacy Workspace token, potentially compromising access to workspace data and legacy features." +regex = '''(xox[ar]-(?:\d-)?[0-9a-zA-Z]{8,48})''' +keywords = [ + "xoxa","xoxr", +] + +[[rules]] +id = "slack-user-token" +description = "Found a Slack User token, posing a risk of unauthorized user impersonation and data access within Slack workspaces." +regex = '''(xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34})''' +keywords = [ + "xoxp-","xoxe-", +] + +[[rules]] +id = "slack-webhook-url" +description = "Discovered a Slack Webhook, which could lead to unauthorized message posting and data leakage in Slack channels." +regex = '''(https?:\/\/)?hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{43,46}''' +keywords = [ + "hooks.slack.com", +] + +[[rules]] +id = "snyk-api-token" +description = "Uncovered a Snyk API token, potentially compromising software vulnerability scanning and code security." +regex = '''(?i)(?:snyk_token|snyk_key|snyk_api_token|snyk_api_key|snyk_oauth_token)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "snyk_token","snyk_key","snyk_api_token","snyk_api_key","snyk_oauth_token", +] + +[[rules]] +id = "square-access-token" +description = "Detected a Square Access Token, risking unauthorized payment processing and financial transaction exposure." +regex = '''(?i)\b(sq0atp-[0-9A-Za-z\-_]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sq0atp-", +] + +[[rules]] +id = "squarespace-access-token" +description = "Identified a Squarespace Access Token, which may compromise website management and content control on Squarespace." +regex = '''(?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "squarespace", +] + +[[rules]] +id = "stripe-access-token" +description = "Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data." +regex = '''(?i)\b((sk)_(test|live)_[0-9a-z]{10,32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "sk_test","sk_live", +] + +[[rules]] +id = "sumologic-access-id" +description = "Discovered a SumoLogic Access ID, potentially compromising log management services and data analytics integrity." +regex = '''(?i:(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3})(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(su[a-zA-Z0-9]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +entropy = 3 +keywords = [ + "sumo", +] + +[rules.allowlist] + +regexTarget = "line" +regexes = [ + "sumOf", +] + +[[rules]] +id = "sumologic-access-token" +description = "Uncovered a SumoLogic Access Token, which could lead to unauthorized access to log data and analytics insights." +regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +entropy = 3 +keywords = [ + "sumo", +] + +[[rules]] +id = "telegram-bot-api-token" +description = "Detected a Telegram Bot API Token, risking unauthorized bot operations and message interception on Telegram." +regex = '''(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])''' +keywords = [ + "telegram","api","bot","token","url", +] + +[[rules]] +id = "travisci-access-token" +description = "Identified a Travis CI Access Token, potentially compromising continuous integration services and codebase security." +regex = '''(?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "travis", +] + +[[rules]] +id = "twilio-api-key" +description = "Found a Twilio API Key, posing a risk to communication services and sensitive customer interaction data." +regex = '''SK[0-9a-fA-F]{32}''' +keywords = [ + "twilio", +] + +[[rules]] +id = "twitch-api-token" +description = "Discovered a Twitch API token, which could compromise streaming services and account integrations." +regex = '''(?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitch", +] + +[[rules]] +id = "twitter-access-secret" +description = "Uncovered a Twitter Access Secret, potentially risking unauthorized Twitter integrations and data breaches." +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitter", +] + +[[rules]] +id = "twitter-access-token" +description = "Detected a Twitter Access Token, posing a risk of unauthorized account operations and social media data exposure." +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitter", +] + +[[rules]] +id = "twitter-api-key" +description = "Identified a Twitter API Key, which may compromise Twitter application integrations and user data security." +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitter", +] + +[[rules]] +id = "twitter-api-secret" +description = "Found a Twitter API Secret, risking the security of Twitter app integrations and sensitive data access." +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitter", +] + +[[rules]] +id = "twitter-bearer-token" +description = "Discovered a Twitter Bearer Token, potentially compromising API access and data retrieval from Twitter." +regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "twitter", +] + +[[rules]] +id = "typeform-api-token" +description = "Uncovered a Typeform API token, which could lead to unauthorized survey management and data collection." +regex = '''(?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "tfp_", +] + +[[rules]] +id = "vault-batch-token" +description = "Detected a Vault Batch Token, risking unauthorized access to secret management services and sensitive data." +regex = '''(?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvb", +] + +[[rules]] +id = "vault-service-token" +description = "Identified a Vault Service Token, potentially compromising infrastructure security and access to sensitive credentials." +regex = '''(?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "hvs", +] + +[[rules]] +id = "yandex-access-token" +description = "Found a Yandex Access Token, posing a risk to Yandex service integrations and user data privacy." +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "yandex", +] + +[[rules]] +id = "yandex-api-key" +description = "Discovered a Yandex API Key, which could lead to unauthorized access to Yandex services and data manipulation." +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "yandex", +] + +[[rules]] +id = "yandex-aws-access-token" +description = "Uncovered a Yandex AWS Access Token, potentially compromising cloud resource access and data security on Yandex Cloud." +regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "yandex", +] + +[[rules]] +id = "zendesk-secret-key" +description = "Detected a Zendesk Secret Key, risking unauthorized access to customer support services and sensitive ticketing data." +regex = '''(?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' +keywords = [ + "zendesk", +] diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000000..070fb56530 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1,157 @@ +app/src/gms/google-services.json:gcp-api-key:24 +app/src/gms/google-services.json:gcp-api-key:27 +app/src/gms/google-services.json:gcp-api-key:56 +app/src/gms/google-services.json:gcp-api-key:59 +app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:508 +app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 +app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:101 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:106 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:131 +app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 +app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 +app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 +app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 +data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 +data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 +data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:73 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 +app/src/gms/google-services.json:gcp-api-key:24 +app/src/gms/google-services.json:gcp-api-key:27 +app/src/gms/google-services.json:gcp-api-key:56 +app/src/gms/google-services.json:gcp-api-key:59 +app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:508 +app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 +app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:101 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:106 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:131 +app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 +app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 +app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 +app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 +data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 +data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 +data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:73 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 +app/src/gms/google-services.json:gcp-api-key:24 +app/src/gms/google-services.json:gcp-api-key:27 +app/src/gms/google-services.json:gcp-api-key:56 +app/src/gms/google-services.json:gcp-api-key:59 +app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:492 +app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 +app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:118 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:123 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:153 +app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 +app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 +app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 +app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 +data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 +data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 +data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:68 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 +app/src/gms/google-services.json:gcp-api-key:24 +app/src/gms/google-services.json:gcp-api-key:27 +app/src/gms/google-services.json:gcp-api-key:56 +app/src/gms/google-services.json:gcp-api-key:59 +app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:492 +app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 +app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:118 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:123 +app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:153 +app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 +app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 +app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:242 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:273 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:393 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:411 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:429 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:447 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:465 +app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 +app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 +app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 +data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 +data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 +data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 +data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:68 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 +app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:510 +data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1383 +data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1410 +data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1437 +domain/src/test/kotlin/mega/privacy/android/domain/usecase/account/ConfirmCancelAccountUseCaseTest.kt:hashicorp-tf-password:38 \ No newline at end of file From ecdf99c3db141c3c1e50ac3022c017072a5f3a9c Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Wed, 28 Feb 2024 12:46:45 +1300 Subject: [PATCH 032/261] Revert "Feature/gitleaks secret scanning pipeline added" This reverts commit ab988ee16e1c594158ba45094438d34a4b6f7859. --- .gitlab-ci.yml | 13 - .gitleaks/gitleaks.toml | 2847 --------------------------------------- .gitleaksignore | 157 --- 3 files changed, 3017 deletions(-) delete mode 100644 .gitlab-ci.yml delete mode 100644 .gitleaks/gitleaks.toml delete mode 100644 .gitleaksignore diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 1930eb6359..0000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,13 +0,0 @@ -variables: - GIT_STRATEGY: clone - -stages: - - scan - -scan: - stage: scan - image: - name: mega-docker.artifactory.developers.mega.co.nz:8443/gitleaks:v8.18.2-mega-1.0 - entrypoint: [""] - script: - - gitleaks detect -v --redact -c .gitleaks/gitleaks.toml diff --git a/.gitleaks/gitleaks.toml b/.gitleaks/gitleaks.toml deleted file mode 100644 index 9c1d21b425..0000000000 --- a/.gitleaks/gitleaks.toml +++ /dev/null @@ -1,2847 +0,0 @@ -# This file has been auto-generated. Do not edit manually. -# If you would like to contribute new rules, please use -# cmd/generate/config/main.go and follow the contributing guidelines -# at https://github.com/zricethezav/gitleaks/blob/master/CONTRIBUTING.md - -# This is the default gitleaks configuration file. -# Rules and allowlists are defined within this file. -# Rules instruct gitleaks on what should be considered a secret. -# Allowlists instruct gitleaks on what is allowed, i.e. not a secret. - -title = "gitleaks config" - -[allowlist] -description = "global allow lists" -paths = [ - '''gitleaks.toml''', - '''(.*?)(jpg|gif|doc|docx|zip|xls|pdf|bin|svg|socket|vsidx|v2|suo|wsuo|.dll|pdb|exe)$''', - '''(go.mod|go.sum)$''', - '''gradle.lockfile''', - '''node_modules''', - '''package-lock.json''', - '''yarn.lock''', - '''pnpm-lock.yaml''', - '''Database.refactorlog''', - '''vendor''', -] - -[[rules]] -id = "adafruit-api-key" -description = "Identified a potential Adafruit API Key, which could lead to unauthorized access to Adafruit services and sensitive data exposure." -regex = '''(?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "adafruit", -] - -[[rules]] -id = "adobe-client-id" -description = "Detected a pattern that resembles an Adobe OAuth Web Client ID, posing a risk of compromised Adobe integrations and data breaches." -regex = '''(?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "adobe", -] - -[[rules]] -id = "adobe-client-secret" -description = "Discovered a potential Adobe Client Secret, which, if exposed, could allow unauthorized Adobe service access and data manipulation." -regex = '''(?i)\b((p8e-)(?i)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "p8e-", -] - -[[rules]] -id = "age secret key" -description = "Discovered a potential Age encryption tool secret key, risking data decryption and unauthorized access to sensitive information." -regex = '''AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}''' -keywords = [ - "age-secret-key-1", -] - -[[rules]] -id = "airtable-api-key" -description = "Uncovered a possible Airtable API Key, potentially compromising database access and leading to data leakage or alteration." -regex = '''(?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "airtable", -] - -[[rules]] -id = "algolia-api-key" -description = "Identified an Algolia API Key, which could result in unauthorized search operations and data exposure on Algolia-managed platforms." -regex = '''(?i)(?:algolia)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "algolia", -] - -[[rules]] -id = "alibaba-access-key-id" -description = "Detected an Alibaba Cloud AccessKey ID, posing a risk of unauthorized cloud resource access and potential data compromise." -regex = '''(?i)\b((LTAI)(?i)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "ltai", -] - -[[rules]] -id = "alibaba-secret-key" -description = "Discovered a potential Alibaba Cloud Secret Key, potentially allowing unauthorized operations and data access within Alibaba Cloud." -regex = '''(?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "alibaba", -] - -[[rules]] -id = "asana-client-id" -description = "Discovered a potential Asana Client ID, risking unauthorized access to Asana projects and sensitive task information." -regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "asana", -] - -[[rules]] -id = "asana-client-secret" -description = "Identified an Asana Client Secret, which could lead to compromised project management integrity and unauthorized access." -regex = '''(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "asana", -] - -[[rules]] -id = "atlassian-api-token" -description = "Detected an Atlassian API token, posing a threat to project management and collaboration tool security and data confidentiality." -regex = '''(?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "atlassian","confluence","jira", -] - -[[rules]] -id = "authress-service-client-access-key" -description = "Uncovered a possible Authress Service Client Access Key, which may compromise access control services and sensitive data." -regex = '''(?i)\b((?:sc|ext|scauth|authress)_[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.acc[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sc_","ext_","scauth_","authress_", -] - -[[rules]] -id = "aws-access-token" -description = "Identified a pattern that may indicate AWS credentials, risking unauthorized cloud resource access and data breaches on AWS platforms." -regex = '''(?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}''' -keywords = [ - "akia","asia","abia","acca", -] - -[[rules]] -id = "beamer-api-token" -description = "Detected a Beamer API token, potentially compromising content management and exposing sensitive notifications and updates." -regex = '''(?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "beamer", -] - -[[rules]] -id = "bitbucket-client-id" -description = "Discovered a potential Bitbucket Client ID, risking unauthorized repository access and potential codebase exposure." -regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "bitbucket", -] - -[[rules]] -id = "bitbucket-client-secret" -description = "Discovered a potential Bitbucket Client Secret, posing a risk of compromised code repositories and unauthorized access." -regex = '''(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "bitbucket", -] - -[[rules]] -id = "bittrex-access-key" -description = "Identified a Bittrex Access Key, which could lead to unauthorized access to cryptocurrency trading accounts and financial loss." -regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "bittrex", -] - -[[rules]] -id = "bittrex-secret-key" -description = "Detected a Bittrex Secret Key, potentially compromising cryptocurrency transactions and financial security." -regex = '''(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "bittrex", -] - -[[rules]] -id = "clojars-api-token" -description = "Uncovered a possible Clojars API token, risking unauthorized access to Clojure libraries and potential code manipulation." -regex = '''(?i)(CLOJARS_)[a-z0-9]{60}''' -keywords = [ - "clojars", -] - -[[rules]] -id = "codecov-access-token" -description = "Found a pattern resembling a Codecov Access Token, posing a risk of unauthorized access to code coverage reports and sensitive data." -regex = '''(?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "codecov", -] - -[[rules]] -id = "coinbase-access-token" -description = "Detected a Coinbase Access Token, posing a risk of unauthorized access to cryptocurrency accounts and financial transactions." -regex = '''(?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "coinbase", -] - -[[rules]] -id = "confluent-access-token" -description = "Identified a Confluent Access Token, which could compromise access to streaming data platforms and sensitive data flow." -regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "confluent", -] - -[[rules]] -id = "confluent-secret-key" -description = "Found a Confluent Secret Key, potentially risking unauthorized operations and data access within Confluent services." -regex = '''(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "confluent", -] - -[[rules]] -id = "contentful-delivery-api-token" -description = "Discovered a Contentful delivery API token, posing a risk to content management systems and data integrity." -regex = '''(?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "contentful", -] - -[[rules]] -id = "databricks-api-token" -description = "Uncovered a Databricks API token, which may compromise big data analytics platforms and sensitive data processing." -regex = '''(?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dapi", -] - -[[rules]] -id = "datadog-access-token" -description = "Detected a Datadog Access Token, potentially risking monitoring and analytics data exposure and manipulation." -regex = '''(?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "datadog", -] - -[[rules]] -id = "defined-networking-api-token" -description = "Identified a Defined Networking API token, which could lead to unauthorized network operations and data breaches." -regex = '''(?i)(?:dnkey)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dnkey", -] - -[[rules]] -id = "digitalocean-access-token" -description = "Found a DigitalOcean OAuth Access Token, risking unauthorized cloud resource access and data compromise." -regex = '''(?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "doo_v1_", -] - -[[rules]] -id = "digitalocean-pat" -description = "Discovered a DigitalOcean Personal Access Token, posing a threat to cloud infrastructure security and data privacy." -regex = '''(?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dop_v1_", -] - -[[rules]] -id = "digitalocean-refresh-token" -description = "Uncovered a DigitalOcean OAuth Refresh Token, which could allow prolonged unauthorized access and resource manipulation." -regex = '''(?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dor_v1_", -] - -[[rules]] -id = "discord-api-token" -description = "Detected a Discord API key, potentially compromising communication channels and user data privacy on Discord." -regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "discord", -] - -[[rules]] -id = "discord-client-id" -description = "Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications." -regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "discord", -] - -[[rules]] -id = "discord-client-secret" -description = "Discovered a potential Discord client secret, risking compromised Discord bot integrations and data leaks." -regex = '''(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "discord", -] - -[[rules]] -id = "doppler-api-token" -description = "Discovered a Doppler API token, posing a risk to environment and secrets management security." -regex = '''(dp\.pt\.)(?i)[a-z0-9]{43}''' -keywords = [ - "doppler", -] - -[[rules]] -id = "droneci-access-token" -description = "Detected a Droneci Access Token, potentially compromising continuous integration and deployment workflows." -regex = '''(?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "droneci", -] - -[[rules]] -id = "dropbox-api-token" -description = "Identified a Dropbox API secret, which could lead to unauthorized file access and data breaches in Dropbox storage." -regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dropbox", -] - -[[rules]] -id = "dropbox-long-lived-api-token" -description = "Found a Dropbox long-lived API token, risking prolonged unauthorized access to cloud storage and sensitive data." -regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dropbox", -] - -[[rules]] -id = "dropbox-short-lived-api-token" -description = "Discovered a Dropbox short-lived API token, posing a risk of temporary but potentially harmful data access and manipulation." -regex = '''(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "dropbox", -] - -[[rules]] -id = "duffel-api-token" -description = "Uncovered a Duffel API token, which may compromise travel platform integrations and sensitive customer data." -regex = '''duffel_(test|live)_(?i)[a-z0-9_\-=]{43}''' -keywords = [ - "duffel", -] - -[[rules]] -id = "dynatrace-api-token" -description = "Detected a Dynatrace API token, potentially risking application performance monitoring and data exposure." -regex = '''dt0c01\.(?i)[a-z0-9]{24}\.[a-z0-9]{64}''' -keywords = [ - "dynatrace", -] - -[[rules]] -id = "easypost-api-token" -description = "Identified an EasyPost API token, which could lead to unauthorized postal and shipment service access and data exposure." -regex = '''\bEZAK(?i)[a-z0-9]{54}''' -keywords = [ - "ezak", -] - -[[rules]] -id = "easypost-test-api-token" -description = "Detected an EasyPost test API token, risking exposure of test environments and potentially sensitive shipment data." -regex = '''\bEZTK(?i)[a-z0-9]{54}''' -keywords = [ - "eztk", -] - -[[rules]] -id = "etsy-access-token" -description = "Found an Etsy Access Token, potentially compromising Etsy shop management and customer data." -regex = '''(?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "etsy", -] - -[[rules]] -id = "facebook" -description = "Discovered a Facebook Access Token, posing a risk of unauthorized access to Facebook accounts and personal data exposure." -regex = '''(?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "facebook", -] - -[[rules]] -id = "fastly-api-token" -description = "Uncovered a Fastly API key, which may compromise CDN and edge cloud services, leading to content delivery and security issues." -regex = '''(?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "fastly", -] - -[[rules]] -id = "finicity-api-token" -description = "Detected a Finicity API token, potentially risking financial data access and unauthorized financial operations." -regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "finicity", -] - -[[rules]] -id = "finicity-client-secret" -description = "Identified a Finicity Client Secret, which could lead to compromised financial service integrations and data breaches." -regex = '''(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "finicity", -] - -[[rules]] -id = "finnhub-access-token" -description = "Found a Finnhub Access Token, risking unauthorized access to financial market data and analytics." -regex = '''(?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "finnhub", -] - -[[rules]] -id = "flickr-access-token" -description = "Discovered a Flickr Access Token, posing a risk of unauthorized photo management and potential data leakage." -regex = '''(?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "flickr", -] - -[[rules]] -id = "flutterwave-encryption-key" -description = "Uncovered a Flutterwave Encryption Key, which may compromise payment processing and sensitive financial information." -regex = '''FLWSECK_TEST-(?i)[a-h0-9]{12}''' -keywords = [ - "flwseck_test", -] - -[[rules]] -id = "flutterwave-public-key" -description = "Detected a Finicity Public Key, potentially exposing public cryptographic operations and integrations." -regex = '''FLWPUBK_TEST-(?i)[a-h0-9]{32}-X''' -keywords = [ - "flwpubk_test", -] - -[[rules]] -id = "flutterwave-secret-key" -description = "Identified a Flutterwave Secret Key, risking unauthorized financial transactions and data breaches." -regex = '''FLWSECK_TEST-(?i)[a-h0-9]{32}-X''' -keywords = [ - "flwseck_test", -] - -[[rules]] -id = "frameio-api-token" -description = "Found a Frame.io API token, potentially compromising video collaboration and project management." -regex = '''fio-u-(?i)[a-z0-9\-_=]{64}''' -keywords = [ - "fio-u-", -] - -[[rules]] -id = "freshbooks-access-token" -description = "Discovered a Freshbooks Access Token, posing a risk to accounting software access and sensitive financial data exposure." -regex = '''(?i)(?:freshbooks)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "freshbooks", -] - -[[rules]] -id = "gcp-api-key" -description = "Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches." -regex = '''(?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "aiza", -] - -[[rules]] -id = "generic-api-key" -description = "Detected a Generic API Key, potentially exposing access to various services and sensitive operations." -regex = '''(?i)(?:key|api|token|secret|client|passwd|password|auth|access)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-z\-_.=]{10,150})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -entropy = 3.5 -keywords = [ - "key","api","token","secret","client","passwd","password","auth","access", -] - -[rules.allowlist] -stopwords = [ - "000000", - "aaaaaa", - "about", - "abstract", - "academy", - "acces", - "account", - "act-", - "act.", - "act_", - "action", - "active", - "actively", - "activity", - "adapter", - "add-", - "add.", - "add_", - "add-on", - "addon", - "addres", - "admin", - "adobe", - "advanced", - "adventure", - "agent", - "agile", - "air-", - "air.", - "air_", - "ajax", - "akka", - "alert", - "alfred", - "algorithm", - "all-", - "all.", - "all_", - "alloy", - "alpha", - "amazon", - "amqp", - "analysi", - "analytic", - "analyzer", - "android", - "angular", - "angularj", - "animate", - "animation", - "another", - "ansible", - "answer", - "ant-", - "ant.", - "ant_", - "any-", - "any.", - "any_", - "apache", - "app-", - "app-", - "app.", - "app.", - "app_", - "app_", - "apple", - "arch", - "archive", - "archived", - "arduino", - "array", - "art-", - "art.", - "art_", - "article", - "asp-", - "asp.", - "asp_", - "asset", - "async", - "atom", - "attention", - "audio", - "audit", - "aura", - "auth", - "author", - "author", - "authorize", - "auto", - "automated", - "automatic", - "awesome", - "aws_", - "azure", - "back", - "backbone", - "backend", - "backup", - "bar-", - "bar.", - "bar_", - "base", - "based", - "bash", - "basic", - "batch", - "been", - "beer", - "behavior", - "being", - "benchmark", - "best", - "beta", - "better", - "big-", - "big.", - "big_", - "binary", - "binding", - "bit-", - "bit.", - "bit_", - "bitcoin", - "block", - "blog", - "board", - "book", - "bookmark", - "boost", - "boot", - "bootstrap", - "bosh", - "bot-", - "bot.", - "bot_", - "bower", - "box-", - "box.", - "box_", - "boxen", - "bracket", - "branch", - "bridge", - "browser", - "brunch", - "buffer", - "bug-", - "bug.", - "bug_", - "build", - "builder", - "building", - "buildout", - "buildpack", - "built", - "bundle", - "busines", - "but-", - "but.", - "but_", - "button", - "cache", - "caching", - "cakephp", - "calendar", - "call", - "camera", - "campfire", - "can-", - "can.", - "can_", - "canva", - "captcha", - "capture", - "card", - "carousel", - "case", - "cassandra", - "cat-", - "cat.", - "cat_", - "category", - "center", - "cento", - "challenge", - "change", - "changelog", - "channel", - "chart", - "chat", - "cheat", - "check", - "checker", - "chef", - "ches", - "chinese", - "chosen", - "chrome", - "ckeditor", - "clas", - "classe", - "classic", - "clean", - "cli-", - "cli.", - "cli_", - "client", - "client", - "clojure", - "clone", - "closure", - "cloud", - "club", - "cluster", - "cms-", - "cms_", - "coco", - "code", - "coding", - "coffee", - "color", - "combination", - "combo", - "command", - "commander", - "comment", - "commit", - "common", - "community", - "compas", - "compiler", - "complete", - "component", - "composer", - "computer", - "computing", - "con-", - "con.", - "con_", - "concept", - "conf", - "config", - "config", - "connect", - "connector", - "console", - "contact", - "container", - "contao", - "content", - "contest", - "context", - "control", - "convert", - "converter", - "conway'", - "cookbook", - "cookie", - "cool", - "copy", - "cordova", - "core", - "couchbase", - "couchdb", - "countdown", - "counter", - "course", - "craft", - "crawler", - "create", - "creating", - "creator", - "credential", - "crm-", - "crm.", - "crm_", - "cros", - "crud", - "csv-", - "csv.", - "csv_", - "cube", - "cucumber", - "cuda", - "current", - "currently", - "custom", - "daemon", - "dark", - "dart", - "dash", - "dashboard", - "data", - "database", - "date", - "day-", - "day.", - "day_", - "dead", - "debian", - "debug", - "debug", - "debugger", - "deck", - "define", - "del-", - "del.", - "del_", - "delete", - "demo", - "deploy", - "design", - "designer", - "desktop", - "detection", - "detector", - "dev-", - "dev.", - "dev_", - "develop", - "developer", - "device", - "devise", - "diff", - "digital", - "directive", - "directory", - "discovery", - "display", - "django", - "dns-", - "dns_", - "doc-", - "doc-", - "doc.", - "doc.", - "doc_", - "doc_", - "docker", - "docpad", - "doctrine", - "document", - "doe-", - "doe.", - "doe_", - "dojo", - "dom-", - "dom.", - "dom_", - "domain", - "done", - "don't", - "dot-", - "dot.", - "dot_", - "dotfile", - "download", - "draft", - "drag", - "drill", - "drive", - "driven", - "driver", - "drop", - "dropbox", - "drupal", - "dsl-", - "dsl.", - "dsl_", - "dynamic", - "easy", - "_ec2_", - "ecdsa", - "eclipse", - "edit", - "editing", - "edition", - "editor", - "element", - "emac", - "email", - "embed", - "embedded", - "ember", - "emitter", - "emulator", - "encoding", - "endpoint", - "engine", - "english", - "enhanced", - "entity", - "entry", - "env_", - "episode", - "erlang", - "error", - "espresso", - "event", - "evented", - "example", - "example", - "exchange", - "exercise", - "experiment", - "expire", - "exploit", - "explorer", - "export", - "exporter", - "expres", - "ext-", - "ext.", - "ext_", - "extended", - "extension", - "external", - "extra", - "extractor", - "fabric", - "facebook", - "factory", - "fake", - "fast", - "feature", - "feed", - "fewfwef", - "ffmpeg", - "field", - "file", - "filter", - "find", - "finder", - "firefox", - "firmware", - "first", - "fish", - "fix-", - "fix_", - "flash", - "flask", - "flat", - "flex", - "flexible", - "flickr", - "flow", - "fluent", - "fluentd", - "fluid", - "folder", - "font", - "force", - "foreman", - "fork", - "form", - "format", - "formatter", - "forum", - "foundry", - "framework", - "free", - "friend", - "friendly", - "front-end", - "frontend", - "ftp-", - "ftp.", - "ftp_", - "fuel", - "full", - "fun-", - "fun.", - "fun_", - "func", - "future", - "gaia", - "gallery", - "game", - "gateway", - "gem-", - "gem.", - "gem_", - "gen-", - "gen.", - "gen_", - "general", - "generator", - "generic", - "genetic", - "get-", - "get.", - "get_", - "getenv", - "getting", - "ghost", - "gist", - "git-", - "git.", - "git_", - "github", - "gitignore", - "gitlab", - "glas", - "gmail", - "gnome", - "gnu-", - "gnu.", - "gnu_", - "goal", - "golang", - "gollum", - "good", - "google", - "gpu-", - "gpu.", - "gpu_", - "gradle", - "grail", - "graph", - "graphic", - "great", - "grid", - "groovy", - "group", - "grunt", - "guard", - "gui-", - "gui.", - "gui_", - "guide", - "guideline", - "gulp", - "gwt-", - "gwt.", - "gwt_", - "hack", - "hackathon", - "hacker", - "hacking", - "hadoop", - "haml", - "handler", - "hardware", - "has-", - "has_", - "hash", - "haskell", - "have", - "haxe", - "hello", - "help", - "helper", - "here", - "hero", - "heroku", - "high", - "hipchat", - "history", - "home", - "homebrew", - "homepage", - "hook", - "host", - "hosting", - "hot-", - "hot.", - "hot_", - "house", - "how-", - "how.", - "how_", - "html", - "http", - "hub-", - "hub.", - "hub_", - "hubot", - "human", - "icon", - "ide-", - "ide.", - "ide_", - "idea", - "identity", - "idiomatic", - "image", - "impact", - "import", - "important", - "importer", - "impres", - "index", - "infinite", - "info", - "injection", - "inline", - "input", - "inside", - "inspector", - "instagram", - "install", - "installer", - "instant", - "intellij", - "interface", - "internet", - "interview", - "into", - "intro", - "ionic", - "iphone", - "ipython", - "irc-", - "irc_", - "iso-", - "iso.", - "iso_", - "issue", - "jade", - "jasmine", - "java", - "jbos", - "jekyll", - "jenkin", - "job-", - "job.", - "job_", - "joomla", - "jpa-", - "jpa.", - "jpa_", - "jquery", - "json", - "just", - "kafka", - "karma", - "kata", - "kernel", - "keyboard", - "kindle", - "kit-", - "kit.", - "kit_", - "kitchen", - "knife", - "koan", - "kohana", - "lab-", - "lab-", - "lab.", - "lab.", - "lab_", - "lab_", - "lambda", - "lamp", - "language", - "laravel", - "last", - "latest", - "latex", - "launcher", - "layer", - "layout", - "lazy", - "ldap", - "leaflet", - "league", - "learn", - "learning", - "led-", - "led.", - "led_", - "leetcode", - "les-", - "les.", - "les_", - "level", - "leveldb", - "lib-", - "lib.", - "lib_", - "librarie", - "library", - "license", - "life", - "liferay", - "light", - "lightbox", - "like", - "line", - "link", - "linked", - "linkedin", - "linux", - "lisp", - "list", - "lite", - "little", - "load", - "loader", - "local", - "location", - "lock", - "log-", - "log.", - "log_", - "logger", - "logging", - "logic", - "login", - "logstash", - "longer", - "look", - "love", - "lua-", - "lua.", - "lua_", - "mac-", - "mac.", - "mac_", - "machine", - "made", - "magento", - "magic", - "mail", - "make", - "maker", - "making", - "man-", - "man.", - "man_", - "manage", - "manager", - "manifest", - "manual", - "map-", - "map-", - "map.", - "map.", - "map_", - "map_", - "mapper", - "mapping", - "markdown", - "markup", - "master", - "math", - "matrix", - "maven", - "md5", - "mean", - "media", - "mediawiki", - "meetup", - "memcached", - "memory", - "menu", - "merchant", - "message", - "messaging", - "meta", - "metadata", - "meteor", - "method", - "metric", - "micro", - "middleman", - "migration", - "minecraft", - "miner", - "mini", - "minimal", - "mirror", - "mit-", - "mit.", - "mit_", - "mobile", - "mocha", - "mock", - "mod-", - "mod.", - "mod_", - "mode", - "model", - "modern", - "modular", - "module", - "modx", - "money", - "mongo", - "mongodb", - "mongoid", - "mongoose", - "monitor", - "monkey", - "more", - "motion", - "moved", - "movie", - "mozilla", - "mqtt", - "mule", - "multi", - "multiple", - "music", - "mustache", - "mvc-", - "mvc.", - "mvc_", - "mysql", - "nagio", - "name", - "native", - "need", - "neo-", - "neo.", - "neo_", - "nest", - "nested", - "net-", - "net.", - "net_", - "nette", - "network", - "new-", - "new-", - "new.", - "new.", - "new_", - "new_", - "next", - "nginx", - "ninja", - "nlp-", - "nlp.", - "nlp_", - "node", - "nodej", - "nosql", - "not-", - "not.", - "not_", - "note", - "notebook", - "notepad", - "notice", - "notifier", - "now-", - "now.", - "now_", - "number", - "oauth", - "object", - "objective", - "obsolete", - "ocaml", - "octopres", - "official", - "old-", - "old.", - "old_", - "onboard", - "online", - "only", - "open", - "opencv", - "opengl", - "openshift", - "openwrt", - "option", - "oracle", - "org-", - "org.", - "org_", - "origin", - "original", - "orm-", - "orm.", - "orm_", - "osx-", - "osx_", - "our-", - "our.", - "our_", - "out-", - "out.", - "out_", - "output", - "over", - "overview", - "own-", - "own.", - "own_", - "pack", - "package", - "packet", - "page", - "page", - "panel", - "paper", - "paperclip", - "para", - "parallax", - "parallel", - "parse", - "parser", - "parsing", - "particle", - "party", - "password", - "patch", - "path", - "pattern", - "payment", - "paypal", - "pdf-", - "pdf.", - "pdf_", - "pebble", - "people", - "perl", - "personal", - "phalcon", - "phoenix", - "phone", - "phonegap", - "photo", - "php-", - "php.", - "php_", - "physic", - "picker", - "pipeline", - "platform", - "play", - "player", - "please", - "plu-", - "plu.", - "plu_", - "plug-in", - "plugin", - "plupload", - "png-", - "png.", - "png_", - "poker", - "polyfill", - "polymer", - "pool", - "pop-", - "pop.", - "pop_", - "popcorn", - "popup", - "port", - "portable", - "portal", - "portfolio", - "post", - "power", - "powered", - "powerful", - "prelude", - "pretty", - "preview", - "principle", - "print", - "pro-", - "pro.", - "pro_", - "problem", - "proc", - "product", - "profile", - "profiler", - "program", - "progres", - "project", - "protocol", - "prototype", - "provider", - "proxy", - "public", - "pull", - "puppet", - "pure", - "purpose", - "push", - "pusher", - "pyramid", - "python", - "quality", - "query", - "queue", - "quick", - "rabbitmq", - "rack", - "radio", - "rail", - "railscast", - "random", - "range", - "raspberry", - "rdf-", - "rdf.", - "rdf_", - "react", - "reactive", - "read", - "reader", - "readme", - "ready", - "real", - "reality", - "real-time", - "realtime", - "recipe", - "recorder", - "red-", - "red.", - "red_", - "reddit", - "redi", - "redmine", - "reference", - "refinery", - "refresh", - "registry", - "related", - "release", - "remote", - "rendering", - "repo", - "report", - "request", - "require", - "required", - "requirej", - "research", - "resource", - "response", - "resque", - "rest", - "restful", - "resume", - "reveal", - "reverse", - "review", - "riak", - "rich", - "right", - "ring", - "robot", - "role", - "room", - "router", - "routing", - "rpc-", - "rpc.", - "rpc_", - "rpg-", - "rpg.", - "rpg_", - "rspec", - "ruby-", - "ruby.", - "ruby_", - "rule", - "run-", - "run.", - "run_", - "runner", - "running", - "runtime", - "rust", - "rvm-", - "rvm.", - "rvm_", - "salt", - "sample", - "sample", - "sandbox", - "sas-", - "sas.", - "sas_", - "sbt-", - "sbt.", - "sbt_", - "scala", - "scalable", - "scanner", - "schema", - "scheme", - "school", - "science", - "scraper", - "scratch", - "screen", - "script", - "scroll", - "scs-", - "scs.", - "scs_", - "sdk-", - "sdk.", - "sdk_", - "sdl-", - "sdl.", - "sdl_", - "search", - "secure", - "security", - "see-", - "see.", - "see_", - "seed", - "select", - "selector", - "selenium", - "semantic", - "sencha", - "send", - "sentiment", - "serie", - "server", - "service", - "session", - "set-", - "set.", - "set_", - "setting", - "setting", - "setup", - "sha1", - "sha2", - "sha256", - "share", - "shared", - "sharing", - "sheet", - "shell", - "shield", - "shipping", - "shop", - "shopify", - "shortener", - "should", - "show", - "showcase", - "side", - "silex", - "simple", - "simulator", - "single", - "site", - "skeleton", - "sketch", - "skin", - "slack", - "slide", - "slider", - "slim", - "small", - "smart", - "smtp", - "snake", - "snippet", - "soap", - "social", - "socket", - "software", - "solarized", - "solr", - "solution", - "solver", - "some", - "soon", - "source", - "space", - "spark", - "spatial", - "spec", - "sphinx", - "spine", - "spotify", - "spree", - "spring", - "sprite", - "sql-", - "sql.", - "sql_", - "sqlite", - "ssh-", - "ssh.", - "ssh_", - "stack", - "staging", - "standard", - "stanford", - "start", - "started", - "starter", - "startup", - "stat", - "statamic", - "state", - "static", - "statistic", - "statsd", - "statu", - "steam", - "step", - "still", - "stm-", - "stm.", - "stm_", - "storage", - "store", - "storm", - "story", - "strategy", - "stream", - "streaming", - "string", - "stripe", - "structure", - "studio", - "study", - "stuff", - "style", - "sublime", - "sugar", - "suite", - "summary", - "super", - "support", - "supported", - "svg-", - "svg.", - "svg_", - "svn-", - "svn.", - "svn_", - "swagger", - "swift", - "switch", - "switcher", - "symfony", - "symphony", - "sync", - "synopsi", - "syntax", - "system", - "system", - "tab-", - "tab-", - "tab.", - "tab.", - "tab_", - "tab_", - "table", - "tag-", - "tag-", - "tag.", - "tag.", - "tag_", - "tag_", - "talk", - "target", - "task", - "tcp-", - "tcp.", - "tcp_", - "tdd-", - "tdd.", - "tdd_", - "team", - "tech", - "template", - "term", - "terminal", - "testing", - "tetri", - "text", - "textmate", - "theme", - "theory", - "three", - "thrift", - "time", - "timeline", - "timer", - "tiny", - "tinymce", - "tip-", - "tip.", - "tip_", - "title", - "todo", - "todomvc", - "token", - "tool", - "toolbox", - "toolkit", - "top-", - "top.", - "top_", - "tornado", - "touch", - "tower", - "tracker", - "tracking", - "traffic", - "training", - "transfer", - "translate", - "transport", - "tree", - "trello", - "try-", - "try.", - "try_", - "tumblr", - "tut-", - "tut.", - "tut_", - "tutorial", - "tweet", - "twig", - "twitter", - "type", - "typo", - "ubuntu", - "uiview", - "ultimate", - "under", - "unit", - "unity", - "universal", - "unix", - "update", - "updated", - "upgrade", - "upload", - "uploader", - "uri-", - "uri.", - "uri_", - "url-", - "url.", - "url_", - "usage", - "usb-", - "usb.", - "usb_", - "use-", - "use.", - "use_", - "used", - "useful", - "user", - "using", - "util", - "utilitie", - "utility", - "vagrant", - "validator", - "value", - "variou", - "varnish", - "version", - "via-", - "via.", - "via_", - "video", - "view", - "viewer", - "vim-", - "vim.", - "vim_", - "vimrc", - "virtual", - "vision", - "visual", - "vpn", - "want", - "warning", - "watch", - "watcher", - "wave", - "way-", - "way.", - "way_", - "weather", - "web-", - "web_", - "webapp", - "webgl", - "webhook", - "webkit", - "webrtc", - "website", - "websocket", - "welcome", - "welcome", - "what", - "what'", - "when", - "where", - "which", - "why-", - "why.", - "why_", - "widget", - "wifi", - "wiki", - "win-", - "win.", - "win_", - "window", - "wip-", - "wip.", - "wip_", - "within", - "without", - "wizard", - "word", - "wordpres", - "work", - "worker", - "workflow", - "working", - "workshop", - "world", - "wrapper", - "write", - "writer", - "writing", - "written", - "www-", - "www.", - "www_", - "xamarin", - "xcode", - "xml-", - "xml.", - "xml_", - "xmpp", - "xxxxxx", - "yahoo", - "yaml", - "yandex", - "yeoman", - "yet-", - "yet.", - "yet_", - "yii-", - "yii.", - "yii_", - "youtube", - "yui-", - "yui.", - "yui_", - "zend", - "zero", - "zip-", - "zip.", - "zip_", - "zsh-", - "zsh.", - "zsh_", -] - -[[rules]] -id = "github-app-token" -description = "Identified a GitHub App Token, which may compromise GitHub application integrations and source code security." -regex = '''(ghu|ghs)_[0-9a-zA-Z]{36}''' -keywords = [ - "ghu_","ghs_", -] - -[[rules]] -id = "github-fine-grained-pat" -description = "Found a GitHub Fine-Grained Personal Access Token, risking unauthorized repository access and code manipulation." -regex = '''github_pat_[0-9a-zA-Z_]{82}''' -keywords = [ - "github_pat_", -] - -[[rules]] -id = "github-oauth" -description = "Discovered a GitHub OAuth Access Token, posing a risk of compromised GitHub account integrations and data leaks." -regex = '''gho_[0-9a-zA-Z]{36}''' -keywords = [ - "gho_", -] - -[[rules]] -id = "github-pat" -description = "Uncovered a GitHub Personal Access Token, potentially leading to unauthorized repository access and sensitive content exposure." -regex = '''ghp_[0-9a-zA-Z]{36}''' -keywords = [ - "ghp_", -] - -[[rules]] -id = "github-refresh-token" -description = "Detected a GitHub Refresh Token, which could allow prolonged unauthorized access to GitHub services." -regex = '''ghr_[0-9a-zA-Z]{36}''' -keywords = [ - "ghr_", -] - -[[rules]] -id = "gitlab-pat" -description = "Identified a GitLab Personal Access Token, risking unauthorized access to GitLab repositories and codebase exposure." -regex = '''glpat-[0-9a-zA-Z\-\_]{20}''' -keywords = [ - "glpat-", -] - -[[rules]] -id = "gitlab-ptt" -description = "Found a GitLab Pipeline Trigger Token, potentially compromising continuous integration workflows and project security." -regex = '''glptt-[0-9a-f]{40}''' -keywords = [ - "glptt-", -] - -[[rules]] -id = "gitlab-rrt" -description = "Discovered a GitLab Runner Registration Token, posing a risk to CI/CD pipeline integrity and unauthorized access." -regex = '''GR1348941[0-9a-zA-Z\-\_]{20}''' -keywords = [ - "gr1348941", -] - -[[rules]] -id = "gitter-access-token" -description = "Uncovered a Gitter Access Token, which may lead to unauthorized access to chat and communication services." -regex = '''(?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "gitter", -] - -[[rules]] -id = "gocardless-api-token" -description = "Detected a GoCardless API token, potentially risking unauthorized direct debit payment operations and financial data exposure." -regex = '''(?i)(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(live_(?i)[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "live_","gocardless", -] - -[[rules]] -id = "grafana-api-key" -description = "Identified a Grafana API key, which could compromise monitoring dashboards and sensitive data analytics." -regex = '''(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "eyjrijoi", -] - -[[rules]] -id = "grafana-cloud-api-token" -description = "Found a Grafana cloud API token, risking unauthorized access to cloud-based monitoring services and data exposure." -regex = '''(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "glc_", -] - -[[rules]] -id = "grafana-service-account-token" -description = "Discovered a Grafana service account token, posing a risk of compromised monitoring services and data integrity." -regex = '''(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "glsa_", -] - -[[rules]] -id = "hashicorp-tf-api-token" -description = "Uncovered a HashiCorp Terraform user/org API token, which may lead to unauthorized infrastructure management and security breaches." -regex = '''(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}''' -keywords = [ - "atlasv1", -] - -[[rules]] -id = "hashicorp-tf-password" -description = "Identified a HashiCorp Terraform password field, risking unauthorized infrastructure configuration and security breaches." -regex = '''(?i)(?:administrator_login_password|password)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}("[a-z0-9=_\-]{8,20}")(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "administrator_login_password","password", -] - -[[rules]] -id = "heroku-api-key" -description = "Detected a Heroku API Key, potentially compromising cloud application deployments and operational security." -regex = '''(?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "heroku", -] - -[[rules]] -id = "hubspot-api-key" -description = "Found a HubSpot API Token, posing a risk to CRM data integrity and unauthorized marketing operations." -regex = '''(?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "hubspot", -] - -[[rules]] -id = "huggingface-access-token" -description = "Discovered a Hugging Face Access token, which could lead to unauthorized access to AI models and sensitive data." -regex = '''(?:^|[\\'"` >=:])(hf_[a-zA-Z]{34})(?:$|[\\'"` <])''' -entropy = 1 -keywords = [ - "hf_", -] - -[[rules]] -id = "huggingface-organization-api-token" -description = "Uncovered a Hugging Face Organization API token, potentially compromising AI organization accounts and associated data." -regex = '''(?:^|[\\'"` >=:\(,)])(api_org_[a-zA-Z]{34})(?:$|[\\'"` <\),])''' -entropy = 2 -keywords = [ - "api_org_", -] - -[[rules]] -id = "infracost-api-token" -description = "Detected an Infracost API Token, risking unauthorized access to cloud cost estimation tools and financial data." -regex = '''(?i)\b(ico-[a-zA-Z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "ico-", -] - -[[rules]] -id = "intercom-api-key" -description = "Identified an Intercom API Token, which could compromise customer communication channels and data privacy." -regex = '''(?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "intercom", -] - -[[rules]] -id = "jfrog-api-key" -description = "Found a JFrog API Key, posing a risk of unauthorized access to software artifact repositories and build pipelines." -regex = '''(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{73})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "jfrog","artifactory","bintray","xray", -] - -[[rules]] -id = "jfrog-identity-token" -description = "Discovered a JFrog Identity Token, potentially compromising access to JFrog services and sensitive software artifacts." -regex = '''(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "jfrog","artifactory","bintray","xray", -] - -[[rules]] -id = "jwt" -description = "Uncovered a JSON Web Token, which may lead to unauthorized access to web applications and sensitive user data." -regex = '''\b(ey[a-zA-Z0-9]{17,}\.ey[a-zA-Z0-9\/\\_-]{17,}\.(?:[a-zA-Z0-9\/\\_-]{10,}={0,2})?)(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "ey", -] - -[[rules]] -id = "jwt-base64" -description = "Detected a Base64-encoded JSON Web Token, posing a risk of exposing encoded authentication and data exchange information." -regex = '''\bZXlK(?:(?PaGJHY2lPaU)|(?PaGNIVWlPaU)|(?PaGNIWWlPaU)|(?PaGRXUWlPaU)|(?PaU5qUWlP)|(?PamNtbDBJanBi)|(?PamRIa2lPaU)|(?PbGNHc2lPbn)|(?PbGJtTWlPaU)|(?PcWEzVWlPaU)|(?PcWQyc2lPb)|(?PcGMzTWlPaU)|(?PcGRpSTZJ)|(?PcmFXUWlP)|(?PclpYbGZiM0J6SWpwY)|(?PcmRIa2lPaUp)|(?PdWIyNWpaU0k2)|(?Pd01tTWlP)|(?Pd01uTWlPaU)|(?Pd2NIUWlPaU)|(?PemRXSWlPaU)|(?PemRuUWlP)|(?PMFlXY2lPaU)|(?PMGVYQWlPaUp)|(?PMWNtd2l)|(?PMWMyVWlPaUp)|(?PMlpYSWlPaU)|(?PMlpYSnphVzl1SWpv)|(?PNElqb2)|(?PNE5XTWlP)|(?PNE5YUWlPaU)|(?PNE5YUWpVekkxTmlJNkl)|(?PNE5YVWlPaU)|(?PNmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2}''' -keywords = [ - "zxlk", -] - -[[rules]] -id = "kraken-access-token" -description = "Identified a Kraken Access Token, potentially compromising cryptocurrency trading accounts and financial security." -regex = '''(?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "kraken", -] - -[[rules]] -id = "kucoin-access-token" -description = "Found a Kucoin Access Token, risking unauthorized access to cryptocurrency exchange services and transactions." -regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "kucoin", -] - -[[rules]] -id = "kucoin-secret-key" -description = "Discovered a Kucoin Secret Key, which could lead to compromised cryptocurrency operations and financial data breaches." -regex = '''(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "kucoin", -] - -[[rules]] -id = "launchdarkly-access-token" -description = "Uncovered a Launchdarkly Access Token, potentially compromising feature flag management and application functionality." -regex = '''(?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "launchdarkly", -] - -[[rules]] -id = "linear-api-key" -description = "Detected a Linear API Token, posing a risk to project management tools and sensitive task data." -regex = '''lin_api_(?i)[a-z0-9]{40}''' -keywords = [ - "lin_api_", -] - -[[rules]] -id = "linear-client-secret" -description = "Identified a Linear Client Secret, which may compromise secure integrations and sensitive project management data." -regex = '''(?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "linear", -] - -[[rules]] -id = "linkedin-client-id" -description = "Found a LinkedIn Client ID, risking unauthorized access to LinkedIn integrations and professional data exposure." -regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "linkedin","linked-in", -] - -[[rules]] -id = "linkedin-client-secret" -description = "Discovered a LinkedIn Client secret, potentially compromising LinkedIn application integrations and user data." -regex = '''(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "linkedin","linked-in", -] - -[[rules]] -id = "lob-api-key" -description = "Uncovered a Lob API Key, which could lead to unauthorized access to mailing and address verification services." -regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "test_","live_", -] - -[[rules]] -id = "lob-pub-api-key" -description = "Detected a Lob Publishable API Key, posing a risk of exposing mail and print service integrations." -regex = '''(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "test_pub","live_pub","_pub", -] - -[[rules]] -id = "mailchimp-api-key" -description = "Identified a Mailchimp API key, potentially compromising email marketing campaigns and subscriber data." -regex = '''(?i)(?:mailchimp)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32}-us20)(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mailchimp", -] - -[[rules]] -id = "mailgun-private-api-token" -description = "Found a Mailgun private API token, risking unauthorized email service operations and data breaches." -regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mailgun", -] - -[[rules]] -id = "mailgun-pub-key" -description = "Discovered a Mailgun public validation key, which could expose email verification processes and associated data." -regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mailgun", -] - -[[rules]] -id = "mailgun-signing-key" -description = "Uncovered a Mailgun webhook signing key, potentially compromising email automation and data integrity." -regex = '''(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mailgun", -] - -[[rules]] -id = "mapbox-api-token" -description = "Detected a MapBox API token, posing a risk to geospatial services and sensitive location data exposure." -regex = '''(?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mapbox", -] - -[[rules]] -id = "mattermost-access-token" -description = "Identified a Mattermost Access Token, which may compromise team communication channels and data privacy." -regex = '''(?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "mattermost", -] - -[[rules]] -id = "messagebird-api-token" -description = "Found a MessageBird API token, risking unauthorized access to communication platforms and message data." -regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "messagebird","message-bird","message_bird", -] - -[[rules]] -id = "messagebird-client-id" -description = "Discovered a MessageBird client ID, potentially compromising API integrations and sensitive communication data." -regex = '''(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "messagebird","message-bird","message_bird", -] - -[[rules]] -id = "microsoft-teams-webhook" -description = "Uncovered a Microsoft Teams Webhook, which could lead to unauthorized access to team collaboration tools and data leaks." -regex = '''https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}''' -keywords = [ - "webhook.office.com","webhookb2","incomingwebhook", -] - -[[rules]] -id = "netlify-access-token" -description = "Detected a Netlify Access Token, potentially compromising web hosting services and site management." -regex = '''(?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "netlify", -] - -[[rules]] -id = "new-relic-browser-api-token" -description = "Identified a New Relic ingest browser API token, risking unauthorized access to application performance data and analytics." -regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "nrjs-", -] - -[[rules]] -id = "new-relic-user-api-id" -description = "Found a New Relic user API ID, posing a risk to application monitoring services and data integrity." -regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "new-relic","newrelic","new_relic", -] - -[[rules]] -id = "new-relic-user-api-key" -description = "Discovered a New Relic user API Key, which could lead to compromised application insights and performance monitoring." -regex = '''(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "nrak", -] - -[[rules]] -id = "npm-access-token" -description = "Uncovered an npm access token, potentially compromising package management and code repository access." -regex = '''(?i)\b(npm_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "npm_", -] - -[[rules]] -id = "nytimes-access-token" -description = "Detected a Nytimes Access Token, risking unauthorized access to New York Times APIs and content services." -regex = '''(?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "nytimes","new-york-times","newyorktimes", -] - -[[rules]] -id = "okta-access-token" -description = "Identified an Okta Access Token, which may compromise identity management services and user authentication data." -regex = '''(?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "okta", -] - -[[rules]] -id = "openai-api-key" -description = "Found an OpenAI API Key, posing a risk of unauthorized access to AI services and data manipulation." -regex = '''(?i)\b(sk-[a-zA-Z0-9]{20}T3BlbkFJ[a-zA-Z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "t3blbkfj", -] - -[[rules]] -id = "plaid-api-token" -description = "Discovered a Plaid API Token, potentially compromising financial data aggregation and banking services." -regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(access-(?:sandbox|development|production)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "plaid", -] - -[[rules]] -id = "plaid-client-id" -description = "Uncovered a Plaid Client ID, which could lead to unauthorized financial service integrations and data breaches." -regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -entropy = 3.5 -keywords = [ - "plaid", -] - -[[rules]] -id = "plaid-secret-key" -description = "Detected a Plaid Secret key, risking unauthorized access to financial accounts and sensitive transaction data." -regex = '''(?i)(?:plaid)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -entropy = 3.5 -keywords = [ - "plaid", -] - -[[rules]] -id = "planetscale-api-token" -description = "Identified a PlanetScale API token, potentially compromising database management and operations." -regex = '''(?i)\b(pscale_tkn_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pscale_tkn_", -] - -[[rules]] -id = "planetscale-oauth-token" -description = "Found a PlanetScale OAuth token, posing a risk to database access control and sensitive data integrity." -regex = '''(?i)\b(pscale_oauth_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pscale_oauth_", -] - -[[rules]] -id = "planetscale-password" -description = "Discovered a PlanetScale password, which could lead to unauthorized database operations and data breaches." -regex = '''(?i)\b(pscale_pw_(?i)[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pscale_pw_", -] - -[[rules]] -id = "postman-api-token" -description = "Uncovered a Postman API token, potentially compromising API testing and development workflows." -regex = '''(?i)\b(PMAK-(?i)[a-f0-9]{24}\-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pmak-", -] - -[[rules]] -id = "prefect-api-token" -description = "Detected a Prefect API token, risking unauthorized access to workflow management and automation services." -regex = '''(?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pnu_", -] - -[[rules]] -id = "private-key" -description = "Identified a Private Key, which may compromise cryptographic security and sensitive data encryption." -regex = '''(?i)-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY( BLOCK)?-----[\s\S-]*KEY( BLOCK)?----''' -keywords = [ - "-----begin", -] - -[[rules]] -id = "pulumi-api-token" -description = "Found a Pulumi API token, posing a risk to infrastructure as code services and cloud resource management." -regex = '''(?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "pul-", -] - -[[rules]] -id = "pypi-upload-token" -description = "Discovered a PyPI upload token, potentially compromising Python package distribution and repository integrity." -regex = '''pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}''' -keywords = [ - "pypi-ageichlwas5vcmc", -] - -[[rules]] -id = "rapidapi-access-token" -description = "Uncovered a RapidAPI Access Token, which could lead to unauthorized access to various APIs and data services." -regex = '''(?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "rapidapi", -] - -[[rules]] -id = "readme-api-token" -description = "Detected a Readme API token, risking unauthorized documentation management and content exposure." -regex = '''(?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "rdme_", -] - -[[rules]] -id = "rubygems-api-token" -description = "Identified a Rubygem API token, potentially compromising Ruby library distribution and package management." -regex = '''(?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "rubygems_", -] - -[[rules]] -id = "scalingo-api-token" -description = "Found a Scalingo API token, posing a risk to cloud platform services and application deployment security." -regex = '''\btk-us-[a-zA-Z0-9-_]{48}\b''' -keywords = [ - "tk-us-", -] - -[[rules]] -id = "sendbird-access-id" -description = "Discovered a Sendbird Access ID, which could compromise chat and messaging platform integrations." -regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sendbird", -] - -[[rules]] -id = "sendbird-access-token" -description = "Uncovered a Sendbird Access Token, potentially risking unauthorized access to communication services and user data." -regex = '''(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sendbird", -] - -[[rules]] -id = "sendgrid-api-token" -description = "Detected a SendGrid API token, posing a risk of unauthorized email service operations and data exposure." -regex = '''(?i)\b(SG\.(?i)[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sg.", -] - -[[rules]] -id = "sendinblue-api-token" -description = "Identified a Sendinblue API token, which may compromise email marketing services and subscriber data privacy." -regex = '''(?i)\b(xkeysib-[a-f0-9]{64}\-(?i)[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "xkeysib-", -] - -[[rules]] -id = "sentry-access-token" -description = "Found a Sentry Access Token, risking unauthorized access to error tracking services and sensitive application data." -regex = '''(?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sentry", -] - -[[rules]] -id = "shippo-api-token" -description = "Discovered a Shippo API token, potentially compromising shipping services and customer order data." -regex = '''(?i)\b(shippo_(live|test)_[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "shippo_", -] - -[[rules]] -id = "shopify-access-token" -description = "Uncovered a Shopify access token, which could lead to unauthorized e-commerce platform access and data breaches." -regex = '''shpat_[a-fA-F0-9]{32}''' -keywords = [ - "shpat_", -] - -[[rules]] -id = "shopify-custom-access-token" -description = "Detected a Shopify custom access token, potentially compromising custom app integrations and e-commerce data security." -regex = '''shpca_[a-fA-F0-9]{32}''' -keywords = [ - "shpca_", -] - -[[rules]] -id = "shopify-private-app-access-token" -description = "Identified a Shopify private app access token, risking unauthorized access to private app data and store operations." -regex = '''shppa_[a-fA-F0-9]{32}''' -keywords = [ - "shppa_", -] - -[[rules]] -id = "shopify-shared-secret" -description = "Found a Shopify shared secret, posing a risk to application authentication and e-commerce platform security." -regex = '''shpss_[a-fA-F0-9]{32}''' -keywords = [ - "shpss_", -] - -[[rules]] -id = "sidekiq-secret" -description = "Discovered a Sidekiq Secret, which could lead to compromised background job processing and application data breaches." -regex = '''(?i)(?:BUNDLE_ENTERPRISE__CONTRIBSYS__COM|BUNDLE_GEMS__CONTRIBSYS__COM)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{8}:[a-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "bundle_enterprise__contribsys__com","bundle_gems__contribsys__com", -] - -[[rules]] -id = "sidekiq-sensitive-url" -description = "Uncovered a Sidekiq Sensitive URL, potentially exposing internal job queues and sensitive operation details." -regex = '''(?i)\b(http(?:s??):\/\/)([a-f0-9]{8}:[a-f0-9]{8})@(?:gems.contribsys.com|enterprise.contribsys.com)(?:[\/|\#|\?|:]|$)''' -secretGroup = 2 -keywords = [ - "gems.contribsys.com","enterprise.contribsys.com", -] - -[[rules]] -id = "slack-app-token" -description = "Detected a Slack App-level token, risking unauthorized access to Slack applications and workspace data." -regex = '''(?i)(xapp-\d-[A-Z0-9]+-\d+-[a-z0-9]+)''' -keywords = [ - "xapp", -] - -[[rules]] -id = "slack-bot-token" -description = "Identified a Slack Bot token, which may compromise bot integrations and communication channel security." -regex = '''(xoxb-[0-9]{10,13}\-[0-9]{10,13}[a-zA-Z0-9-]*)''' -keywords = [ - "xoxb", -] - -[[rules]] -id = "slack-config-access-token" -description = "Found a Slack Configuration access token, posing a risk to workspace configuration and sensitive data access." -regex = '''(?i)(xoxe.xox[bp]-\d-[A-Z0-9]{163,166})''' -keywords = [ - "xoxe.xoxb-","xoxe.xoxp-", -] - -[[rules]] -id = "slack-config-refresh-token" -description = "Discovered a Slack Configuration refresh token, potentially allowing prolonged unauthorized access to configuration settings." -regex = '''(?i)(xoxe-\d-[A-Z0-9]{146})''' -keywords = [ - "xoxe-", -] - -[[rules]] -id = "slack-legacy-bot-token" -description = "Uncovered a Slack Legacy bot token, which could lead to compromised legacy bot operations and data exposure." -regex = '''(xoxb-[0-9]{8,14}\-[a-zA-Z0-9]{18,26})''' -keywords = [ - "xoxb", -] - -[[rules]] -id = "slack-legacy-token" -description = "Detected a Slack Legacy token, risking unauthorized access to older Slack integrations and user data." -regex = '''(xox[os]-\d+-\d+-\d+-[a-fA-F\d]+)''' -keywords = [ - "xoxo","xoxs", -] - -[[rules]] -id = "slack-legacy-workspace-token" -description = "Identified a Slack Legacy Workspace token, potentially compromising access to workspace data and legacy features." -regex = '''(xox[ar]-(?:\d-)?[0-9a-zA-Z]{8,48})''' -keywords = [ - "xoxa","xoxr", -] - -[[rules]] -id = "slack-user-token" -description = "Found a Slack User token, posing a risk of unauthorized user impersonation and data access within Slack workspaces." -regex = '''(xox[pe](?:-[0-9]{10,13}){3}-[a-zA-Z0-9-]{28,34})''' -keywords = [ - "xoxp-","xoxe-", -] - -[[rules]] -id = "slack-webhook-url" -description = "Discovered a Slack Webhook, which could lead to unauthorized message posting and data leakage in Slack channels." -regex = '''(https?:\/\/)?hooks.slack.com\/(services|workflows)\/[A-Za-z0-9+\/]{43,46}''' -keywords = [ - "hooks.slack.com", -] - -[[rules]] -id = "snyk-api-token" -description = "Uncovered a Snyk API token, potentially compromising software vulnerability scanning and code security." -regex = '''(?i)(?:snyk_token|snyk_key|snyk_api_token|snyk_api_key|snyk_oauth_token)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "snyk_token","snyk_key","snyk_api_token","snyk_api_key","snyk_oauth_token", -] - -[[rules]] -id = "square-access-token" -description = "Detected a Square Access Token, risking unauthorized payment processing and financial transaction exposure." -regex = '''(?i)\b(sq0atp-[0-9A-Za-z\-_]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sq0atp-", -] - -[[rules]] -id = "squarespace-access-token" -description = "Identified a Squarespace Access Token, which may compromise website management and content control on Squarespace." -regex = '''(?i)(?:squarespace)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "squarespace", -] - -[[rules]] -id = "stripe-access-token" -description = "Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data." -regex = '''(?i)\b((sk)_(test|live)_[0-9a-z]{10,32})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "sk_test","sk_live", -] - -[[rules]] -id = "sumologic-access-id" -description = "Discovered a SumoLogic Access ID, potentially compromising log management services and data analytics integrity." -regex = '''(?i:(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3})(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(su[a-zA-Z0-9]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -entropy = 3 -keywords = [ - "sumo", -] - -[rules.allowlist] - -regexTarget = "line" -regexes = [ - "sumOf", -] - -[[rules]] -id = "sumologic-access-token" -description = "Uncovered a SumoLogic Access Token, which could lead to unauthorized access to log data and analytics insights." -regex = '''(?i)(?:sumo)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -entropy = 3 -keywords = [ - "sumo", -] - -[[rules]] -id = "telegram-bot-api-token" -description = "Detected a Telegram Bot API Token, risking unauthorized bot operations and message interception on Telegram." -regex = '''(?i)(?:^|[^0-9])([0-9]{5,16}:A[a-zA-Z0-9_\-]{34})(?:$|[^a-zA-Z0-9_\-])''' -keywords = [ - "telegram","api","bot","token","url", -] - -[[rules]] -id = "travisci-access-token" -description = "Identified a Travis CI Access Token, potentially compromising continuous integration services and codebase security." -regex = '''(?i)(?:travis)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "travis", -] - -[[rules]] -id = "twilio-api-key" -description = "Found a Twilio API Key, posing a risk to communication services and sensitive customer interaction data." -regex = '''SK[0-9a-fA-F]{32}''' -keywords = [ - "twilio", -] - -[[rules]] -id = "twitch-api-token" -description = "Discovered a Twitch API token, which could compromise streaming services and account integrations." -regex = '''(?i)(?:twitch)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitch", -] - -[[rules]] -id = "twitter-access-secret" -description = "Uncovered a Twitter Access Secret, potentially risking unauthorized Twitter integrations and data breaches." -regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{45})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitter", -] - -[[rules]] -id = "twitter-access-token" -description = "Detected a Twitter Access Token, posing a risk of unauthorized account operations and social media data exposure." -regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{15,25}-[a-zA-Z0-9]{20,40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitter", -] - -[[rules]] -id = "twitter-api-key" -description = "Identified a Twitter API Key, which may compromise Twitter application integrations and user data security." -regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitter", -] - -[[rules]] -id = "twitter-api-secret" -description = "Found a Twitter API Secret, risking the security of Twitter app integrations and sensitive data access." -regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitter", -] - -[[rules]] -id = "twitter-bearer-token" -description = "Discovered a Twitter Bearer Token, potentially compromising API access and data retrieval from Twitter." -regex = '''(?i)(?:twitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(A{22}[a-zA-Z0-9%]{80,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "twitter", -] - -[[rules]] -id = "typeform-api-token" -description = "Uncovered a Typeform API token, which could lead to unauthorized survey management and data collection." -regex = '''(?i)(?:typeform)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(tfp_[a-z0-9\-_\.=]{59})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "tfp_", -] - -[[rules]] -id = "vault-batch-token" -description = "Detected a Vault Batch Token, risking unauthorized access to secret management services and sensitive data." -regex = '''(?i)\b(hvb\.[a-z0-9_-]{138,212})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "hvb", -] - -[[rules]] -id = "vault-service-token" -description = "Identified a Vault Service Token, potentially compromising infrastructure security and access to sensitive credentials." -regex = '''(?i)\b(hvs\.[a-z0-9_-]{90,100})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "hvs", -] - -[[rules]] -id = "yandex-access-token" -description = "Found a Yandex Access Token, posing a risk to Yandex service integrations and user data privacy." -regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(t1\.[A-Z0-9a-z_-]+[=]{0,2}\.[A-Z0-9a-z_-]{86}[=]{0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "yandex", -] - -[[rules]] -id = "yandex-api-key" -description = "Discovered a Yandex API Key, which could lead to unauthorized access to Yandex services and data manipulation." -regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(AQVN[A-Za-z0-9_\-]{35,38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "yandex", -] - -[[rules]] -id = "yandex-aws-access-token" -description = "Uncovered a Yandex AWS Access Token, potentially compromising cloud resource access and data security on Yandex Cloud." -regex = '''(?i)(?:yandex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(YC[a-zA-Z0-9_\-]{38})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "yandex", -] - -[[rules]] -id = "zendesk-secret-key" -description = "Detected a Zendesk Secret Key, risking unauthorized access to customer support services and sensitive ticketing data." -regex = '''(?i)(?:zendesk)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)''' -keywords = [ - "zendesk", -] diff --git a/.gitleaksignore b/.gitleaksignore deleted file mode 100644 index 070fb56530..0000000000 --- a/.gitleaksignore +++ /dev/null @@ -1,157 +0,0 @@ -app/src/gms/google-services.json:gcp-api-key:24 -app/src/gms/google-services.json:gcp-api-key:27 -app/src/gms/google-services.json:gcp-api-key:56 -app/src/gms/google-services.json:gcp-api-key:59 -app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:508 -app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 -app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:101 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:106 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:131 -app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 -app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 -app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 -app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 -data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 -data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 -data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:73 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 -app/src/gms/google-services.json:gcp-api-key:24 -app/src/gms/google-services.json:gcp-api-key:27 -app/src/gms/google-services.json:gcp-api-key:56 -app/src/gms/google-services.json:gcp-api-key:59 -app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:508 -app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 -app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:101 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:106 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:131 -app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 -app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 -app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 -app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 -data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 -data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 -data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:73 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 -app/src/gms/google-services.json:gcp-api-key:24 -app/src/gms/google-services.json:gcp-api-key:27 -app/src/gms/google-services.json:gcp-api-key:56 -app/src/gms/google-services.json:gcp-api-key:59 -app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:492 -app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 -app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:118 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:123 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:153 -app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 -app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 -app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:243 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:274 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:395 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:413 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:431 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:448 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:467 -app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 -data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 -data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 -data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:68 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 -app/src/gms/google-services.json:gcp-api-key:24 -app/src/gms/google-services.json:gcp-api-key:27 -app/src/gms/google-services.json:gcp-api-key:56 -app/src/gms/google-services.json:gcp-api-key:59 -app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:492 -app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt:hashicorp-tf-password:2829 -app/src/main/java/mega/privacy/android/app/main/DecryptAlertDialog.kt:hashicorp-tf-password:283 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:118 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:123 -app/src/main/java/mega/privacy/android/app/presentation/changepassword/view/ChangePasswordComposeView.kt:hashicorp-tf-password:153 -app/src/main/java/mega/privacy/android/app/presentation/testpassword/TestPasswordActivity.kt:hashicorp-tf-password:244 -app/src/main/java/mega/privacy/android/app/presentation/verifytwofactor/VerifyTwoFactorActivity.kt:hashicorp-tf-password:108 -app/src/main/java/mega/privacy/android/app/utils/Constants.java:hashicorp-tf-password:75 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:112 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:242 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:273 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:393 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:394 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:411 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:412 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:429 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:430 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:447 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:465 -app/src/test/java/test/mega/privacy/android/app/presentation/changepassword/ChangePasswordViewModelTest.kt:hashicorp-tf-password:466 -app/src/test/java/test/mega/privacy/android/app/presentation/settings/exportrecoverykey/ExportRecoveryKeyViewModelTest.kt:generic-api-key:40 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:generic-api-key:270 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:85 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:98 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:114 -app/src/test/java/test/mega/privacy/android/app/presentation/testpassword/TestPasswordViewModelTest.kt:hashicorp-tf-password:132 -data/src/main/java/mega/privacy/android/data/mapper/security/PasscodeTypeStringMapper.kt:hashicorp-tf-password:20 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:32 -data/src/test/java/mega/privacy/android/data/mapper/login/EphemeralCredentialsMapperTest.kt:hashicorp-tf-password:41 -data/src/test/java/mega/privacy/android/data/mapper/psa/PsaMapperTest.kt:hashicorp-tf-password:23 -data/src/test/java/mega/privacy/android/data/repository/DefaultLoginRepositoryTest.kt:hashicorp-tf-password:68 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginWith2FAUseCaseTest.kt:hashicorp-tf-password:35 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/login/LoginUseCaseTest.kt:hashicorp-tf-password:36 -app/src/main/java/mega/privacy/android/app/MegaApplication.kt:generic-api-key:510 -data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1383 -data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1410 -data/src/test/java/mega/privacy/android/data/repository/DefaultAccountRepositoryTest.kt:hashicorp-tf-password:1437 -domain/src/test/kotlin/mega/privacy/android/domain/usecase/account/ConfirmCancelAccountUseCaseTest.kt:hashicorp-tf-password:38 \ No newline at end of file From 65f345bab61ba2325476fa1a4c5dbf0f18bba5c2 Mon Sep 17 00:00:00 2001 From: Javier Gomez Date: Wed, 6 Mar 2024 13:18:49 +0100 Subject: [PATCH 033/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 1be3b2b3d9..b4214ef139 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240306.102824" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 79f932e07d77e9db6eaa069c28f0079112cc18b1 Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Thu, 7 Mar 2024 09:42:45 +0700 Subject: [PATCH 034/261] CC-6537: Fix Image Preview's Save To Device Functionality --- .../presentation/imagepreview/ImagePreviewViewModel.kt | 10 +++++----- .../imagepreview/menu/FolderLinkImagePreviewMenu.kt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt index f6431259a9..69e58d1eb1 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt @@ -395,11 +395,11 @@ class ImagePreviewViewModel @Inject constructor( // chat nodes are not using this screen for now when { isFromFolderLink -> getPublicChildNodeFromIdUseCase(node.id) - imagePreviewMenuSource == ImagePreviewMenuSource.PUBLIC_FILE -> { - node.serializedData?.let { - getPublicNodeFromSerializedDataUseCase(it) - } - } + + imagePreviewMenuSource in listOf( + ImagePreviewMenuSource.ALBUM_SHARING, + ImagePreviewMenuSource.PUBLIC_FILE, + ) -> node.serializedData?.let { getPublicNodeFromSerializedDataUseCase(it) } else -> addImageTypeUseCase(node) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/menu/FolderLinkImagePreviewMenu.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/menu/FolderLinkImagePreviewMenu.kt index 09a52f45b1..7315d5452e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/menu/FolderLinkImagePreviewMenu.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/menu/FolderLinkImagePreviewMenu.kt @@ -36,7 +36,7 @@ internal class FolderLinkImagePreviewMenu @Inject constructor( } override suspend fun isForwardMenuVisible(imageNode: ImageNode): Boolean { - return checkFullAccessPermission(imageNode) + return false } override suspend fun isSaveToDeviceMenuVisible(imageNode: ImageNode): Boolean { From c24323054c3d6c31f2cf433628a609289235e2b6 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Thu, 7 Mar 2024 16:36:49 +1300 Subject: [PATCH 035/261] AP-1184 Improve Upgrade Screen's Subscription Details based on Google Play's Rejection --- .../upgradeAccount/UpgradeAccountFragment.kt | 13 +- .../upgradeAccount/view/UpgradeAccountView.kt | 152 +++++++++++++++--- app/src/main/res/values/strings.xml | 49 +++++- .../upgradeAccount/UpgradeAccountViewTest.kt | 111 ++++++++++--- 4 files changed, 269 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt index d78858b06d..e7bf713235 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt @@ -105,7 +105,6 @@ class UpgradeAccountFragment : Fragment() { startPurchase(uiState.isMonthlySelected, chosenPlan) } }, - onTOSClicked = this::redirectToTOSPage, onPlayStoreLinkClicked = this::redirectToPlayStoreSubscription, onPricingPageClicked = this::redirectToPricingPage, onChoosingMonthlyYearlyPlan = upgradeAccountViewModel::onSelectingMonthlyPlan, @@ -208,14 +207,6 @@ class UpgradeAccountFragment : Fragment() { } } - private fun redirectToTOSPage() { - startActivity( - Intent(requireContext(), WebViewActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - .setData(Uri.parse(Constants.TERMS_OF_SERVICE_URL)) - ) - } - private fun redirectToPlayStoreSubscription(link: String) { val uriUrl = Uri.parse(link) val launchBrowser = Intent(ACTION_VIEW, uriUrl) @@ -269,4 +260,8 @@ class UpgradeAccountFragment : Fragment() { upgradeAccountActivity.onBackPressedDispatcher.onBackPressed() } } + + companion object { + const val PRIVACY_POLICY_URL = "https://mega.nz/privacy" + } } \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt index 55e3da0616..04f0f5afc8 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt @@ -10,7 +10,6 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -55,12 +54,14 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextIndent +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.launch import mega.privacy.android.app.R +import mega.privacy.android.app.upgradeAccount.UpgradeAccountFragment.Companion.PRIVACY_POLICY_URL import mega.privacy.android.app.upgradeAccount.model.LocalisedSubscription import mega.privacy.android.app.upgradeAccount.model.UpgradeAccountState import mega.privacy.android.app.upgradeAccount.model.UpgradePayment @@ -74,6 +75,7 @@ import mega.privacy.android.app.upgradeAccount.view.components.ProPlanInfoCard import mega.privacy.android.app.upgradeAccount.view.components.SaveUpToLabel import mega.privacy.android.app.utils.Constants.INVALID_VALUE import mega.privacy.android.app.utils.Constants.PRICING_PAGE_URL +import mega.privacy.android.app.utils.Constants.TERMS_OF_SERVICE_URL import mega.privacy.android.app.utils.PLAY_STORE_SUBSCRIPTION_URL import mega.privacy.android.core.ui.controls.text.MegaSpannedClickableText import mega.privacy.android.core.ui.controls.text.MegaText @@ -84,6 +86,7 @@ import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.theme.Typography import mega.privacy.android.core.ui.theme.extensions.black_white import mega.privacy.android.core.ui.theme.extensions.black_yellow_700 +import mega.privacy.android.core.ui.theme.extensions.body2medium import mega.privacy.android.core.ui.theme.extensions.body4 import mega.privacy.android.core.ui.theme.extensions.grey_020_grey_800 import mega.privacy.android.core.ui.theme.extensions.grey_100_alpha_060_dark_grey @@ -97,9 +100,9 @@ import mega.privacy.android.domain.entity.Currency import mega.privacy.android.domain.entity.account.CurrencyAmount import mega.privacy.android.legacy.core.ui.controls.appbar.SimpleNoTitleTopAppBar import mega.privacy.android.shared.theme.MegaAppTheme +import java.util.Locale internal const val UPGRADE_ACCOUNT_SCREEN_TAG = "upgrade_account_screen:" -internal const val TOS_TAG = "upgrade_account_screen:link_terms_of_service" internal const val BILLING_WARNING_TAG = "upgrade_account_screen:box_warning_unavailable_payments" internal const val BILLING_WARNING_CLOSE_BUTTON_TAG = "upgrade_account_screen:button_close_billing_warning" @@ -125,7 +128,6 @@ fun UpgradeAccountView( state: UpgradeAccountState, onBackPressed: () -> Unit, onBuyClicked: () -> Unit, - onTOSClicked: () -> Unit, onPlayStoreLinkClicked: (String) -> Unit, onPricingPageClicked: (String) -> Unit, onChoosingMonthlyYearlyPlan: (isMonthly: Boolean) -> Unit, @@ -294,22 +296,14 @@ fun UpgradeAccountView( } FeaturesOfPlans(showNoAdsFeature = state.showNoAdsFeature) - SubscriptionDetails(onLinkClick = onPlayStoreLinkClicked) - - Text( - text = stringResource(id = R.string.account_upgrade_account_terms_of_service_link), - style = MaterialTheme.typography.button, - color = MaterialTheme.colors.teal_300_teal_200, - modifier = Modifier - .padding( - start = 24.dp, - top = 20.dp, - bottom = 12.dp - ) - .testTag(TOS_TAG) - .clickable { onTOSClicked() }, - fontWeight = FontWeight.Medium, - ) + if (state.localisedSubscriptionsList.isNotEmpty()) { + SubscriptionDetails( + onLinkClick = onPlayStoreLinkClicked, + chosenPlan = chosenPlan, + subscriptionList = state.localisedSubscriptionsList, + isMonthly = isMonthly, + ) + } } } } @@ -626,7 +620,103 @@ private fun FeaturesOfPlans( @Composable private fun SubscriptionDetails( onLinkClick: (link: String) -> Unit, + chosenPlan: AccountType, + subscriptionList: List, + isMonthly: Boolean, ) { + var subscriptionDetailsBodyString = + stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_without_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_without_price + } + ) + val subscription = subscriptionList.firstOrNull { it.accountType == chosenPlan } + val formattedPrice = subscription?.localisePriceCurrencyCode(Locale.getDefault(), isMonthly) + var testTag = if (isMonthly) "_monthly_no_price" else "_yearly_no_price" + when (chosenPlan) { + AccountType.PRO_LITE -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = if (isMonthly) "_monthly_lite_with_price" else "_yearly_lite_with_price" + } + } + + AccountType.PRO_I -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = if (isMonthly) "_monthly_pro_i_with_price" else "_yearly_pro_i_with_price" + } + } + + AccountType.PRO_II -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = + if (isMonthly) "_monthly_pro_ii_with_price" else "_yearly_pro_ii_with_price" + } + } + + AccountType.PRO_III -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = + if (isMonthly) "_monthly_pro_iii_with_price" else "_yearly_pro_iii_with_price" + } + } + + else -> { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_without_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_without_price + } + ) + testTag = if (isMonthly) "_monthly_no_price" else "_yearly_no_price" + } + } Column( modifier = Modifier .padding( @@ -639,25 +729,38 @@ private fun SubscriptionDetails( MegaText( modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_TITLE_TAG), text = stringResource(id = R.string.account_upgrade_account_description_subscription_title), - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.body2medium, textColor = TextColor.Primary, ) Spacer(modifier = Modifier.height(12.dp)) MegaSpannedClickableText( - modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG), - value = stringResource(id = R.string.account_upgrade_subscription_details), + modifier = Modifier.testTag("$SUBSCRIPTION_DETAILS_DESCRIPTION_TAG$testTag"), + value = subscriptionDetailsBodyString, styles = hashMapOf( SpanIndicator('A') to MegaSpanStyleWithAnnotation( MegaSpanStyle( SpanStyle(textDecoration = TextDecoration.None), color = TextColor.Accent, ), PLAY_STORE_SUBSCRIPTION_URL - ) + ), + SpanIndicator('B') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(textDecoration = TextDecoration.None), + color = TextColor.Accent, + ), TERMS_OF_SERVICE_URL + ), + SpanIndicator('C') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(textDecoration = TextDecoration.None), + color = TextColor.Accent, + ), PRIVACY_POLICY_URL + ), ), onAnnotationClick = onLinkClick, - baseStyle = MaterialTheme.typography.body4, + baseStyle = MaterialTheme.typography.body4.copy(lineHeight = 16.sp), color = TextColor.Primary ) + Spacer(modifier = Modifier.height(42.dp)) } } @@ -698,7 +801,6 @@ fun PreviewUpgradeAccountView( state = state, onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index da4b4893ad..a49bef2ea7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,7 +43,7 @@ Loading - Adding + Adding… Forwarding @@ -795,7 +795,7 @@ Grow your cloud.[A]Get increased storage and transfer quotas with a Pro account. - This email address is already in use. Please use another email address. + Email address already in use. Enter another email address. You have already requested a confirmation link for that email address. @@ -5232,7 +5232,7 @@ Call all - This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. + This app is logged into a different MEGA account. \nLog out of this account, and log in with your MEGA VPN account. MEGA needs access to your camera to capture photos and videos. @@ -5290,4 +5290,47 @@ Assign and leave Leave anyway + + Camera uploads updated + + Upload paused due to no internet connection + + Upload paused. Battery below %1$d%% and not charging. + + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + + + Camera uploads in progress, %1$d file pending + Camera uploads in progress, %1$d files pending + + + + Camera uploads complete, %1$d file uploaded + Camera uploads complete, %1$d files uploaded + + + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + + Hide + + Unhide + + Promo + + Limited time offer + + Change SFU Server + Default is -1 + Enter SFU ID + Change + + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s%2$s immediately and your subscription will automatically renew after 1 month for %3$s%4$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s%2$s immediately and your subscription will automatically renew after 12 months for %3$s%4$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. \ No newline at end of file diff --git a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt index 6aab0a3527..430ba15a51 100644 --- a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt @@ -137,7 +137,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -174,7 +173,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -210,7 +208,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -240,7 +237,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -270,7 +266,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -297,7 +292,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -328,7 +322,6 @@ class UpgradeAccountViewTest { ), onBuyClicked = onBuyClicked, onBackPressed = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -360,7 +353,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -389,7 +381,6 @@ class UpgradeAccountViewTest { hideBillingWarning = hideBillingWarning, onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -414,7 +405,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -440,7 +430,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -467,7 +456,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -494,7 +482,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -528,7 +515,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -602,7 +588,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, @@ -630,7 +615,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, @@ -647,7 +631,36 @@ class UpgradeAccountViewTest { } @Test - fun `test that subscription details is shown correctly`() { + fun `test that subscription details are shown correctly when pre-selected plan is Pro I`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.FREE, + showBillingWarning = false, + isPaymentMethodAvailable = true + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_yearly_pro_i_with_price") + .assertExists() + } + + @Test + fun `test that subscription details are shown correctly when current plan is Pro I and pre-selected plan is Pro II`() { composeRule.setContent { UpgradeAccountView( state = getUpgradeAccountState( @@ -657,7 +670,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -672,8 +684,69 @@ class UpgradeAccountViewTest { composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) .assertExists() composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() - composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_yearly_pro_ii_with_price") + .assertExists() + } + @Test + fun `test that subscription details are shown correctly when user selects monthly tab`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.FREE, + showBillingWarning = false, + isPaymentMethodAvailable = true + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag("$UPGRADE_ACCOUNT_SCREEN_TAG$MONTHLY_TAB_TAG").performClick() + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_monthly_pro_i_with_price") + .assertExists() + } + + @Test + fun `test that subscription details are shown correctly when current plan is monthly Pro III and no plan was preselected`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.PRO_III, + showBillingWarning = false, + isPaymentMethodAvailable = true, + userSubscription = UserSubscription.MONTHLY_SUBSCRIBED, + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag("$UPGRADE_ACCOUNT_SCREEN_TAG$MONTHLY_TAB_TAG").performClick() + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_monthly_no_price") + .assertExists() } private fun getUpgradeAccountState( From 57b7dcdf697e70cc010d2885885249c53e97f293 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Thu, 7 Mar 2024 14:02:42 +1300 Subject: [PATCH 036/261] AP-1184 Improve Upgrade Screen's Subscription Details based on Google Play's Rejection --- .../upgradeAccount/view/UpgradeAccountView.kt | 8 -------- app/src/main/res/values/strings.xml | 20 +++++++------------ 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt index 04f0f5afc8..c3a9968a45 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt @@ -644,9 +644,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = if (isMonthly) "_monthly_lite_with_price" else "_yearly_lite_with_price" @@ -661,9 +659,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = if (isMonthly) "_monthly_pro_i_with_price" else "_yearly_pro_i_with_price" @@ -678,9 +674,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = @@ -696,9 +690,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a49bef2ea7..75e6155444 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4473,18 +4473,12 @@ Couldn’t copy %1$d item Couldn’t copy %1$d items - + Copied %1$d item,  Copied %1$d items,  - + couldn’t copy %1$d item couldn’t copy %1$d items @@ -5297,7 +5291,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, please contact support. Camera uploads in progress, %1$d file pending @@ -5325,10 +5319,10 @@ Change Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] - - You will be charged %1$s%2$s immediately and your subscription will automatically renew after 1 month for %3$s%4$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. - - You will be charged %1$s%2$s immediately and your subscription will automatically renew after 12 months for %3$s%4$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. From 3665025116275faafb03d540d0b3cb939ba7f1f7 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Thu, 7 Mar 2024 16:41:30 +1300 Subject: [PATCH 037/261] upgrade version to 11.7.1 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2fde17e466..f2492ad3f2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "11.7" +extra["appVersion"] = "11.7.1" // Sdk and tools extra["compileSdkVersion"] = 34 From 3f371a1f10076b90e9e5e2135fee64a2db5c24b7 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Thu, 7 Mar 2024 10:12:51 +1300 Subject: [PATCH 038/261] AP-1184 Improve Upgrade Screen's Subscription Details based on Google Play's Rejection --- .../upgradeAccount/UpgradeAccountFragment.kt | 13 +- .../upgradeAccount/view/UpgradeAccountView.kt | 152 +++++++++++++++--- app/src/main/res/values/strings.xml | 8 + .../upgradeAccount/UpgradeAccountViewTest.kt | 111 ++++++++++--- 4 files changed, 231 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt index d78858b06d..e7bf713235 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/UpgradeAccountFragment.kt @@ -105,7 +105,6 @@ class UpgradeAccountFragment : Fragment() { startPurchase(uiState.isMonthlySelected, chosenPlan) } }, - onTOSClicked = this::redirectToTOSPage, onPlayStoreLinkClicked = this::redirectToPlayStoreSubscription, onPricingPageClicked = this::redirectToPricingPage, onChoosingMonthlyYearlyPlan = upgradeAccountViewModel::onSelectingMonthlyPlan, @@ -208,14 +207,6 @@ class UpgradeAccountFragment : Fragment() { } } - private fun redirectToTOSPage() { - startActivity( - Intent(requireContext(), WebViewActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - .setData(Uri.parse(Constants.TERMS_OF_SERVICE_URL)) - ) - } - private fun redirectToPlayStoreSubscription(link: String) { val uriUrl = Uri.parse(link) val launchBrowser = Intent(ACTION_VIEW, uriUrl) @@ -269,4 +260,8 @@ class UpgradeAccountFragment : Fragment() { upgradeAccountActivity.onBackPressedDispatcher.onBackPressed() } } + + companion object { + const val PRIVACY_POLICY_URL = "https://mega.nz/privacy" + } } \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt index 55e3da0616..04f0f5afc8 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt @@ -10,7 +10,6 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -55,12 +54,14 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextIndent +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.launch import mega.privacy.android.app.R +import mega.privacy.android.app.upgradeAccount.UpgradeAccountFragment.Companion.PRIVACY_POLICY_URL import mega.privacy.android.app.upgradeAccount.model.LocalisedSubscription import mega.privacy.android.app.upgradeAccount.model.UpgradeAccountState import mega.privacy.android.app.upgradeAccount.model.UpgradePayment @@ -74,6 +75,7 @@ import mega.privacy.android.app.upgradeAccount.view.components.ProPlanInfoCard import mega.privacy.android.app.upgradeAccount.view.components.SaveUpToLabel import mega.privacy.android.app.utils.Constants.INVALID_VALUE import mega.privacy.android.app.utils.Constants.PRICING_PAGE_URL +import mega.privacy.android.app.utils.Constants.TERMS_OF_SERVICE_URL import mega.privacy.android.app.utils.PLAY_STORE_SUBSCRIPTION_URL import mega.privacy.android.core.ui.controls.text.MegaSpannedClickableText import mega.privacy.android.core.ui.controls.text.MegaText @@ -84,6 +86,7 @@ import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.theme.Typography import mega.privacy.android.core.ui.theme.extensions.black_white import mega.privacy.android.core.ui.theme.extensions.black_yellow_700 +import mega.privacy.android.core.ui.theme.extensions.body2medium import mega.privacy.android.core.ui.theme.extensions.body4 import mega.privacy.android.core.ui.theme.extensions.grey_020_grey_800 import mega.privacy.android.core.ui.theme.extensions.grey_100_alpha_060_dark_grey @@ -97,9 +100,9 @@ import mega.privacy.android.domain.entity.Currency import mega.privacy.android.domain.entity.account.CurrencyAmount import mega.privacy.android.legacy.core.ui.controls.appbar.SimpleNoTitleTopAppBar import mega.privacy.android.shared.theme.MegaAppTheme +import java.util.Locale internal const val UPGRADE_ACCOUNT_SCREEN_TAG = "upgrade_account_screen:" -internal const val TOS_TAG = "upgrade_account_screen:link_terms_of_service" internal const val BILLING_WARNING_TAG = "upgrade_account_screen:box_warning_unavailable_payments" internal const val BILLING_WARNING_CLOSE_BUTTON_TAG = "upgrade_account_screen:button_close_billing_warning" @@ -125,7 +128,6 @@ fun UpgradeAccountView( state: UpgradeAccountState, onBackPressed: () -> Unit, onBuyClicked: () -> Unit, - onTOSClicked: () -> Unit, onPlayStoreLinkClicked: (String) -> Unit, onPricingPageClicked: (String) -> Unit, onChoosingMonthlyYearlyPlan: (isMonthly: Boolean) -> Unit, @@ -294,22 +296,14 @@ fun UpgradeAccountView( } FeaturesOfPlans(showNoAdsFeature = state.showNoAdsFeature) - SubscriptionDetails(onLinkClick = onPlayStoreLinkClicked) - - Text( - text = stringResource(id = R.string.account_upgrade_account_terms_of_service_link), - style = MaterialTheme.typography.button, - color = MaterialTheme.colors.teal_300_teal_200, - modifier = Modifier - .padding( - start = 24.dp, - top = 20.dp, - bottom = 12.dp - ) - .testTag(TOS_TAG) - .clickable { onTOSClicked() }, - fontWeight = FontWeight.Medium, - ) + if (state.localisedSubscriptionsList.isNotEmpty()) { + SubscriptionDetails( + onLinkClick = onPlayStoreLinkClicked, + chosenPlan = chosenPlan, + subscriptionList = state.localisedSubscriptionsList, + isMonthly = isMonthly, + ) + } } } } @@ -626,7 +620,103 @@ private fun FeaturesOfPlans( @Composable private fun SubscriptionDetails( onLinkClick: (link: String) -> Unit, + chosenPlan: AccountType, + subscriptionList: List, + isMonthly: Boolean, ) { + var subscriptionDetailsBodyString = + stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_without_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_without_price + } + ) + val subscription = subscriptionList.firstOrNull { it.accountType == chosenPlan } + val formattedPrice = subscription?.localisePriceCurrencyCode(Locale.getDefault(), isMonthly) + var testTag = if (isMonthly) "_monthly_no_price" else "_yearly_no_price" + when (chosenPlan) { + AccountType.PRO_LITE -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = if (isMonthly) "_monthly_lite_with_price" else "_yearly_lite_with_price" + } + } + + AccountType.PRO_I -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = if (isMonthly) "_monthly_pro_i_with_price" else "_yearly_pro_i_with_price" + } + } + + AccountType.PRO_II -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = + if (isMonthly) "_monthly_pro_ii_with_price" else "_yearly_pro_ii_with_price" + } + } + + AccountType.PRO_III -> { + if (formattedPrice != null) { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_with_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_with_price + }, + formattedPrice.currencyCode, + formattedPrice.price, + formattedPrice.currencyCode, + formattedPrice.price + ) + testTag = + if (isMonthly) "_monthly_pro_iii_with_price" else "_yearly_pro_iii_with_price" + } + } + + else -> { + subscriptionDetailsBodyString = stringResource( + id = if (isMonthly) { + R.string.account_upgrade_account_subscription_details_body_monthly_without_price + } else { + R.string.account_upgrade_account_subscription_details_body_yearly_without_price + } + ) + testTag = if (isMonthly) "_monthly_no_price" else "_yearly_no_price" + } + } Column( modifier = Modifier .padding( @@ -639,25 +729,38 @@ private fun SubscriptionDetails( MegaText( modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_TITLE_TAG), text = stringResource(id = R.string.account_upgrade_account_description_subscription_title), - style = MaterialTheme.typography.body2, + style = MaterialTheme.typography.body2medium, textColor = TextColor.Primary, ) Spacer(modifier = Modifier.height(12.dp)) MegaSpannedClickableText( - modifier = Modifier.testTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG), - value = stringResource(id = R.string.account_upgrade_subscription_details), + modifier = Modifier.testTag("$SUBSCRIPTION_DETAILS_DESCRIPTION_TAG$testTag"), + value = subscriptionDetailsBodyString, styles = hashMapOf( SpanIndicator('A') to MegaSpanStyleWithAnnotation( MegaSpanStyle( SpanStyle(textDecoration = TextDecoration.None), color = TextColor.Accent, ), PLAY_STORE_SUBSCRIPTION_URL - ) + ), + SpanIndicator('B') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(textDecoration = TextDecoration.None), + color = TextColor.Accent, + ), TERMS_OF_SERVICE_URL + ), + SpanIndicator('C') to MegaSpanStyleWithAnnotation( + MegaSpanStyle( + SpanStyle(textDecoration = TextDecoration.None), + color = TextColor.Accent, + ), PRIVACY_POLICY_URL + ), ), onAnnotationClick = onLinkClick, - baseStyle = MaterialTheme.typography.body4, + baseStyle = MaterialTheme.typography.body4.copy(lineHeight = 16.sp), color = TextColor.Primary ) + Spacer(modifier = Modifier.height(42.dp)) } } @@ -698,7 +801,6 @@ fun PreviewUpgradeAccountView( state = state, onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f64ce90515..a49bef2ea7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5325,4 +5325,12 @@ Change Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s%2$s immediately and your subscription will automatically renew after 1 month for %3$s%4$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s%2$s immediately and your subscription will automatically renew after 12 months for %3$s%4$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. \ No newline at end of file diff --git a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt index 6aab0a3527..430ba15a51 100644 --- a/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/upgradeAccount/UpgradeAccountViewTest.kt @@ -137,7 +137,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -174,7 +173,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -210,7 +208,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -240,7 +237,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -270,7 +266,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -297,7 +292,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -328,7 +322,6 @@ class UpgradeAccountViewTest { ), onBuyClicked = onBuyClicked, onBackPressed = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -360,7 +353,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -389,7 +381,6 @@ class UpgradeAccountViewTest { hideBillingWarning = hideBillingWarning, onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -414,7 +405,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -440,7 +430,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -467,7 +456,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -494,7 +482,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -528,7 +515,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -602,7 +588,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, @@ -630,7 +615,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingPlanType = {}, @@ -647,7 +631,36 @@ class UpgradeAccountViewTest { } @Test - fun `test that subscription details is shown correctly`() { + fun `test that subscription details are shown correctly when pre-selected plan is Pro I`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.FREE, + showBillingWarning = false, + isPaymentMethodAvailable = true + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_yearly_pro_i_with_price") + .assertExists() + } + + @Test + fun `test that subscription details are shown correctly when current plan is Pro I and pre-selected plan is Pro II`() { composeRule.setContent { UpgradeAccountView( state = getUpgradeAccountState( @@ -657,7 +670,6 @@ class UpgradeAccountViewTest { ), onBackPressed = {}, onBuyClicked = {}, - onTOSClicked = {}, onPlayStoreLinkClicked = {}, onPricingPageClicked = {}, onChoosingMonthlyYearlyPlan = {}, @@ -672,8 +684,69 @@ class UpgradeAccountViewTest { composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) .assertExists() composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() - composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_DESCRIPTION_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_yearly_pro_ii_with_price") + .assertExists() + } + @Test + fun `test that subscription details are shown correctly when user selects monthly tab`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.FREE, + showBillingWarning = false, + isPaymentMethodAvailable = true + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag("$UPGRADE_ACCOUNT_SCREEN_TAG$MONTHLY_TAB_TAG").performClick() + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_monthly_pro_i_with_price") + .assertExists() + } + + @Test + fun `test that subscription details are shown correctly when current plan is monthly Pro III and no plan was preselected`() { + composeRule.setContent { + UpgradeAccountView( + state = getUpgradeAccountState( + accountType = AccountType.PRO_III, + showBillingWarning = false, + isPaymentMethodAvailable = true, + userSubscription = UserSubscription.MONTHLY_SUBSCRIBED, + ), + onBackPressed = {}, + onBuyClicked = {}, + onPlayStoreLinkClicked = {}, + onPricingPageClicked = {}, + onChoosingMonthlyYearlyPlan = {}, + onChoosingPlanType = {}, + showBillingWarning = {}, + hideBillingWarning = {}, + onDialogConfirmButtonClicked = {}, + onDialogDismissButtonClicked = {}, + showUpgradeWarningBanner = false + ) + } + composeRule.onNodeWithTag("$UPGRADE_ACCOUNT_SCREEN_TAG$MONTHLY_TAB_TAG").performClick() + composeRule.onNodeWithTag(GOOGLE_PLAY_STORE_SUBSCRIPTION_LINK_TAG) + .assertExists() + composeRule.onNodeWithTag(SUBSCRIPTION_DETAILS_TITLE_TAG).assertExists() + composeRule.onNodeWithTag("${SUBSCRIPTION_DETAILS_DESCRIPTION_TAG}_monthly_no_price") + .assertExists() } private fun getUpgradeAccountState( From b92ec91c25ad96fc02eeb24e4467be48ab565ff6 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Thu, 7 Mar 2024 14:02:42 +1300 Subject: [PATCH 039/261] AP-1184 Improve Upgrade Screen's Subscription Details based on Google Play's Rejection --- .../upgradeAccount/view/UpgradeAccountView.kt | 8 -------- app/src/main/res/values/strings.xml | 20 +++++++------------ 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt index 04f0f5afc8..c3a9968a45 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/UpgradeAccountView.kt @@ -644,9 +644,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = if (isMonthly) "_monthly_lite_with_price" else "_yearly_lite_with_price" @@ -661,9 +659,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = if (isMonthly) "_monthly_pro_i_with_price" else "_yearly_pro_i_with_price" @@ -678,9 +674,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = @@ -696,9 +690,7 @@ private fun SubscriptionDetails( } else { R.string.account_upgrade_account_subscription_details_body_yearly_with_price }, - formattedPrice.currencyCode, formattedPrice.price, - formattedPrice.currencyCode, formattedPrice.price ) testTag = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a49bef2ea7..75e6155444 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4473,18 +4473,12 @@ Couldn’t copy %1$d item Couldn’t copy %1$d items - + Copied %1$d item,  Copied %1$d items,  - + couldn’t copy %1$d item couldn’t copy %1$d items @@ -5297,7 +5291,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, please contact support. Camera uploads in progress, %1$d file pending @@ -5325,10 +5319,10 @@ Change Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] - - You will be charged %1$s%2$s immediately and your subscription will automatically renew after 1 month for %3$s%4$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. - - You will be charged %1$s%2$s immediately and your subscription will automatically renew after 12 months for %3$s%4$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s / month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. From c14a2b29a8f8208e247af4c76431eaaaf21d81f8 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 7 Mar 2024 09:38:11 +0100 Subject: [PATCH 040/261] TRAN-321: Text files are not downloaded --- .../android/app/textEditor/TextEditorViewModel.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/textEditor/TextEditorViewModel.kt b/app/src/main/java/mega/privacy/android/app/textEditor/TextEditorViewModel.kt index 5f8ef6b22a..3a76ba4464 100644 --- a/app/src/main/java/mega/privacy/android/app/textEditor/TextEditorViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/textEditor/TextEditorViewModel.kt @@ -906,6 +906,16 @@ class TextEditorViewModel @Inject constructor( TransferTriggerEvent.StartDownloadNode(nodes) ) } + + else -> { + val node = getNode()?.handle?.let { + getNodeByIdUseCase(NodeId(it)) + } + val nodes = listOfNotNull(node) + updateDownloadEvent( + TransferTriggerEvent.StartDownloadNode(nodes) + ) + } } } else { when (getAdapterType()) { From 8171611d661f4ead7e44b45f929fde5f10e561a9 Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Fri, 8 Mar 2024 02:55:53 +1300 Subject: [PATCH 041/261] T15262271, T15262237, T15262357 Create a meeting by adding the meeting name --- .../app/meeting/fragments/CreateMeetingFragment.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/fragments/CreateMeetingFragment.kt b/app/src/main/java/mega/privacy/android/app/meeting/fragments/CreateMeetingFragment.kt index 18a9099ba9..ecf1fc6369 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/fragments/CreateMeetingFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/fragments/CreateMeetingFragment.kt @@ -50,10 +50,16 @@ class CreateMeetingFragment : AbstractMeetingOnBoardingFragment() { Timber.d("Meeting Name: $meetingName") releaseVideoAndHideKeyboard() + sharedModel.updateGuestFullNameAndMeetingLink( + guestFisrtName, + guestLastName, + meetingLink, + meetingName + ) + val action = InMeetingFragmentDirections.actionGlobalInMeeting( action = MEETING_ACTION_CREATE, - meetingName = meetingName ) findNavController().navigate(action) } From a38dd4b35a3c31b3fb216546205fefaea588a3c0 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Fri, 8 Mar 2024 04:32:40 +1300 Subject: [PATCH 042/261] Hotfix: T15262154, T15262155 Download already downloaded --- .../StartDownloadComponentViewModel.kt | 8 ++- .../model/StartDownloadTransferEvent.kt | 13 +++- .../view/StartDownloadComponent.kt | 60 ++++++++++++++++--- .../StartDownloadComponentViewModelTest.kt | 10 ++-- .../entity/transfer/ActiveTransferTotals.kt | 5 ++ .../entity/transfer/MultiTransferEvent.kt | 24 +++++++- .../shared/AbstractTransferNodesUseCase.kt | 17 +++++- .../message/SendChatAttachmentsUseCaseTest.kt | 2 +- .../StartChatUploadsWithWorkerUseCaseTest.kt | 4 +- .../downloads/DownloadNodesUseCaseTest.kt | 2 +- .../StartDownloadsWithWorkerUseCaseTest.kt | 16 ++--- 11 files changed, 128 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt index b106b813cb..8f90a9134c 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt @@ -288,14 +288,18 @@ internal class StartDownloadComponentViewModel @Inject constructor( } monitorFinish() checkRating() - if (terminalEvent == MultiTransferEvent.ScanningFoldersFinished) toDoAfterProcessing?.invoke() + if (terminalEvent is MultiTransferEvent.ScanningFoldersFinished) toDoAfterProcessing?.invoke() _uiState.updateEventAndClearProgress( when (terminalEvent) { MultiTransferEvent.InsufficientSpace -> StartDownloadTransferEvent.Message.NotSufficientSpace else -> { + val finishedEvent = + (terminalEvent as? MultiTransferEvent.ScanningFoldersFinished) StartDownloadTransferEvent.FinishProcessing( exception = lastError?.takeIf { terminalEvent == null }, totalNodes = nodes.size, + totalFiles = finishedEvent?.scannedFiles ?: 0, + totalAlreadyDownloaded = finishedEvent?.alreadyDownloadedFiles ?: 0, ) } } @@ -422,7 +426,7 @@ internal class StartDownloadComponentViewModel @Inject constructor( .takeWhile { it.totalTransfers > 0 }.lastOrNull() ?: return@launch - (lastBeforeClear.totalFileTransfers - lastBeforeClear.totalFinishedWithErrorsFileTransfers).takeIf { it > 0 } + (lastBeforeClear.totalFilesDownloaded).takeIf { it > 0 } ?.let { when (_uiState.value.transferTriggerEvent) { is TransferTriggerEvent.StartDownloadForOffline -> { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/model/StartDownloadTransferEvent.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/model/StartDownloadTransferEvent.kt index 8fcd7e8d57..22ed89ad3b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/model/StartDownloadTransferEvent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/model/StartDownloadTransferEvent.kt @@ -13,9 +13,18 @@ sealed interface StartDownloadTransferEvent { * Transfers scanning has finished * @param exception [Throwable] in case of not correctly finished * @param totalNodes + * @param totalFiles total files on this nodes + * @param totalAlreadyDownloaded total files already downloaded, so they won't be downloaded + * @property filesToDownload */ - data class FinishProcessing(val exception: Throwable?, val totalNodes: Int) : - StartDownloadTransferEvent + data class FinishProcessing( + val exception: Throwable?, + val totalNodes: Int, + val totalFiles: Int, + val totalAlreadyDownloaded: Int, + ) : StartDownloadTransferEvent { + val filesToDownload = totalFiles - totalAlreadyDownloaded + } /** * we can't do work because there's no Internet connection diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt index 86ed2f52fd..f9a9324f95 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt @@ -49,6 +49,8 @@ import mega.privacy.android.app.presentation.transfers.startdownload.model.Start import mega.privacy.android.app.presentation.transfers.startdownload.model.TransferTriggerEvent import mega.privacy.android.app.presentation.transfers.view.TransferInProgressDialog import mega.privacy.android.app.upgradeAccount.UpgradeAccountActivity +import mega.privacy.android.app.usecase.exception.NotEnoughQuotaMegaException +import mega.privacy.android.app.usecase.exception.QuotaExceededMegaException import mega.privacy.android.app.utils.AlertsAndWarnings import mega.privacy.android.app.utils.Util import mega.privacy.android.core.ui.controls.dialogs.ConfirmationDialog @@ -57,8 +59,6 @@ import mega.privacy.android.core.ui.controls.dialogs.MegaAlertDialog import mega.privacy.android.core.ui.navigation.launchFolderPicker import mega.privacy.android.core.ui.utils.MinimumTimeVisibility import mega.privacy.android.domain.entity.StorageState -import mega.privacy.android.domain.exception.NotEnoughQuotaMegaException -import mega.privacy.android.domain.exception.QuotaExceededMegaException import mega.privacy.android.shared.theme.MegaAppTheme import timber.log.Timber @@ -331,16 +331,58 @@ private suspend fun consumeFinishProcessing( ) { when (event.exception) { null -> { - val message = when (transferTriggerEvent) { - is TransferTriggerEvent.StartDownloadForPreview -> { + val message = when { + transferTriggerEvent is TransferTriggerEvent.StartDownloadForPreview -> { context.resources.getString(R.string.cloud_drive_snackbar_preparing_file_for_preview_context) } - else -> context.resources.getQuantityString( - R.plurals.download_started, - event.totalNodes, - event.totalNodes, - ) + event.totalAlreadyDownloaded == 0 -> { + context.resources.getQuantityString( + R.plurals.download_started, + event.totalNodes, + event.totalNodes, + ) + } + + event.filesToDownload == 0 -> { + context.resources.getQuantityString( + R.plurals.already_downloaded_service, + event.totalFiles, + event.totalFiles, + ) + } + + event.totalAlreadyDownloaded == 1 -> { + context.resources.getQuantityString( + R.plurals.file_already_downloaded_and_files_pending_download, + event.filesToDownload, + event.filesToDownload + ) + } + + event.filesToDownload == 1 -> { + context.resources.getQuantityString( + R.plurals.files_already_downloaded_and_file_pending_download, + event.totalAlreadyDownloaded, + event.totalAlreadyDownloaded + ) + } + + else -> { + StringBuilder().append( + context.resources.getQuantityString( + R.plurals.file_already_downloaded, + event.totalAlreadyDownloaded, + event.totalAlreadyDownloaded + ) + ).append(" ").append( + context.resources.getQuantityString( + R.plurals.file_pending_download, + event.filesToDownload, + event.filesToDownload + ) + ).toString() + } } snackBarHostState.showSnackbar(message) } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt index 6b14191167..a4e856fe8b 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt @@ -230,7 +230,7 @@ class StartDownloadComponentViewModelTest { commonStub() stubStartDownload(flow { delay(500) - emit(MultiTransferEvent.ScanningFoldersFinished) + emit(mock()) }) underTest.startDownload(TransferTriggerEvent.StartDownloadNode(nodes)) Truth.assertThat(underTest.uiState.value.jobInProgressState) @@ -242,7 +242,7 @@ class StartDownloadComponentViewModelTest { runTest { commonStub() underTest.startDownload(TransferTriggerEvent.StartDownloadNode(nodes)) - assertCurrentEventIsEqualTo(StartDownloadTransferEvent.FinishProcessing(null, 1)) + assertCurrentEventIsEqualTo(StartDownloadTransferEvent.FinishProcessing(null, 1, 0, 0)) } @Test @@ -380,8 +380,8 @@ class StartDownloadComponentViewModelTest { private fun provideDownloadNodeParameters() = listOf( Arguments.of( - MultiTransferEvent.ScanningFoldersFinished, - StartDownloadTransferEvent.FinishProcessing(null, 1), + mock(), + StartDownloadTransferEvent.FinishProcessing(null, 1, 0, 0), ), Arguments.of( MultiTransferEvent.InsufficientSpace, @@ -413,7 +413,7 @@ class StartDownloadComponentViewModelTest { whenever(isConnectedToInternetUseCase()).thenReturn(true) whenever(totalFileSizeOfNodesUseCase(any())).thenReturn(1) whenever(shouldAskDownloadDestinationUseCase()).thenReturn(false) - stubStartDownload(flowOf(MultiTransferEvent.ScanningFoldersFinished)) + stubStartDownload(flowOf(mock())) } private fun stubStartDownload(flow: Flow) { diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/ActiveTransferTotals.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/ActiveTransferTotals.kt index 13f3576f97..3897fd021a 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/ActiveTransferTotals.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/ActiveTransferTotals.kt @@ -60,4 +60,9 @@ data class ActiveTransferTotals( */ val totalFinishedWithErrorsFileTransfers = totalFinishedFileTransfers - totalCompletedFileTransfers - totalAlreadyDownloadedFiles + + /** + * The total number of files that has been fully downloaded + */ + val totalFilesDownloaded = totalCompletedFileTransfers - totalAlreadyDownloadedFiles } \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt index 2ed22e062a..091b7fee05 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt @@ -39,13 +39,28 @@ sealed interface MultiTransferEvent { true } - this is TransferEvent.TransferFinishEvent && transfer.isFolderTransfer -> true - this is TransferEvent.TransferStartEvent && !transfer.isFolderTransfer -> true + this is TransferEvent.TransferFinishEvent -> true + this is TransferEvent.TransferUpdateEvent && !transfer.isFolderTransfer -> true else -> false } } } + /** + * This event indicates that the transfer was not done due to being already transferred. + */ + val isAlreadyTransferredEvent by lazy { + with(transferEvent.transfer) { + !isFolderTransfer && isAlreadyDownloaded + } + } + + /** + * This event is related to a file transfer, not a folder. + */ + val isFileTransferEvent by lazy { !transferEvent.transfer.isFolderTransfer } + + /** * Current overall progress of all the initiated transfers. May be inaccurate since some nodes may not have been processed yet, and therefore, totalBytesToTransfer could be inaccurate. */ @@ -54,8 +69,11 @@ sealed interface MultiTransferEvent { /** * All transfers has been scanned by the sdk, starting from this event transfers can be retried by sdk if the app is closed + * @property scannedFiles the amount of files scanned for the transfer of the involved nodes + * @property alreadyDownloadedFiles the amount of already downloaded files */ - data object ScanningFoldersFinished : MultiTransferEvent + data class ScanningFoldersFinished(val scannedFiles: Int, val alreadyDownloadedFiles: Int) : + MultiTransferEvent /** * Event to notify that the download cannot be done due to insufficient storage space in the destination path diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt index da1b26a118..adfb98d083 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt @@ -46,6 +46,8 @@ abstract class AbstractTransferNodesUseCase( doTransfer: (T) -> Flow, ): Flow { val alreadyScanned = mutableSetOf() + val scannedFiles = mutableSetOf() + val alreadyDownloadedFiles = mutableSetOf() val allIds = items.map(::generateIdFromItem) var scanningFinishedSend = false return channelFlow { @@ -91,6 +93,14 @@ abstract class AbstractTransferNodesUseCase( //update active transfers db addOrUpdateActiveTransferUseCase(event.transferEvent) + //keep track of files counters + if (event.isFileTransferEvent) { + val id = generateIdFromTransferEvent(event.transferEvent) + scannedFiles.add(id) + if (event.isAlreadyTransferredEvent) { + alreadyDownloadedFiles.add(id) + } + } //check if is a single node scanning finish event if (event.isFinishScanningEvent) { val id = generateIdFromTransferEvent(event.transferEvent) @@ -102,7 +112,12 @@ abstract class AbstractTransferNodesUseCase( if (!scanningFinishedSend && alreadyScanned.containsAll(allIds)) { scanningFinishedSend = true invalidateCancelTokenUseCase() //we need to avoid a future cancellation from now on - emit(MultiTransferEvent.ScanningFoldersFinished) + emit( + MultiTransferEvent.ScanningFoldersFinished( + scannedFiles.size, + alreadyDownloadedFiles.size + ) + ) } } } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt index 2dccdb4929..5a6d31d8b9 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt @@ -114,7 +114,7 @@ class SendChatAttachmentsUseCaseTest { whenever(chatMessageRepository.savePendingMessage(any())) .thenReturn(pendingMessage) whenever(startChatUploadsWithWorkerUseCase(any(), any())).thenReturn( - flowOf(MultiTransferEvent.ScanningFoldersFinished) + flowOf(mock()) ) whenever(getFileForChatUploadUseCase(any())).thenReturn(file) } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt index 4d16ab92e1..f5617138fa 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt @@ -138,7 +138,7 @@ class StartChatUploadsWithWorkerUseCaseTest { fun `test that download worker is started when start download finish correctly`() = runTest { mockFlow( flowOf( - MultiTransferEvent.ScanningFoldersFinished, + mock(), ) ) underTest(listOf(mock()), 1L).collect() @@ -150,7 +150,7 @@ class StartChatUploadsWithWorkerUseCaseTest { var workerStarted = false mockFlow( flow { - emit(MultiTransferEvent.ScanningFoldersFinished) + emit(mock()) awaitCancellation() } ) diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt index d458c87c67..1787c2b0c8 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt @@ -528,7 +528,7 @@ class DownloadNodesUseCaseTest { on { nodeHandle }.thenReturn(handle) }) } else { - TransferEvent.TransferStartEvent(mock { + TransferEvent.TransferUpdateEvent(mock { on { isFolderTransfer }.thenReturn(false) on { nodeHandle }.thenReturn(handle) }) diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt index 712caac291..3c5d3a23a3 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt @@ -106,28 +106,30 @@ class StartDownloadsWithWorkerUseCaseTest { @Test fun `test that single events are filtered out`() = runTest { + val mockFinish = mock() mockFlow( flowOf( mock(), - MultiTransferEvent.ScanningFoldersFinished, + mockFinish, ) ) underTest(mockNodes(), DESTINATION_PATH_FOLDER, false).test { - assertThat(awaitItem()).isEqualTo(MultiTransferEvent.ScanningFoldersFinished) + assertThat(awaitItem()).isEqualTo(mockFinish) awaitComplete() } } @Test fun `test that flow completes when finish processing transfers is emitted`() = runTest { + val mockFinish = mock() mockFlow( flowOf( - MultiTransferEvent.ScanningFoldersFinished, + mockFinish, mock(), ) ) underTest(mockNodes(), DESTINATION_PATH_FOLDER, false).test { - assertThat(awaitItem()).isEqualTo(MultiTransferEvent.ScanningFoldersFinished) + assertThat(awaitItem()).isEqualTo(mockFinish) awaitComplete() } } @@ -136,7 +138,7 @@ class StartDownloadsWithWorkerUseCaseTest { fun `test that download worker is started when start download finish correctly`() = runTest { mockFlow( flowOf( - MultiTransferEvent.ScanningFoldersFinished, + mock(), ) ) underTest(mockNodes(), DESTINATION_PATH_FOLDER, false).collect() @@ -148,7 +150,7 @@ class StartDownloadsWithWorkerUseCaseTest { var workerStarted = false mockFlow( flow { - emit(MultiTransferEvent.ScanningFoldersFinished) + emit(mock()) awaitCancellation() } ) @@ -171,7 +173,7 @@ class StartDownloadsWithWorkerUseCaseTest { mockFlow( flow { delay(1000) - emit(MultiTransferEvent.ScanningFoldersFinished) + emit(mock()) } ) val job = From 6338e3530abc091fc9eb5d7edb76dc582b606a05 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 7 Mar 2024 16:57:00 +0100 Subject: [PATCH 043/261] Hotfix: T15262172, T15262173, 15262175 Download complete message in Transfer Screen --- .../transfers/page/TransferPageFragment.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/page/TransferPageFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/page/TransferPageFragment.kt index b3e7551232..f4cfea7e7b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/page/TransferPageFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/page/TransferPageFragment.kt @@ -20,6 +20,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.addTo import io.reactivex.rxjava3.schedulers.Schedulers +import kotlinx.coroutines.flow.emptyFlow import mega.privacy.android.app.BaseActivity import mega.privacy.android.app.R import mega.privacy.android.app.arch.extensions.collectFlow @@ -32,6 +33,7 @@ import mega.privacy.android.app.main.managerSections.TransfersFragment import mega.privacy.android.app.main.managerSections.TransfersViewModel import mega.privacy.android.app.presentation.manager.model.TransfersTab import mega.privacy.android.app.presentation.transfers.TransfersManagementViewModel +import mega.privacy.android.app.presentation.transfers.startdownload.view.createStartDownloadView import mega.privacy.android.app.usecase.DownloadNodeUseCase import mega.privacy.android.app.usecase.UploadUseCase import mega.privacy.android.app.utils.Constants @@ -103,10 +105,20 @@ internal class TransferPageFragment : Fragment() { savedInstanceState: Bundle?, ): View { return FragmentTransferPageBinding.inflate(inflater, container, false).also { + addStartDownloadTransferView(it.root) _binding = it }.root } + private fun addStartDownloadTransferView(root: ViewGroup) { + root.addView( + createStartDownloadView( + requireActivity(), + emptyFlow(), //This view is just to show messages, as transfers can not be started in this screen, that's why it has no events + ) {} + ) + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setUpPager() From d3dc7b25be5aa9d2eaffad974e84b148e921a4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20G=C3=B3mez=20Mart=C3=ADn?= Date: Mon, 11 Mar 2024 22:12:42 +1300 Subject: [PATCH 044/261] Pre-Release v11.8 --- app/src/main/res/values-ar/strings.xml | 36 ++++++++++++--- app/src/main/res/values-de/strings.xml | 44 ++++++++++++++----- app/src/main/res/values-es/strings.xml | 38 ++++++++++++---- app/src/main/res/values-fr/strings.xml | 42 +++++++++++++----- app/src/main/res/values-in/strings.xml | 36 ++++++++++++--- app/src/main/res/values-it/strings.xml | 40 +++++++++++++---- app/src/main/res/values-ja/strings.xml | 36 ++++++++++++--- app/src/main/res/values-ko/strings.xml | 34 +++++++++++--- app/src/main/res/values-nl/strings.xml | 40 +++++++++++++---- app/src/main/res/values-pl/strings.xml | 42 +++++++++++++----- app/src/main/res/values-pt/strings.xml | 38 ++++++++++++---- app/src/main/res/values-ro/strings.xml | 40 +++++++++++++---- app/src/main/res/values-ru/strings.xml | 42 +++++++++++++----- app/src/main/res/values-th/strings.xml | 36 ++++++++++++--- app/src/main/res/values-vi/strings.xml | 36 ++++++++++++--- app/src/main/res/values-zh-rCN/strings.xml | 40 +++++++++++++---- app/src/main/res/values-zh-rTW/strings.xml | 40 +++++++++++++---- app/src/main/res/values/strings.xml | 42 ++++++++++++++---- .../res/values-de/strings_sync_feature.xml | 8 ++-- .../values-zh-rCN/strings_sync_feature.xml | 8 ++-- 20 files changed, 558 insertions(+), 160 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 81f0b6173e..c1ad89c335 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -817,7 +817,7 @@ ركن - هذه هي الخطوة الأخيرة لركن حسابك، يرجى إدخال كلمة المرور الجديدة. سيتم الاحتفاظ ببياناتك لمدة 60 يوماً على الأقل. إذا كنت تتذكر كلمة مرور حسابك المركون، يرجى التواصل معنا عبر البريد الالكتروني support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz أدخل كلمة مرور جديدة @@ -2025,7 +2025,7 @@ في المرة القادمة التي تسجل فيها الدخول الى حسابك سيطلب منك إدخال رمز من 6 أرقام ستزود به من تطبيق المصادقة الخاص بك. - يرجى حفظ مفتاح الاستعادة الخاص بك في مكان آمن لتجنب المشاكل في حالة فقد الوصول إلى التطبيق الخاص بك أو إذا كنت ترغب في تعطيل المصادقة المزدوجة. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. الرمز غير صالح @@ -6211,10 +6211,13 @@ السماح بالوصول إلى معرض الصور الخاص بك منح اذن الوصول - + التحديث مطلوب + انت لا تستخدم أحدث إصدار من تطبيقنا لذا لا يمكنك بدء المكالمات أو الانضمام إليها. قم بالتحديث الآن للمتابعة. + تحديث + رفض تعيين مضيف لمغادرة المكالمة @@ -6231,7 +6234,7 @@ تم إيقاف الترفيع مؤقتًا. شحن البطارية أقل من %1$d%% و ليست تُشحن الآن. - توقفت ترفيعات الكاميرا عن العمل. حاول إعادة تمكين ترفيعات الكاميرا لحلها. إذا استمرت المشكلة يرجى التواصل مع الدعم + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. ترفيعات الكاميرا قيد الإنجاز، %1$d ملف معلق @@ -6251,7 +6254,7 @@ اكتملت عمليات ترفيعات الكاميرا، وتم ترفيع %1$d ملف - [A]باقتك المجانية لها حد 60 دقيقة للاجتماعات. يتمتع مستخدمو برو Pro بمكالمات غير محدودة وما يصل إلى 1000 مشارك.[/A] [B]قم بالترقية الآن.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] إخفاء @@ -6260,11 +6263,30 @@ ترويج عرض لفترة محدودة - + Change SFU Server + الافتراضي هو -1 + أدخل معرف SFU + تغيير - الباقات المجانية لها حد 60 دقيقة لكل اجتماع. [A]قم بالترقية الآن.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + حسنًا، فهمت ذلك \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5d0e98a77d..d597139fb5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -781,7 +781,7 @@ Parken - Dies ist der letzte Schritt zum Parken Ihres Accounts. Bitte geben Sie nun Ihr neues Passwort ein. Ihre Daten werden mindestens 60 Tage lang aufbewahrt. Sollten Sie sich wieder an das Passwort Ihres geparkten Accounts erinnern, so hilft Ihnen support@mega.nz gerne weiter. + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Neues Passwort @@ -795,7 +795,7 @@ Vergrößern Sie Ihre Cloud. [A]Holen Sie sich mit einem Pro-Account mehr Speicherplatz und Transfervolumen. - Email address already in use. Enter another email address. + Diese E-Mail-Adresse wird bereits verwendet. Geben Sie eine andere E-Mail-Adresse an. Sie haben einen Bestätigungslink für diese E-Mail-Adresse angefordert. @@ -1853,7 +1853,7 @@ Beim nächsten Login werden Sie nach einem sechsstelligen Code gefragt, den Sie von Ihrer Authentifizierungs-App erhalten. - Bitte speichern Sie Ihren Rettungsschlüssel an einem sicheren Ort, um Probleme zu vermeiden, falls Sie nicht mehr auf Ihre App zugreifen können oder wenn Sie die Zwei-Faktor-Authentifizierung deaktivieren möchten. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Code ungültig @@ -5271,10 +5271,13 @@ Gewähren Sie Zugriff auf Ihre Galerie Zugriff gewähren - + Update erforderlich + Da Sie nicht die neueste Version unserer App verwenden, können Sie keine Anrufe oder Konferenzen starten oder an diesen teilnehmen. Führen Sie jetzt ein Update durch, um fortzufahren. + Aktualisieren + Später Zum Verlassen der Konferenz Gastgeber zuweisen @@ -5289,9 +5292,9 @@ Upload-Pause wegen fehlender Internetverbindung - Upload paused. Battery below %1$d%% and not charging. + Upload pausiert. Akku unter %1$d %% und nicht an Ladegerät angeschlossen. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Kamera-Uploads funktionieren nicht mehr. Um das Problem zu lösen, versuchen Sie, die Kamera-Uploads wieder zu aktivieren. Wenn das Problem weiterhin besteht, wenden Sie sich an den Support. Kamera-Uploads aktiv, noch %1$d Datei @@ -5303,20 +5306,39 @@ Kamera-Uploads abgeschlossen, %1$d Dateien hochgeladen - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Nicht anzeigen - Unhide + Einblenden Aktion - Limited time offer - + Zeitlich begrenztes Angebot + Change SFU Server + Der Standardwert ist -1 + SFU-ID eingeben + Ändern - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business-Account deaktiviert + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Ihr Business-Account wurde aufgrund einer fehlenden Zahlung deaktiviert. Sie können Ihre Daten nur lesen.\nUm eine Zahlung vorzunehmen und Ihr Abonnement erneut zu aktivieren, melden Sie sich in einem Browser bei MEGA an. + + Alles klar \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index af9cf1a2ee..4051d6607b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -403,7 +403,7 @@ Error. No se ha podido copiar - Choose a destination folder + Elige una carpeta de destino Elemento movido @@ -790,7 +790,7 @@ Aparcar - Éste es el último paso para aparcar tu cuenta, por favor escribe tu nueva contraseña. Tus datos se conservarán durante al menos 60 días. Si recuerdas la contraseña de tu cuenta aparcada, ponte en contacto con support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Introduce una nueva contraseña @@ -1896,7 +1896,7 @@ La próxima vez que inicies sesión en tu cuenta, tendrás que introducir un código de 6 dígitos proporcionado por tu aplicación de autenticación. - Guarda tu clave de recuperaciónen un lugar seguro en caso de que pierdas el acceso a tu aplicación o quieras desactivar la autenticación de dos factores. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Código no valido @@ -5506,10 +5506,13 @@ Permitir acceso a la galería Conceder acceso - + Actualización requerida + No estás usando la última versión de nuestra aplicación, por lo que no puedes iniciar llamadas ni unirte a ellas. Actualiza ahora para continuar. + Actualizar + Descartar Asignar anfitrión para abandonar la llamada @@ -5526,7 +5529,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. Subidas de la cámara en curso, %1$d archivo pendiente @@ -5540,7 +5543,7 @@ Subidas de la cámara completadas, %1$d archivos subidos - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Ocultar @@ -5549,11 +5552,30 @@ Oferta Limited time offer - + Change SFU Server + El predeterminado es -1 + Introducir identificador del SFU + Cambiar - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 1 mes a %2$s por mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + + Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 12 meses a %2$s por año. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + + Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 1 mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + + Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 12 meses. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + Entendido \ 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 2024e61a5a..f36af139de 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -790,7 +790,7 @@ Remiser - Cette étape est la dernière pour remiser votre compte. Veuillez saisir votre nouveau mot de passe. Vos données seront conservées pendant au moins 60 jours. Si vous vous souvenez du mot de passe de votre compte remisé, veuillez contacter support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Saisir le nouveau mot de passe @@ -1896,7 +1896,7 @@ La prochaine fois que vous vous connecterez à votre compte, un code à 6 chiffres fourni par votre appli d’authentification vous sera demandé. - Veuillez enregistrer votre clé de récupération en lieu sûr pour éviter les problèmes au cas où vous perdriez l’accès à votre appli ou si vous voulez désactiver l’authentification à deux facteurs. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Le code est invalide @@ -5506,10 +5506,13 @@ Autoriser l’accès à votre galerie Accorder l’accès - + Une mise à jour est nécessaire + Vous n’utilisez pas la version la plus récente de notre appli et ne pouvez donc pas démarrer d’appels ou y participer. Mettez l’appli à jour maintenant afin de poursuivre. + Mettre à jour + Fermer Assigner un hôte avant de quitter l’appel @@ -5524,9 +5527,9 @@ Les téléversements ont été mis en pause, car il n’y a pas de connexion à Internet - Upload paused. Battery below %1$d%% and not charging. + Le téléversement est en pause. Le niveau de batterie est inférieur à %1$d %% et l’appareil n’est pas en charge. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Les téléversements de l’appareil photo ne fonctionnent plus. Essayez de les réactiver afin de résoudre la situation. Si le problème persiste, contactez l’assistance. Téléversements de l’appareil photo en cours, %1$d fichier en attente @@ -5540,20 +5543,39 @@ Téléversements de l’appareil photo terminés, %1$d fichiers téléversés - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Cacher - Unhide + Afficher - Solde + Promo Offre à durée limitée - + Change SFU Server + La valeur par défaut est -1 + Saisissez l’ID SFU + Changer - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Le compte Pour entreprise a été désactivé + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Votre compte Pour Entreprise a été désactivé en raison d’un défaut de paiement. Vous ne pouvez que consulter vos données.\nPour effectuer un paiement et réactiver votre abonnement, connectez-vous à MEGA dans un navigateur. + + D’accord, j’ai compris \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index cd00a6a14d..bddbd91c8c 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -772,7 +772,7 @@ Parkir - Ini adalah langkah terakhir untuk memarkir akun anda, masukkan kata sandi baru anda. Data anda akan disimpan setidaknya selama 60 hari. Jika anda mengingat kata sandi akun yang diparkir, hubungi support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Masukkan password baru @@ -1810,7 +1810,7 @@ Lain kali anda masuk ke akun anda, anda akan diminta memasukkan kode 6-digit yang disediakan oleh aplikasi otentikasi anda. - Harap simpan kunci pemulihan anda di lokasi yang aman, untuk menghindari masalah jika anda kehilangan akses ke aplikasi anda, atau jika anda ingin menonaktifkan autentikasi dua faktor. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Kode salah @@ -5036,10 +5036,13 @@ Izinkan akses ke galeri anda Berikan akses - + Diperlukan pembaruan + Anda tidak menggunakan versi terbaru aplikasi kami sehingga anda tidak dapat memulai atau bergabung dengan panggilan. Perbarui sekarang untuk melanjutkan. + Perbarui + Abaikan Tetapkan tuan rumah untuk meninggalkan panggilan @@ -5056,7 +5059,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. Pengunggahan kamera sedang berlangsung, %1$d file tertunda @@ -5066,7 +5069,7 @@ Unggahan kamera selesai, %1$d file diunggah - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Menyembunyikan @@ -5075,11 +5078,30 @@ Promo Limited time offer - + Change SFU Server + Standarnya adalah -1 + Masukan ID SFU + Ganti - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + OK, mengerti \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1d500653f4..98bcc686d1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -790,7 +790,7 @@ Parcheggia - Questo è l’ultimo step per parcheggiare il tuo account, per favore inserisci la tua nuova password. I tuoi dati verranno mantenuti per almeno 60 giorni. Se recuperi la vecchia password del tuo account parcheggiato, per favore contatta support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Inserisci la nuova password @@ -1896,7 +1896,7 @@ La prossima volta che effettuerai l’accesso al tuo account ti verrà chiesto di inserire il codice di 6 cifre che ti è stato fornito dall\’app di autenticazione. - Per favore, salva la tua chiave di recupero in un luogo sicuro, per evitare problemi nel caso tu perda accesso alla tua app, o se vuoi disattivare l\’autenticazione a due fattori (2FA). + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Codice non valido @@ -5506,10 +5506,13 @@ Permetti l\’accesso alla tua galleria Garantisci l\’accesso - + Aggiornamento necessario + Non stai utilizzando l\’ultima versione della nostra app, quindi non puoi avviare o partecipare alle chiamate. Aggiorna ora per continuare. + Aggiorna + Chiudi Scegli host per abbandonare la chiamata @@ -5524,9 +5527,9 @@ Upload paused due to no internet connection - Upload paused. Battery below %1$d%% and not charging. + Caricamento in pausa. Batteria inferiore al %1$d%% e non in carica. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. Caricamenti da fotocamera in corso, %1$d file in attesa @@ -5540,20 +5543,39 @@ Caricamenti da fotocamera completati, %1$d file caricati - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Nascondi - Unhide + Rivela Promo Offerta a tempo limitato - + Change SFU Server + Il valore predefinito è -1 + Inserisci l\’ID SFU + Cambia - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + OK, capito \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 745e6d02e2..8f154a7934 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -772,7 +772,7 @@ 放置 - これは、あなたのアカウントをそのままにしておくための最後のステップです。新しいパスワードを入力してください。あなたのデータは少なくとも60日間は保持されます。そのままにしておいたアカウントのパスワードを思い出された場合は、support@mega.nzまでご連絡ください。 + これは、あなたのアカウントをそのままにしておくための最後のステップです。新しいパスワードを入力してください。あなたのデータは少なくとも60 日間は保持されます。そのままにしておいたアカウントのパスワードを思い出された場合は、support@mega.nzまでご連絡ください。 新しいパスワードを入力 @@ -1810,7 +1810,7 @@ 次回アカウントにログインすると、オーセンティケータアプリで提供される6桁のコードを入力するよう求められます。 - アプリへのアクセスができなくなったり、二要素認証を無効にしたい場合の問題を回避するために、回復キー安全な場所に保存してください。 + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. コードが無効です @@ -5036,10 +5036,13 @@ ギャラリーへのアクセスを許可する アクセスを許可 - + アップデートが必要です + 当社の最新バージョンのアプリを使用されていないため、通話を開始したり、通話に参加したりできません。今すぐアップデートしてから続行してください。 + 更新 + 却下 主催者を割り当てて通話を終了する @@ -5054,7 +5057,7 @@ インターネット接続がないためアップロードが一時停止されました - アップロードが一時停止されました。バッテリーが%1$d%%を下回っており、充電されていません。 + アップロードが一時停止されました。バッテリーが%1$d %%を下回っており、充電されていません。 カメラアップロードが機能しなくなりました。これを解決するには、カメラアップロードを再度有効にしてみてください。問題が解決しない場合は、サポートにご連絡ください。 @@ -5066,7 +5069,7 @@ カメラアップロードが完了しました。%1$d個のファイルがアップロードされました。 - [A]無料プランではミーティングに60分の制限があります。Proユーザー様は無制限の通話と、最大1000人の参加者まで可能です。[/A][B]ぜひ今すぐアップグレードしてください。[/B] + [A]無料プランではミーティングに60 分の制限があります。Proユーザー様は無制限の通話と、最大1000 人の参加者まで可能です。[/A][B]ぜひ今すぐアップグレードしてください。[/B] 隠す @@ -5075,11 +5078,30 @@ プロモ 期間限定オファー - + Change SFU Server + デフォルトは-1です + SFU IDを入力してください + 変更 - 無料プランでは、1回のミーティングあたり60分の制限があります。[A]ぜひ今すぐアップグレードしてください。[/A] + 無料プランでは、1回のミーティングあたり60 分の制限があります。[A]ぜひ今すぐアップグレードしてください。[/A] + + すぐに%1$sが請求され、お客様のサブスクリプションは1 か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + + すぐに%1$sが請求され、お客様のサブスクリプションは12 か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + + すぐに請求され、お客様のサブスクリプションは1 か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + + すぐに請求され、お客様のサブスクリプションは12 か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24 時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + + ビジネスアカウントの停止 + + お支払いに失敗されたため、お客様のビジネスアカウントが無効になりました。データの閲覧のみが可能です。\nこの問題を解決するには、ビジネスアカウン管理者様にお尋ねください。 + + お支払いに失敗されたため、お客様のビジネスアカウントが無効になりました。データの閲覧のみが可能です。\nお支払いを行ってサブスクリプションを再有効化するには、ブラウザからMEGAにログインしてください。 + + はい、わかりました。 \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 71a0386e6c..03bc17544d 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1810,7 +1810,7 @@ 다음번 로그인 때 당신의 인증기 앱에서 생성된 6자리 코드를 요구합니다. - 앱에 대한 접근을 잃었을 때의 문제를 피하거나, 2단계 인증을 비활성화 하고 싶은 경우를 대비하여, 복구 키를 안전한 곳에 저장하세요. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. 잘못된 코드 @@ -5036,10 +5036,13 @@ 갤러리에 접근 허용 접근 허가 - + 업데이트가 필요합니다 + 앱의 최신 버전을 이용하고 있지 않아서 통화를 시작하거나 참여할 수 없습니다. 계속 하려면 지금 업데이트 하세요. + 업데이트 + 해제 통화를 떠나려면 주최자를 할당하세요 @@ -5056,7 +5059,7 @@ 업로드가 일시 정지되었습니다. 배터리가 %1$d%% 이하이고 충전 중이지 않습니다 - 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면 지원으로 연락하세요 + 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면, 지원으로 연락하세요. 카메라 업로드 진행 중, 파일 %1$d개 대기 중 @@ -5070,16 +5073,35 @@ 숨기기 - Unhide + 숨기기 취소 행사 시간 제한이 있는 제안 - - Change SFU Server + + SFU 서버 변경 + 기본값은 -1입니다 + SFU ID 입력 + 변경 무료 요금제는 회의마다 60분의 제한이 있습니다. [A]지금 업그레이드.[/A] + + 즉시 %1$s이/가 청구될 것이며 구독은 1개월 후 자동으로 매월 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + + 즉시 %1$s이/가 청구될 것이며 구독은 12개월 후 자동으로 매년 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + + 요금이 즉시 청구될 것이며 구독은 1개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + + 요금이 즉시 청구될 것이며 구독은 12개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + + 비즈니스 계정이 비활성화됨 + + 비즈니스 계정이 결제 실패로 인하여 비활성화 되었습니다. 데이터 탐색만 할 수 있습니다.\n비즈니스 계정 관리자에게 문제를 해결해달라고 요청하세요. + + 비즈니스 계정이 결제 실패로 인하여 비활성화 되었습니다. 데이터 탐색만 할 수 있습니다.\n결제를 하고 구독을 재활성화 하려면, 브라우저를 통해 MEGA에 로그인하세요. + + 알겠습니다 \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4b7189a8d2..f09c604b9e 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -781,7 +781,7 @@ Parkeren - Dit is de laatste stap om uw account te parkeren, voer uw nieuwe wachtwoord in. Uw gegevens worden behouden voor tenminste 60 dagen, als u uw geparkeerde account wachtwoord herinnert, neem dan contact op met support@mega.nz + Dit is de laatste stap om uw account te parkeren. Voer uw nieuwe wachtwoord in. Uw gegevens worden minstens 60   dagen bewaard. Als u zich het wachtwoord van uw geparkeerde account herinnert, neem contact op met support@mega.nz Voer nieuw wachtwoord in @@ -1853,7 +1853,7 @@ De volgende keer dat u inlogt in uw account wordt u gevraagd een 6-cijferige code in te voeren die gegeven is door uw authenticatie applicatie. - Bewaar uw herstelsleutel op een veilige locatie om problemen te voorkomen als u toegang tot uw applicatie verliest of als u twee-staps authenticatie wilt uitschakelen. + Bewaar alstublieft uw herstelsleutel op een veilige lokatie, om problemen te vermijden als u de toegang tot uw applicatie verliest of als u twee-staps authenticatie wilt uitschakelen. Ongeldige code @@ -5271,10 +5271,13 @@ Geef toegang tot uw gallerij Toegang verlenen - + Update vereist + U gebruikt niet de laatste versie van onze applicatie, dus u kunt geen oproepen starten of aansluiten. Update nu om door te gaan. + Updaten + Afwijzen Gastheer toewijzen om oproep te verlaten @@ -5291,7 +5294,7 @@ Het uploaden is gepauzeerd. Batterij onder %1$d%% en laad niet op. - Camera-uploads werken niet meer. Probeer camera-uploads opnieuw in te schakelen om dit op te lossen. Als het probleem zich blijft voordoen, neem contact op met de klantenservice + Camera-uploads werken niet meer. Probeer camera-uploads opnieuw in te schakelen om het probleem op te lossen. Als het probleem zich blijft voordoen, neem contact op met de klantenservice. Camera uploads zijn in behandeling,%1$d bestand in wachtrij @@ -5303,20 +5306,39 @@ Camera uploads voltooid, %1$d bestanden geüpload - [A]Uw gratis abonnement heeft een limiet van 60 minuten voor vergaderingen. Pro-gebruikers kunnen onbeperkt bellen en tot 1000 deelnemers.[/A] [B]Nu upgraden.[/B] + [A]Uw gratis abonnement heeft een limiet van 60   minuten voor vergaderingen. Pro-gebruikers kunnen onbeperkt bellen en tot 1000   deelnemers.[/A] [B]Nu upgraden.[/B] Verbergen - Unhide + Zichtbaar maken Promo Tijdelijke aanbieding - - Change SFU Server + + SFU-server wijzigen + Standaard is -1 + Voer SFU-ID in + Wijzigen - Gratis abonnementen hebben een limiet van 60 minuten per vergadering. [A]Nu upgraden.[/A] + Gratis abonnementen hebben een limiet van 60   minuten per vergadering. [A]Nu upgraden.[/A] + + Er worden onmiddelijk kosten in rekening gebracht %1$s en uw abonnement wordt na 1   maand automatisch verlengd voor %2$s per maand. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + + Er worden onmiddelijk kosten in rekening gebracht %1$s en uw abonnement wordt na 12   maanden automatisch verlengd voor %2$s per jaar. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + + Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 1   maand automatisch verlengd. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + + Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 12   maanden automatisch verlengd. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + + Zakelijke account gedeactiveerd + + Uw Zakelijke account is gedeactiveerd vanwege een mislukte betaling. U kunt alleen uw gegevens bekijken.\nVraag de beheerder van uw Zakelijke account om het probleem op te lossen. + + Uw Zakelijke account is gedeactiveerd vanwege een mislukte betaling. U kunt alleen uw gegevens bekijken.\nOm een betaling uit te voeren en uw abonnement te her activeren, moet u via een browser bij MEGA inloggen. + + Ok, ik snap het \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 646287795b..9b760ac2fd 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -799,7 +799,7 @@ Zaparkuj - To jest ostatni krok przed zawieszeniem konta, wprowadź noweg hasło. Twoje dane będą przechowywanie przez conajmniej 60 dni. Jeżeli chcesz odwiesić swoje konto, skontaktuj się z support@mega.nz + To ostatni krok do zaparkowania konta, wprowadź nowe hasło. Twoje dane będą przechowywane przez co najmniej 60   dni. Jeśli pamiętasz hasło swojego zaparkowanego konta, kontakt support@mega.nz Wprowadź nowe hasło @@ -1939,7 +1939,7 @@ Gdy następnym razem zalogujesz się na swoje konto, zostaniesz poproszony o podanie 6-cyfrowego kodu podanego przez aplikację uwierzytelniającego. - Zapisz swój klucz odzyskiwania w bezpiecznym miejscu, aby uniknąć problemów w przypadku utraty dostępu do aplikacji lub jeśli chcesz wyłączyć uwierzytelnianie dwuskładnikowe. + Zapisz swój klucz odzyskiwania w bezpiecznej lokalizacji, aby uniknąć problemów w przypadku utraty dostępu do aplikacja lub jeśli chcesz wyłączyć uwierzytelnianie dwuskładnikowe. Nieprawidłowy kod @@ -5741,10 +5741,13 @@ Zezwalaj na dostęp do swojej galerii Przyznaj dostęp - + Wymagana aktualizacja + Nie używasz najnowszej wersji naszej aplikacji, więc nie możesz rozpoczynać połączeń ani dołączać do nich. Zaktualizuj teraz, aby kontynuować. + Zaktualizuj + Odrzucić Przypisanie hosta do opuszczenia połączenia @@ -5759,9 +5762,9 @@ Upload paused due to no internet connection - Upload paused. Battery below %1$d%% and not charging. + Przesyłanie wstrzymane. Bateria poniżej %1$d%% i nie ładuje. - Przesyłanie wgraj kamery przestało działać. Spróbuj ponownie włączyć przesyłanie z kamery, aby rozwiązać ten problem. Jeśli problem nadal występuje, skontaktuj się z pomocą techniczną + Przesyłanie wgraj kamery przestało działać. Spróbuj ponownie włączyć przesyłanie z kamery, aby rozwiązać ten problem. Jeśli problem nadal występuje, skontaktuj kontakt wsparcie. Trwa przesyłanie kamery, %1$d plików oczekuje na przesłanie @@ -5777,20 +5780,39 @@ Przesyłanie kamery zakończone, przesłano %1$d plików - [A]Twój darmowy plan ma limit 60 minut na spotkania. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000 uczestników.[/A] [B]Uaktualnij teraz.[/B] + [A]Twój darmowy plan ma limit 60   minut na spotkanie. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000   uczestników.[/A] [B]Uaktualnij teraz.[/B] Ukryj - Unhide + Odkryj Promocja Oferta ograniczona czasowo - - Change SFU Server + + Zmień serwer SFU + Domyślna wartość to -1 + Wprowadź SFU ID + Zmień - Bezpłatne plan mają limit 60 minut na spotkanie. [A]Uaktualnij teraz.[/A] + Bezpłatne plany mają limit 60   minut na spotkanie. [A]Uaktualnij teraz.[/A] + + Zostaniesz obciążony %1$s natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 1   miesiącu %2$s miesięcznie. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godziny przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + + Zostaniesz obciążony %1$s natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 12   miesiącach %2$s rocznie. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + + Zostaniesz obciążony natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 1   miesiącach. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + + Zostaniesz obciążony natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 12   miesiącach. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + + Biznes firmowe dezaktywowane + + Twoje konto firmowe zostało dezaktywowane z powodu niepowodzenia płatności. Możesz przeglądać tylko swoje dane.\nPoproś administratora konto firmowego o rozwiązanie problemu. + + Twoje konto firmowe zostało dezaktywowane z powodu niepowodzenia płatności. Możesz przeglądać tylko swoje dane.\nAby dokonać płatności i ponownie aktywować subskrypcja, zaloguj się do MEGA przez przeglądarkę. + + OK, rozumiem \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 08cdc588bc..d42227ff9f 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -790,7 +790,7 @@ Estacionar - Este é o último passo para estacionar a sua conta: por favor, digite a sua nova senha. Os seus dados serão mantidos durante um mínimo de 60 dias. Se você lembrar da senha da sua conta estacionada, entre em contato com support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Insira a nova senha @@ -1896,7 +1896,7 @@ Na próxima vez que você fizer login na sua conta, você deverá digitar um código de seis dígitos proporcionado pelo seu aplicativo de autenticação. - Salve a sua chave de recuperação em um lugar seguro, para evitar problemas caso perca o acesso ao seu aplicativo ou se queira desativar a autenticação de dois fatores. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Código inválido @@ -1906,7 +1906,7 @@ Alterar senha - Alterar e-mail + Alterar o email Deletar conta @@ -5506,10 +5506,13 @@ Permitir o acesso à sua galeria Permitir acesso - + Atualização necessária + Você não está usando a versão mais recente do nosso aplicativo, e por isso não poderá fazer ou entrar em chamadas. Atualize para poder continuar. + Atualizar + Fechar Designar anfitrião para sair da chamada @@ -5526,7 +5529,7 @@ O upload foi pausado. Há menos de %1$d%% de bateria, e não está sendo carregada. - Os uploads da câmera pararam de funcionar - tente reativá-los. Se o problema persistir, entre em contato com o suporte + Os uploads da câmera pararam de funcionar - tente reativá-los. Se o problema persistir, entre em contato com o suporte. Uploads da câmera em andamento, %1$d arquivo pendente @@ -5540,7 +5543,7 @@ Uploads da câmera concluídos, foi feito o upload de %1$d arquivos - [A]O seu plano gratuito tem um limite de 60 minutos para reuniões. Usuários com planos Pro podem fazer chamadas ilimitadas com até 1000 participantes.[/A] [B]Faça um upgrade.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Ocultar @@ -5549,11 +5552,30 @@ Oferta Oferta por tempo limitado - + Change SFU Server + O ID predeterminado é -1 + Digite o ID SFU + Alterar - Os planos gratuitos têm um limite de 60 minutos por reunião. [A]Faça um upgrade.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Conta Business desativada + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + A sua conta Business foi desativada porque o pagamento falhou. Somente é possível visualizar os seus dados.\nPara fazer um pagamento e reativar a sua assinatura, faça login no MEGA usando um navegador. + + Entendi \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 383cc3a403..1e8e34cd0f 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -790,7 +790,7 @@ Parchează - Acesta este ultimul pas pentru a vă parca contul, vă rugăm să introduceți noua parolă. Datele dvs. vor fi păstrate timp de cel puțin 60 de zile. Dacă vă amintiți parola contului parcat, vă rugăm să contactați support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Introduceți o parolă nouă @@ -1896,7 +1896,7 @@ Data viitoare când vă conectați la contul dvs., vi se va cere să introduceți un cod de 6 cifre furnizat de aplicația dvs. de autentificare. - Vă rugăm să salvați cheie de recuperare într-o locație sigură, pentru a evita problemele în cazul în care pierdeți accesul la aplicația dvs. sau dacă doriți să dezactivați autentificarea cu doi factori. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Cod nevalid @@ -5506,10 +5506,13 @@ Permiteți accesul la galeria dvs. Acordă acces - + Actualizarea necesară + Nu utilizați cea mai recentă versiune a aplicației noastre, astfel încât să nu puteți începe sau să vă alăturați apelurilor. Actualizați acum pentru a continua. + Actualizează + Respinge Desemnează o gazdă înainte de a părăsi apelul @@ -5524,9 +5527,9 @@ Încărcarea întreruptă din cauza lipsei conexiunii la internet - Upload paused. Battery below %1$d%% and not charging. + Încărcarea întreruptă. Baterie este sub %1$d %% și nu se încarcă. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. Încărcări cameră în desfășurare, %1$d fișier în așteptare @@ -5540,20 +5543,39 @@ Încărcări cameră complete, %1$d de fișiere încărcate - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Ascunde - Unhide + Afișare. Promoție Ofertă de timp limitat - + Change SFU Server + Implicit este -1 + Introduceți ID-ul SFU + Schimbă - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + OK, am înțeles \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3bb9521c11..ad9c7c6a73 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -799,7 +799,7 @@ Заморозить - Это последний шаг перед заморозкой аккаунта. Пожалуйста, введите новый пароль. Ваши данные будут храниться ещё как минимум 60 дней. Если вы вспомнили пароль замороженного аккаунта, пожалуйста, свяжитесь с support@mega.nz + Это последний шаг перед заморозкой аккаунта. Пожалуйста, введите новый пароль. Ваши данные будут храниться ещё как минимум 60 дней. Если вы вспомнили пароль замороженного аккаунта, пожалуйста, свяжитесь с support@mega.nz Введите новый пароль @@ -1939,7 +1939,7 @@ При следующем входе в аккаунт система запросит 6-значный код из приложения-аутентификатора. - Пожалуйста, сохраните ключ восстановления в надёжном месте, чтобы избежать проблем, если вы потеряете доступ к своему приложению или захотите отключить двухфакторную аутентификацию. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Недействительный код @@ -5741,10 +5741,13 @@ Разрешите доступ к галерее Открыть доступ - + Требуется обновление + У вас не последняя версия нашего приложения, поэтому вы не можете начинать звонки или присоединяться к ним. Обновите приложение, чтобы продолжить. + Изменить + Отклонить Назначьте организатора, чтобы покинуть звонок @@ -5759,9 +5762,9 @@ Upload paused due to no internet connection - Загрузка приостановлена. Аккумулятор заряжен менее чем на %1$d%% и не заряжается. + Загрузка приостановлена. Аккумулятор заряжен менее чем на %1$d %% и не заряжается. - Загрузки из камеры перестали работать. Попробуйте повторно включить загрузки из камеры. Если проблема повторяется, пожалуйста, обратитесь в поддержку + Загрузки из камеры перестали работать. Попробуйте повторно включить загрузки из камеры. Если проблема повторяется, обратитесь в поддержку. Выполняется загрузка из камеры, %1$d файл ожидает обработки @@ -5777,20 +5780,39 @@ Загрузка из камеры завершена, загружено %1$d файла - [A]В бесплатном плане встречи ограничены 60 минутами. У пользователей Pro звонки не ограничены по длительности и могут включать до 1000 участников.[/A] [B]Улучшить план.[/B] + [A]В бесплатном плане встречи ограничены 60 минутами. У пользователей Pro звонки не ограничены по длительности и могут включать до 1000 участников.[/A] [B]Улучшить план.[/B] Скрыть - Unhide + Показывать Промо Предложение ограничено по времени - - Change SFU Server + + Изменение SFU-сервера + По умолчанию -1 + Введите SFU ID + Изменить - В бесплатных планах встречи ограничены 60 минутами. [A]Улучшить план.[/A] + В бесплатных планах встречи ограничены 60 минутами. [A]Улучшить план.[/A] + + У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 1 месяц за %2$s в месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + + У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 12 месяцев за %2$s в год. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + + У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 1 месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + + У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 12 месяцев. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + + Бизнес-аккаунт деактивирован + + Ваш бизнес-аккаунт был деактивирован из-за сбоя оплаты. Вы сможете только просматривать свои данные.\nОбратитесь к администратору бизнес-аккаунта, чтобы решить проблему. + + Ваш бизнес-аккаунт был деактивирован из-за сбоя оплаты. Вы сможете только просматривать свои данные.\nДля оплаты и возобновления подписки войдите в MEGA через веб-браузер. + + Понятно \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 7f1cabb9ed..07864eaf8d 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -772,7 +772,7 @@ เก็บบัญชี - นี่เป็นขั้นตอนสุดท้ายในการเก็บบัญชีของคุณ กรุณากรอกรหัสผ่านใหม่ของคุณ ข้อมูลของคุณจะถูกเก็บไว้อย่างน้อย 60 วัน ถ้าคุณจำรหัสผ่านของบัญชีที่เก็บไว้ได้ กรุณาติดต่อ support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz กรอกรหัสผ่านใหม่ @@ -1810,7 +1810,7 @@ ครั้งต่อไปที่คุณลงชื่อเข้าใช้บัญชี ระบบจะขอให้คุณกรอกรหัส 6 หลักจากแอปตัวรับรองความถูกต้องที่ให้มา - กรุณาบันทึกคีย์การกู้คืนของคุณไว้ในที่ปลอดภัย เพื่อหลีกเลี่ยงปัญหาในกรณีที่คุณไม่สามารถเข้าถึงแอปของคุณหรือคุณต้องการปิดใช้งานการรับรองความถูกต้องด้วยสองปัจจัย + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. โค้ดไม่ถูกต้อง @@ -5036,10 +5036,13 @@ อนุญาตให้เข้าถึงแกลเลอรี่ของคุณ ให้สิทธิ์เข้าถึง - + จำเป็นต้องได้รับการอัปเดต + คุณกำลังใช้แอปเวอร์ชันเก่า ไม่สามารถเริ่มหรือเข้าร่วมการโทรได้ กรุณาอัปเดตแอปเป็นเวอร์ชันล่าสุดเพื่อใช้งานต่อไป + อัปเดต + ปิด มอบหมายให้คนอื่นเป็นผู้จัดการประชุมก่อนที่จะวางสาย @@ -5056,7 +5059,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. การอัปโหลดจากกล้องกำลังอยู่ในระหว่างดำเนินการ มี %1$d ไฟล์รอดำเนินการ @@ -5066,7 +5069,7 @@ การอัปโหลดจากกล้องเสร็จสมบูรณ์ มี %1$d ไฟล์ที่อัปโหลดแล้ว - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] ซ่อน @@ -5075,11 +5078,30 @@ โปรโมชั่น ข้อเสนอสุดพิเศษ - + Change SFU Server + ค่าเริ่มต้นคือ -1 + กรอกไอดี SFU + เปลี่ยน - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + คุณจะถูกเรียกเก็บเงิน %1$s ทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน ในราคา %2$s ต่อเดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + + คุณจะถูกเรียกเก็บเงิน %1$s ทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 12 เดือน ในราคา %2$s ต่อปี บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + + คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + + คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 12 เดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + โอเค เข้าใจแล้ว \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 14e2cd9c4d..9b5f6b174d 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -772,7 +772,7 @@ Đặt thay mới - Đây là bước cuối cùng để đặt thay mới tài khoản, xin tạo một mật khẩu ở dưới đây. Mọi dữ liệu từ tài khoản cũ sẽ được bảo lưu trong 60 ngày. Trong thời gian đó nếu nhớ ra lại mật khẩu của tài khoản cũ, xin vui lòng liên hệ support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz Nhập mật khẩu mới @@ -1810,7 +1810,7 @@ Vào những lần đăng nhập tiếp theo, hệ thống sẽ yêu cầu nhập một đoạn mã dài 6 chữ số lấy từ app lập xác thực. - Xin lưu chìa khóa phục hồi của tài khoản của bạn ở nơi an toàn, để tránh trường hợp mất khả năng truy cập vào ứng dụng, hoặc khi bạn muốn tắt đi xác thực 2 yếu tố. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Mã không phù hợp @@ -5036,10 +5036,13 @@ Cho phép truy cập vào thư viện hình ảnh của bạn Cấp quyền - + Cần phải cập nhật + Bạn hiện không sử dụng phiên bản mới nhất của ứng dụng nên bạn không thể bắt đầu hoặc tham gia cuộc gọi được. Cập nhật ngay bây giờ để tiếp tục. + Cập nhật + Bỏ qua Giao chức chủ trì để rời khỏi cuộc gọi @@ -5056,7 +5059,7 @@ Tải lên bị tạm dừng. Pin bên dưới %1$d%% và không được sạc. - Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với bộ phận hỗ trợ + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. Việc đăng tải camêra đang được thực hiện, %1$d tệp đang chờ @@ -5066,7 +5069,7 @@ Đăng tải camêra hoàn tất, %1$d tệp tin đã được tải lên - [A]Gói miễn phí của bạn có giới hạn cuộc họp là 60 phút. Người dùng Pro có thời lượng cuộc gọi không giới hạn và có tối đa 1000 người tham gia.[/A] [B]Nâng cấp ngay bây giờ.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] Ẩn @@ -5075,11 +5078,30 @@ Khuyến mãi Ưu đãi có thời gian giới hạn - + Change SFU Server + Mặc định là -1 + Nhập số ID của SFU + Thay đổi - Gói miễn phí có giới hạn thời lượng cuộc họp là 60 phút mỗi cuộc. [A]Nâng cấp ngay.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + OK, hiểu rồi \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 807c6bae08..850b4aa339 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -772,7 +772,7 @@ 封存 - 这是封存您的帐户的最后一步,请输入您的新密码。您的数据将保留至少60天。在此期间,如果您想起了已封存帐户的密码,请联系support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz 请输入新密码 @@ -1810,7 +1810,7 @@ 下次登录您的帐户时,系统会要求您输入身份验证应用程序中提供的6位数验证码。 - 为避免您忘记密码或想要禁用双重验证时出现问题,请将您的恢复密钥保存到安全位置。 + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. 验证码无效 @@ -5036,10 +5036,13 @@ 允许访问您的图库 授予权限 - + 需要更新 + 您使用的不是我们应用程序的最新版本,因此您无法发起或加入通话。立即更新以继续。 + 更新 + 忽略 指定主持人以离开通话 @@ -5056,7 +5059,7 @@ Upload paused. Battery below %1$d%% and not charging. - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists please contact support + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. 正在相机上传,%1$d个文件待处理 @@ -5066,20 +5069,39 @@ 相机上传完成,%1$d个文件已上传 - [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] 隐藏 - Unhide + 取消隐藏 促销 - Limited time offer - + 限时优惠 + Change SFU Server + 默认为-1 + 输入SFU帐号 + 更改 - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + 好的,明白了 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 2462119e0f..e1c4f5954a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -772,7 +772,7 @@ 停用 - 這是停用您帳戶的最後一步,請輸入您的新密碼。您的資料將保留至少60天。如果您之後想起您已停用帳戶的密碼,請聯繫 support@mega.nz + This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, please contact support@mega.nz 請輸入新密碼 @@ -856,7 +856,7 @@ %1$d個項目 - 由於多次違反我們的服務條款,相關的用戶帳戶已被終止使用權。 + 由於多次違反我們的服務條款,相關的用戶帳戶已被停用。 您提供的資料夾連結解密金鑰無效。 @@ -1810,7 +1810,7 @@ 下次登入您的帳戶時,系統會要求您輸入身份驗證程式提供的6位數字代碼。 - 為避免您忘記密碼或想要停用雙重驗證時遇到問題,請將您的還原金鑰儲存在一個安全地方, + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. 無效的二維條碼 @@ -5036,10 +5036,13 @@ 允許存取您的相簿 授予權限 - + 需要更新 + 您沒有使用我們應用程式的最新版本,因此您無法啟動或加入通話。立即更新以繼續。 + 更改 + 忽略 指定主持人再離開通話 @@ -5056,7 +5059,7 @@ 上傳暫停。電量低於%1$d%%且未處充電中。 - 相機上傳停止運作。嘗試重新啟用相機上傳來解決問題。如果問題仍然存在,請聯繫客服 + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. 相機上傳正在進行中,%1$d個檔案待處理 @@ -5066,20 +5069,39 @@ 相機上傳已完成,%1$d個檔案已上傳 - [A]您的免費方案有60分鐘的會議時間限制。Pro版使用者有無限時間的通話,而且最多可容納 1000個與會者。[/A][B]立即升級。[/B] + [A]Your free plan has a 60 minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] 隱藏 - Unhide + 取消隱藏 促銷 限時優惠 - + Change SFU Server + 預設為-1 + 輸入SFU ID + 變更 - 免費方案每次會議有60分鐘的限制。[A]立即升級。[/A] + Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + 商業帳戶已停用 + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + 由於付款失敗,您的商業帳戶已停用。您只能瀏覽您的資料。\n若要付款並重新啟用您的訂閱,請透過瀏覽器登入MEGA。 + + 好的,明白了 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 75e6155444..02c2cad116 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + Pro Lite @@ -1853,7 +1853,7 @@ Next time you log in to your account you will be asked to enter a 6-digit code provided by your authenticator app. - Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. + Please save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. Invalid code @@ -4473,12 +4473,18 @@ Couldn’t copy %1$d item Couldn’t copy %1$d items - + Copied %1$d item,  Copied %1$d items,  - + couldn’t copy %1$d item couldn’t copy %1$d items @@ -5271,10 +5277,13 @@ Allow access to your gallery Grant access - + Update required + You’re not using the latest version of our app so you can’t start or join calls. Update now to continue. + Update + Dismiss Assign host to leave call @@ -5312,10 +5321,13 @@ Promo Limited time offer - + Change SFU Server + Default is -1 + Enter SFU ID + Change Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] @@ -5324,7 +5336,19 @@ You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s / year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. - You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. - - You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + + Business account deactivated + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + + Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + + OK, got it + + • Host calls and meetings with unlimited participants and without time restrictions + + • Stay private online with our high-speed VPN \ No newline at end of file diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index be5bdca4c6..5241d3fdb0 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -121,7 +121,7 @@ Verschieben oder Umbenennen nicht möglich - Deletion or move waiting on scanning + Löschen oder Verschieben während des Scanvorgangs Löschen noch nicht möglich @@ -167,7 +167,7 @@ Der Zielordner ist nicht zugänglich - An error occurred either downloading the file, or moving the downloaded temporary file to its final location. + Beim Herunterladen der Datei oder beim Verschieben der heruntergeladenen temporären Datei an den endgültigen Speicherort ist ein Fehler aufgetreten. Ein lokaler Fehler verhindert den Ordnerzugriff @@ -185,9 +185,9 @@ Ein Verschieben oder Umbenennen wurde auf MEGA erkannt, konnte jedoch lokal nicht repliziert werden. - Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. + Ein lokal erkannter Verschiebe- oder Umbenennungsvorgang konnte auf MEGA nicht repliziert werden. - Waiting for scan to finish to determine if the file was moved or deleted. + Abschluss des Scanvorgangs wird abgewartet, um zu bestimmen, ob die Datei verschoben oder gelöscht wurde. Ordner auswählen \ No newline at end of file diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index 122c33db15..e8916f9f90 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -117,7 +117,7 @@ 无法移动或重命名 - Deletion or move waiting on scanning + 等待删除或移动的扫描中 还无法删除 @@ -163,7 +163,7 @@ 无法访问目标文件夹 - An error occurred either downloading the file, or moving the downloaded temporary file to its final location. + 下载文件或将下载的临时文件移动到其最终位置时出错。 本地错误导致无法访问文件夹 @@ -181,9 +181,9 @@ 在MEGA中检测到移动或重命名,但无法在本地复制。 - Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. + 检测到本地发生的移动或重命名,但无法在MEGA中复制。 - Waiting for scan to finish to determine if the file was moved or deleted. + 等待扫描完成以确定文件是否已移动或删除。 选择文件夹 \ No newline at end of file From d7cb877e02f1a0cea3c9f767f11484f2b61ee572 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Wed, 20 Mar 2024 12:59:27 +0800 Subject: [PATCH 045/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 92852be0cb..d26a94f8a6 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240319.060714" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 2cf331c3abf61ca30a1f1dfe55ecff4f22a76ec4 Mon Sep 17 00:00:00 2001 From: Javier Gomez Date: Wed, 20 Mar 2024 16:25:31 +0100 Subject: [PATCH 046/261] SAT-371: Device Center - Create a New "Info" Page for Devices (TC15394497) --- .../devicecenter/ui/DeviceCenterInfoScreen.kt | 17 ++++++++++++++++- .../ui/DeviceCenterInfoViewModel.kt | 8 +++++++- .../ui/model/DeviceCenterInfoUiState.kt | 4 ++++ .../ui/model/icon/DeviceCenterUINodeIcon.kt | 6 ++++-- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt index 362fd32063..a7b3386e40 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource @@ -31,6 +32,7 @@ import mega.privacy.android.core.ui.controls.appbar.AppBarType import mega.privacy.android.core.ui.controls.appbar.MegaAppBar import mega.privacy.android.core.ui.controls.text.MegaText import mega.privacy.android.core.ui.preview.CombinedThemePreviews +import mega.privacy.android.core.ui.theme.extensions.textColorSecondary import mega.privacy.android.core.ui.theme.tokens.TextColor import mega.privacy.android.feature.devicecenter.R import mega.privacy.android.feature.devicecenter.ui.model.DeviceCenterInfoUiState @@ -83,7 +85,11 @@ private fun DeviceCenterInfoScreenContent( Column( modifier = modifier.fillMaxSize() ) { - IconAndTitleRow(icon = uiState.icon, name = uiState.name) + IconAndTitleRow( + icon = uiState.icon, + applySecondaryColorIconTint = uiState.applySecondaryColorIconTint, + name = uiState.name + ) if (uiState.creationTime > 0) { InfoRow( title = "Added", info = formatModifiedDate( @@ -133,6 +139,7 @@ private fun DeviceCenterInfoScreenContent( @Composable private fun IconAndTitleRow( @DrawableRes icon: Int, + applySecondaryColorIconTint: Boolean, name: String, modifier: Modifier = Modifier, ) { @@ -151,6 +158,13 @@ private fun IconAndTitleRow( .testTag(DEVICE_CENTER_INFO_VIEW_ICON_TAG), painter = painterResource(id = icon), contentDescription = "Item icon", + colorFilter = if (applySecondaryColorIconTint) { + // Temporary fix in order to fix icon color until we change to the new icon set. + // Will be removed soon + ColorFilter.tint(MaterialTheme.colors.textColorSecondary) + } else { + null + } ) MegaText( @@ -193,6 +207,7 @@ private fun DeviceCenterInfoScreenDevicePreview() { DeviceCenterInfoScreen( uiState = DeviceCenterInfoUiState( icon = R.drawable.ic_device_pc, + applySecondaryColorIconTint = true, name = "Device name", numberOfFiles = 6, numberOfFolders = 5, diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoViewModel.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoViewModel.kt index fc8dc32b7f..e4622402bf 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoViewModel.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoViewModel.kt @@ -46,7 +46,13 @@ internal class DeviceCenterInfoViewModel @Inject constructor( private fun loadInfo() { selectedItem?.let { item -> with(item) { - _state.update { it.copy(name = name, icon = icon.iconRes) } + _state.update { + it.copy( + name = name, + icon = icon.iconRes, + applySecondaryColorIconTint = item is DeviceUINode + ) + } when (item) { is DeviceUINode -> { diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt index 444208653e..007a28a448 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt @@ -7,6 +7,7 @@ import mega.privacy.android.feature.devicecenter.R * Data class representing the state of the Device Center Info View * * @property icon Icon of the item + * @property applySecondaryColorIconTint If true, applies the secondary color to the icon * @property name Name of the item * @property numberOfFiles The number of files this item and its sub-folders has * @property numberOfFolders The number of folders and sub-folders this item has, including itself @@ -15,6 +16,9 @@ import mega.privacy.android.feature.devicecenter.R */ data class DeviceCenterInfoUiState( @DrawableRes val icon: Int = R.drawable.ic_device_folder, + @Deprecated( + "Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon." + ) val applySecondaryColorIconTint: Boolean = false, val name: String = String(), val numberOfFiles: Int = 0, val numberOfFolders: Int = 0, diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceCenterUINodeIcon.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceCenterUINodeIcon.kt index d870f0e1c8..69154575ff 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceCenterUINodeIcon.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceCenterUINodeIcon.kt @@ -7,12 +7,14 @@ import androidx.annotation.DrawableRes * Device Center are derived from * * @property iconRes The UI Node icon as a [DrawableRes] - * @property applySecondaryColorTint if true, applies the textColorSecondary color from - * MaterialTheme.colors. No tint is applied if false + * @property applySecondaryColorTint if true, applies the textColorSecondary color from MaterialTheme.colors. No tint is applied if false */ interface DeviceCenterUINodeIcon { @get:DrawableRes val iconRes: Int + @Deprecated( + "Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon." + ) val applySecondaryColorTint: Boolean } \ No newline at end of file From 6ea6ac62a61fe234936271560c09a15cfbb01fab Mon Sep 17 00:00:00 2001 From: Yenel Date: Thu, 21 Mar 2024 14:05:03 +0100 Subject: [PATCH 047/261] AND-18487 Remove ChatActivity.java usage from MeetingActivity --- .../app/meeting/activity/MeetingActivity.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt index f28431d265..b17d42940e 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt @@ -29,7 +29,6 @@ import mega.privacy.android.app.R import mega.privacy.android.app.activities.PasscodeActivity import mega.privacy.android.app.arch.extensions.collectFlow import mega.privacy.android.app.databinding.ActivityMeetingBinding -import mega.privacy.android.app.main.megachat.ChatActivity import mega.privacy.android.app.meeting.CallNotificationIntentService import mega.privacy.android.app.meeting.fragments.CreateMeetingFragment import mega.privacy.android.app.meeting.fragments.InMeetingFragment @@ -41,7 +40,6 @@ import mega.privacy.android.app.meeting.gateway.RTCAudioManagerGateway import mega.privacy.android.app.myAccount.MyAccountActivity import mega.privacy.android.app.presentation.contactinfo.ContactInfoActivity import mega.privacy.android.app.presentation.extensions.changeStatusBarColor -import mega.privacy.android.app.presentation.extensions.isDarkMode import mega.privacy.android.app.presentation.meeting.WaitingRoomManagementViewModel import mega.privacy.android.app.presentation.meeting.model.MeetingState import mega.privacy.android.app.presentation.meeting.model.WaitingRoomManagementState @@ -52,12 +50,12 @@ import mega.privacy.android.app.presentation.meeting.view.UsersInWaitingRoomDial import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.Constants.REQUIRE_PASSCODE_INVALID import mega.privacy.android.app.utils.ScheduledMeetingDateUtil.getAppropriateStringForScheduledMeetingDate -import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.android.domain.entity.ChatRoomPermission -import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.entity.chat.ChatScheduledMeeting import mega.privacy.android.domain.entity.meeting.ParticipantsSection import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.navigation.MegaNavigator +import mega.privacy.android.shared.theme.MegaAppTheme import nz.mega.sdk.MegaChatApiJava.MEGACHAT_INVALID_HANDLE import timber.log.Timber import javax.inject.Inject @@ -109,6 +107,9 @@ class MeetingActivity : PasscodeActivity() { @Inject lateinit var getThemeMode: GetThemeMode + @Inject + lateinit var navigator: MegaNavigator + /** * Rtc audio manager gateway */ @@ -414,12 +415,10 @@ class MeetingActivity : PasscodeActivity() { } if (state.chatIdToOpen != -1L) { - startActivity( - Intent( - this, - ChatActivity::class.java - ).setAction(Constants.ACTION_CHAT_SHOW_MESSAGES) - .putExtra(Constants.CHAT_ID, state.chatIdToOpen) + navigator.openChat( + context = this, + chatId = state.chatIdToOpen, + action = Constants.ACTION_CHAT_SHOW_MESSAGES ) meetingViewModel.onConsumeNavigateToChatEvent() } From 7add499166cbc465adf1dd6c2d3df2142ba59d73 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 21 Mar 2024 14:05:53 +0700 Subject: [PATCH 048/261] T15414727: Fix can not leave group chat (cherry picked from commit 71d2995deb8bcd68079ff18ac18efa19838f2070) --- .../meeting/chat/model/ChatViewModel.kt | 34 +++++++++++++++++++ .../meeting/chat/ChatViewModelTest.kt | 30 ++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt index 8d934e6289..7658457d32 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt @@ -28,6 +28,7 @@ import mega.privacy.android.app.main.megachat.MapsActivity import mega.privacy.android.app.meeting.gateway.RTCAudioManagerGateway import mega.privacy.android.app.objects.GifData import mega.privacy.android.app.objects.PasscodeManagement +import mega.privacy.android.app.presentation.extensions.getErrorStringId import mega.privacy.android.app.presentation.extensions.isPast import mega.privacy.android.app.presentation.meeting.chat.extension.isJoined import mega.privacy.android.app.presentation.meeting.chat.mapper.ForwardMessagesResultMapper @@ -57,6 +58,7 @@ import mega.privacy.android.domain.entity.node.chat.ChatFile import mega.privacy.android.domain.entity.statistics.EndCallForAll import mega.privacy.android.domain.entity.transfer.MultiTransferEvent import mega.privacy.android.domain.entity.user.UserId +import mega.privacy.android.domain.exception.MegaException import mega.privacy.android.domain.exception.chat.CreateChatException import mega.privacy.android.domain.exception.chat.ResourceDoesNotExistChatException import mega.privacy.android.domain.qualifier.ApplicationScope @@ -79,9 +81,11 @@ import mega.privacy.android.domain.usecase.chat.InviteToChatUseCase import mega.privacy.android.domain.usecase.chat.IsAnonymousModeUseCase import mega.privacy.android.domain.usecase.chat.IsChatNotificationMuteUseCase import mega.privacy.android.domain.usecase.chat.IsGeolocationEnabledUseCase +import mega.privacy.android.domain.usecase.chat.LeaveChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorCallInChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorChatConnectionStateUseCase import mega.privacy.android.domain.usecase.chat.MonitorChatPendingChangesUseCase +import mega.privacy.android.domain.usecase.chat.MonitorLeaveChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorLeavingChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorParticipatingInACallInOtherChatsUseCase import mega.privacy.android.domain.usecase.chat.MonitorUserChatStatusByHandleUseCase @@ -231,6 +235,8 @@ class ChatViewModel @Inject constructor( private val getCacheFileUseCase: GetCacheFileUseCase, private val recordAudioUseCase: RecordAudioUseCase, private val deleteFileUseCase: DeleteFileUseCase, + private val monitorLeaveChatUseCase: MonitorLeaveChatUseCase, + private val leaveChatUseCase: LeaveChatUseCase, ) : ViewModel() { private val _state = MutableStateFlow(ChatUiState()) val state = _state.asStateFlow() @@ -264,6 +270,7 @@ class ChatViewModel @Inject constructor( monitorNotificationMute() monitorJoiningChat() monitorLeavingChat() + monitorLeaveChat() monitorChatRoomPreference() } @@ -1521,6 +1528,33 @@ class ChatViewModel @Inject constructor( } } + private fun monitorLeaveChat() { + viewModelScope.launch { + monitorLeaveChatUseCase() + .collect { requestChatId -> + if (chatId == requestChatId) { + leaveChat() + } + } + } + } + + private fun leaveChat() { + viewModelScope.launch { + runCatching { + leaveChatUseCase(chatId) + }.onFailure { exception -> + if (exception is MegaException) { + _state.update { state -> + state.copy( + infoToShowEvent = triggered(InfoToShow.SimpleString(exception.getErrorStringId())) + ) + } + } + } + } + } + companion object { private const val INVALID_HANDLE = -1L } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt index 79b8c9f0d9..3fb3958ae1 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt @@ -89,9 +89,11 @@ import mega.privacy.android.domain.usecase.chat.InviteToChatUseCase import mega.privacy.android.domain.usecase.chat.IsAnonymousModeUseCase import mega.privacy.android.domain.usecase.chat.IsChatNotificationMuteUseCase import mega.privacy.android.domain.usecase.chat.IsGeolocationEnabledUseCase +import mega.privacy.android.domain.usecase.chat.LeaveChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorCallInChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorChatConnectionStateUseCase import mega.privacy.android.domain.usecase.chat.MonitorChatPendingChangesUseCase +import mega.privacy.android.domain.usecase.chat.MonitorLeaveChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorLeavingChatUseCase import mega.privacy.android.domain.usecase.chat.MonitorParticipatingInACallInOtherChatsUseCase import mega.privacy.android.domain.usecase.chat.MonitorUserChatStatusByHandleUseCase @@ -295,6 +297,11 @@ internal class ChatViewModelTest { private val getCacheFileUseCase = mock() private val recordAudioUseCase = mock() private val deleteFileUseCase = mock() + private val monitorLeaveChatUseCase = mock { + on { invoke() } doReturn emptyFlow() + } + private val leaveChatUseCase = mock() + @BeforeEach fun resetMocks() { @@ -357,6 +364,7 @@ internal class ChatViewModelTest { getCacheFileUseCase, recordAudioUseCase, deleteFileUseCase, + leaveChatUseCase ) whenever(savedStateHandle.get(Constants.CHAT_ID)).thenReturn(chatId) wheneverBlocking { isAnonymousModeUseCase() } doReturn false @@ -383,6 +391,7 @@ internal class ChatViewModelTest { wheneverBlocking { monitorJoiningChatUseCase(any()) } doReturn emptyFlow() wheneverBlocking { monitorLeavingChatUseCase(any()) } doReturn emptyFlow() whenever(monitorChatPendingChangesUseCase(any())) doReturn emptyFlow() + whenever(monitorLeaveChatUseCase()) doReturn emptyFlow() } private fun initTestClass() { @@ -460,6 +469,8 @@ internal class ChatViewModelTest { getCacheFileUseCase = getCacheFileUseCase, recordAudioUseCase = recordAudioUseCase, deleteFileUseCase = deleteFileUseCase, + leaveChatUseCase = leaveChatUseCase, + monitorLeaveChatUseCase = monitorLeaveChatUseCase ) } @@ -2891,6 +2902,25 @@ internal class ChatViewModelTest { } } + @Test + fun `test that leave chat call when monitorLeaveChatUseCase emit equals chat id`() = runTest { + val flow = MutableSharedFlow() + whenever(monitorLeaveChatUseCase()).thenReturn(flow) + initTestClass() + flow.emit(chatId) + verify(leaveChatUseCase).invoke(chatId) + } + + @Test + fun `test that leave chat doesn't call when monitorLeaveChatUseCase emit differ chat id`() = + runTest { + val flow = MutableSharedFlow() + whenever(monitorLeaveChatUseCase()).thenReturn(flow) + initTestClass() + flow.emit(345L) + verifyNoInteractions(leaveChatUseCase) + } + @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) inner class VoiceClipTests { From 2f96977bbee485a085934e9284972f7a24b5c0ab Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 21 Mar 2024 13:05:16 +0100 Subject: [PATCH 049/261] T15414589: failure to download multiple files from cloud drive --- .../voiceclip/VoiceClipMessageViewModel.kt | 3 - .../StartDownloadComponentViewModel.kt | 5 +- .../StartDownloadComponentViewModelTest.kt | 15 +- .../entity/transfer/MultiTransferEvent.kt | 61 ++------ .../StartChatUploadsWithWorkerUseCase.kt | 6 +- ...AbstractStartTransfersWithWorkerUseCase.kt | 8 +- .../shared/AbstractTransferNodesUseCase.kt | 133 +++++++++++------- .../message/SendChatAttachmentsUseCaseTest.kt | 5 +- .../StartChatUploadsWithWorkerUseCaseTest.kt | 14 +- .../downloads/DownloadNodesUseCaseTest.kt | 9 +- .../StartDownloadsWithWorkerUseCaseTest.kt | 21 ++- 11 files changed, 145 insertions(+), 135 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/voiceclip/VoiceClipMessageViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/voiceclip/VoiceClipMessageViewModel.kt index 796a9f739b..8821fe125a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/voiceclip/VoiceClipMessageViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/voiceclip/VoiceClipMessageViewModel.kt @@ -153,9 +153,6 @@ class VoiceClipMessageViewModel @Inject constructor( } } - is MultiTransferEvent.ScanningFoldersFinished -> { - } - is MultiTransferEvent.InsufficientSpace -> { updateDoesNotExists(msgId) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt index b9a1be8c2e..007e86f334 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt @@ -283,12 +283,11 @@ internal class StartDownloadComponentViewModel @Inject constructor( when (terminalEvent) { MultiTransferEvent.InsufficientSpace -> StartDownloadTransferEvent.Message.NotSufficientSpace else -> { - val finishedEvent = - (terminalEvent as? MultiTransferEvent.ScanningFoldersFinished) + val finishedEvent = (terminalEvent as? MultiTransferEvent.SingleTransferEvent) StartDownloadTransferEvent.FinishProcessing( exception = lastError?.takeIf { terminalEvent == null }, totalNodes = nodes.size, - totalFiles = finishedEvent?.scannedFiles ?: 0, + totalFiles = finishedEvent?.startedFiles ?: 0, totalAlreadyDownloaded = finishedEvent?.alreadyTransferred ?: 0, ) } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt index fb23005b33..6e2dbc1fd1 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt @@ -221,7 +221,9 @@ class StartDownloadComponentViewModelTest { commonStub() stubStartDownload(flow { delay(500) - emit(mock()) + emit(mock { + on { scanningFinished } doReturn true + }) }) underTest.startDownload(TransferTriggerEvent.StartDownloadNode(nodes)) Truth.assertThat(underTest.uiState.value.jobInProgressState) @@ -371,7 +373,9 @@ class StartDownloadComponentViewModelTest { private fun provideDownloadNodeParameters() = listOf( Arguments.of( - mock(), + mock { + on { scanningFinished } doReturn true + }, StartDownloadTransferEvent.FinishProcessing(null, 1, 0, 0), ), Arguments.of( @@ -404,7 +408,12 @@ class StartDownloadComponentViewModelTest { whenever(isConnectedToInternetUseCase()).thenReturn(true) whenever(totalFileSizeOfNodesUseCase(any())).thenReturn(1) whenever(shouldAskDownloadDestinationUseCase()).thenReturn(false) - stubStartDownload(flowOf(mock())) + stubStartDownload( + flowOf( + mock { + on { scanningFinished } doReturn true + }) + ) } private fun stubStartDownload(flow: Flow) { diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt index 4a45aeaaf8..dfe117f67c 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/transfer/MultiTransferEvent.kt @@ -19,47 +19,23 @@ sealed interface MultiTransferEvent { /** * Wraps a [TransferEvent] for a single node event - * @param transferEvent wrapped [TransferEvent] - * @param totalBytesTransferred the total amount of bytes already transferred in all involved transfers. - * @param totalBytesToTransfer the total amount of bytes to be transferred in all involved transfers. May be inaccurate since some nodes may not have been processed yet + * @property transferEvent wrapped [TransferEvent] + * @property totalBytesTransferred the total amount of bytes already transferred in all involved transfers. + * @property totalBytesToTransfer the total amount of bytes to be transferred in all involved transfers. May be inaccurate if [scanningFinished] is false since some nodes may not have been processed yet + * @property startedFiles the amount of files scanned for the transfer of the involved nodes + * @property alreadyTransferred the amount of already transferred files + * @property alreadyTransferredIds the ids of the nodes already transferred + * @property scanningFinished All transfers has been scanned by the sdk, starting from this event transfers can be retried by sdk if the app is closed */ data class SingleTransferEvent( val transferEvent: TransferEvent, val totalBytesTransferred: Long, val totalBytesToTransfer: Long, - ) : - MultiTransferEvent { - /** - * return true if this event represents a finish processing event (or already finished) - */ - val isFinishScanningEvent by lazy { - with(transferEvent) { - when { - this is TransferEvent.TransferUpdateEvent && - transfer.isFolderTransfer && transfer.stage == TransferStage.STAGE_TRANSFERRING_FILES -> { - true - } - - this is TransferEvent.TransferFinishEvent -> true - this is TransferEvent.TransferUpdateEvent && !transfer.isFolderTransfer -> true - else -> false - } - } - } - - /** - * This event indicates that the transfer was not done due to being already transferred. - */ - val isAlreadyTransferredEvent by lazy { - with(transferEvent.transfer) { - !isFolderTransfer && isAlreadyDownloaded - } - } - - /** - * This event is related to a file transfer, not a folder. - */ - val isFileTransferEvent by lazy { !transferEvent.transfer.isFolderTransfer } + val startedFiles: Int = 0, + val alreadyTransferred: Int = 0, + val alreadyTransferredIds: Set = emptySet(), + val scanningFinished: Boolean = false, + ) : MultiTransferEvent { /** * Returns true if the transfer finished with error. @@ -74,19 +50,6 @@ sealed interface MultiTransferEvent { val overallProgress = Progress(totalBytesTransferred, totalBytesToTransfer) } - /** - * All transfers has been scanned by the sdk, starting from this event transfers can be retried by sdk if the app is closed - * @property scannedFiles the amount of files scanned for the transfer of the involved nodes - * @property alreadyTransferred the amount of already transferred files - * @property alreadyTransferredIds the ids of the nodes already transferred - */ - data class ScanningFoldersFinished( - val scannedFiles: Int, - val alreadyTransferred: Int, - val alreadyTransferredIds: Set, - ) : - MultiTransferEvent - /** * Event to notify that the download cannot be done due to insufficient storage space in the destination path */ diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt index a6e5fb3b11..d81dd3c6dd 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt @@ -77,10 +77,10 @@ class StartChatUploadsWithWorkerUseCase @Inject constructor( UpdatePendingMessageTransferTagRequest(pendingMessageId, transferTag) ) } - //attach it if already uploaded - (event as? MultiTransferEvent.ScanningFoldersFinished) + //attach it if it's already uploaded + (event as? MultiTransferEvent.SingleTransferEvent) ?.alreadyTransferredIds - ?.firstOrNull() + ?.singleOrNull() ?.takeIf { it.longValue != -1L } ?.let { alreadyTransferredNodeId -> attachNodeWithPendingMessageUseCase( diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractStartTransfersWithWorkerUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractStartTransfersWithWorkerUseCase.kt index b1c7514995..f55ae020b4 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractStartTransfersWithWorkerUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractStartTransfersWithWorkerUseCase.kt @@ -25,17 +25,13 @@ abstract class AbstractStartTransfersWithWorkerUseCase( ) = emitAll(doTransfers() .filter { it !is MultiTransferEvent.SingleTransferEvent - || (it.isFinishScanningEvent) + || (it.scanningFinished) }.transformWhile { event -> val finished = - event is MultiTransferEvent.ScanningFoldersFinished || (event as? MultiTransferEvent.SingleTransferEvent)?.isFinishScanningEvent == true + (event as? MultiTransferEvent.SingleTransferEvent)?.scanningFinished == true //emitting a FinishProcessingTransfers can cause a terminal event in the collector (firstOrNull for instance), so we need to start the worker before emitting it if (finished) { startWorker() - if (event !is MultiTransferEvent.ScanningFoldersFinished) { - //this is just in case the event was lost for some reason and we are finishing by a SingleTransferEvent - emit(MultiTransferEvent.ScanningFoldersFinished(0, 0, emptySet())) - } } emit(event) return@transformWhile !finished diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt index 37681d7ca0..457251b254 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt @@ -11,7 +11,6 @@ import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onStart -import kotlinx.coroutines.flow.transform import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -46,8 +45,10 @@ abstract class AbstractTransferNodesUseCase( beforeStartTransfer: (suspend () -> Unit)?, doTransfer: (T) -> Flow, ): Flow { - val alreadyScanned = mutableSetOf() - val scannedFiles = mutableSetOf() + val alreadyScanned = + mutableSetOf() //to check if all [items] have been scanned (childs not needed here) + val filesStarted = + mutableSetOf() //to count the number of files that have been started (no folders but including children) val alreadyTransferredFiles = mutableSetOf() val alreadyTransferredNodeIds = mutableSetOf() val allIds = items.map(::generateIdFromItem) @@ -65,14 +66,55 @@ abstract class AbstractTransferNodesUseCase( } alreadyScanned.add(id) } - .collect { - totalBytesMap[it.transfer.tag] = it.transfer.totalBytes - transferredBytesMap[it.transfer.tag] = it.transfer.transferredBytes + .buffer(capacity = Channel.UNLIMITED) + .collect { transferEvent -> + totalBytesMap[transferEvent.transfer.tag] = + transferEvent.transfer.totalBytes + transferredBytesMap[transferEvent.transfer.tag] = + transferEvent.transfer.transferredBytes + + if (transferEvent is TransferEvent.TransferStartEvent) { + rootTags += transferEvent.transfer.tag + } + handleSDCardEventUseCase(transferEvent) + //update active transfers db + addOrUpdateActiveTransferUseCase(transferEvent) + + //keep track of file counters + if (transferEvent.isFileTransfer) { + val id = generateIdFromTransferEvent(transferEvent) + filesStarted.add(id) + if (transferEvent.isAlreadyTransferredEvent) { + alreadyTransferredFiles.add(id) + alreadyTransferredNodeIds.add(NodeId(transferEvent.transfer.nodeHandle)) + } + } + //check if is a single node scanning finish event + if (!scanningFinishedSend && transferEvent.isFinishScanningEvent) { + val id = generateIdFromTransferEvent(transferEvent) + if (!alreadyScanned.contains(id)) { + //this node is already scanned: save it and emit the event + alreadyScanned.add(id) + + //check if all nodes have been scanned + if (alreadyScanned.containsAll(allIds)) { + scanningFinishedSend = true + invalidateCancelTokenUseCase() //we need to avoid a future cancellation from now on + } + } + } + + + send( MultiTransferEvent.SingleTransferEvent( - it, - transferredBytes, - totalBytes + transferEvent = transferEvent, + totalBytesTransferred = transferredBytes, + totalBytesToTransfer = totalBytes, + startedFiles = filesStarted.size, + alreadyTransferred = alreadyTransferredFiles.size, + alreadyTransferredIds = alreadyTransferredNodeIds, + scanningFinished = scanningFinishedSend, ) ) } @@ -83,49 +125,7 @@ abstract class AbstractTransferNodesUseCase( .onStart { beforeStartTransfer?.invoke() } - .buffer(capacity = Channel.UNLIMITED) - .transform { event -> - if (event is MultiTransferEvent.SingleTransferEvent) { - if (event.transferEvent is TransferEvent.TransferStartEvent) { - rootTags += event.transferEvent.transfer.tag - } - handleSDCardEventUseCase(event.transferEvent) - //update active transfers db - addOrUpdateActiveTransferUseCase(event.transferEvent) - - //keep track of files counters - if (event.isFileTransferEvent) { - val id = generateIdFromTransferEvent(event.transferEvent) - scannedFiles.add(id) - if (event.isAlreadyTransferredEvent) { - alreadyTransferredFiles.add(id) - alreadyTransferredNodeIds.add(NodeId(event.transferEvent.transfer.nodeHandle)) - } - } - //check if is a single node scanning finish event - if (event.isFinishScanningEvent) { - val id = generateIdFromTransferEvent(event.transferEvent) - if (!alreadyScanned.contains(id)) { - //this node is already scanned: save it and emit the event - alreadyScanned.add(id) - - //check if all nodes have been scanned - if (!scanningFinishedSend && alreadyScanned.containsAll(allIds)) { - scanningFinishedSend = true - invalidateCancelTokenUseCase() //we need to avoid a future cancellation from now on - emit( - MultiTransferEvent.ScanningFoldersFinished( - scannedFiles.size, - alreadyTransferredFiles.size, - alreadyTransferredNodeIds, - ) - ) - } - } - } - } - emit(event) - }.onCompletion { + .onCompletion { runCatching { cancelCancelTokenUseCase() } }.cancellable() } @@ -164,4 +164,33 @@ abstract class AbstractTransferNodesUseCase( } } } + + /** + * This event indicates that the transfer was not done due to being already transferred. + */ + private val TransferEvent.isAlreadyTransferredEvent: Boolean + get() = with(this.transfer) { + !isFolderTransfer && isAlreadyDownloaded + } + + /** + * This event is related to a file transfer, not a folder. + */ + private val TransferEvent.isFileTransfer: Boolean + get() = !this.transfer.isFolderTransfer + + /** + * return true if this event represents a finish processing event (or already finished) + */ + private val TransferEvent.isFinishScanningEvent: Boolean + get() = when { + this is TransferEvent.TransferUpdateEvent && + transfer.isFolderTransfer && transfer.stage == mega.privacy.android.domain.entity.transfer.TransferStage.STAGE_TRANSFERRING_FILES -> { + true + } + + this is TransferEvent.TransferFinishEvent -> true + this is TransferEvent.TransferUpdateEvent && !transfer.isFolderTransfer -> true + else -> false + } } \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt index 6c324e98f0..a9ea5d2321 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt @@ -131,8 +131,11 @@ class SendChatAttachmentsUseCaseTest { } whenever(chatMessageRepository.savePendingMessage(any())) .thenReturn(pendingMessage) + val event = mock { + on { scanningFinished } doReturn true + } whenever(startChatUploadsWithWorkerUseCase(any(), any())).thenReturn( - flowOf(mock()) + flowOf(event) ) whenever(getFileForChatUploadUseCase(any())).thenReturn(file) } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt index af5de7e342..5793146e61 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt @@ -151,7 +151,9 @@ class StartChatUploadsWithWorkerUseCaseTest { fun `test that download worker is started when start download finish correctly`() = runTest { mockFlow( flowOf( - mock(), + mock { + on { scanningFinished } doReturn true + }, ) ) underTest(mockFile(), 1L).collect() @@ -163,7 +165,9 @@ class StartChatUploadsWithWorkerUseCaseTest { var workerStarted = false mockFlow( flow { - emit(mock()) + emit(mock { + on { scanningFinished } doReturn true + }) awaitCancellation() } ) @@ -240,8 +244,10 @@ class StartChatUploadsWithWorkerUseCaseTest { val file = mockFile() val pendingMessageId = 15L val nodeHandle = 12L - val event = MultiTransferEvent.ScanningFoldersFinished( - 1, 1, setOf(NodeId(nodeHandle)) + val event = MultiTransferEvent.SingleTransferEvent( + mock(), + 1L, 1L, + alreadyTransferredIds = setOf(NodeId(nodeHandle)) ) whenever( uploadFilesUseCase(any(), NodeId(any()), any(), any(), any()) diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt index 1787c2b0c8..fa4385889f 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/DownloadNodesUseCaseTest.kt @@ -10,7 +10,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.count import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @@ -37,7 +36,6 @@ import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCas import mega.privacy.android.domain.usecase.transfers.active.AddOrUpdateActiveTransferUseCase import mega.privacy.android.domain.usecase.transfers.sd.HandleSDCardEventUseCase import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -361,7 +359,6 @@ class DownloadNodesUseCaseTest { false ) .filterIsInstance() - .filter { it.isFinishScanningEvent } .test { nodeIds.forEach { assertThat(awaitItem().transferEvent.transfer.nodeHandle).isEqualTo(it.longValue) @@ -380,7 +377,7 @@ class DownloadNodesUseCaseTest { underTest(fileAndFolderNodes, DESTINATION_PATH_FOLDER, null, false).test { assertThat(cancelAndConsumeRemainingEvents().mapNotNull { event -> - (event as? Event.Item)?.value?.takeIf { it is MultiTransferEvent.ScanningFoldersFinished } + (event as? Event.Item)?.value?.takeIf { (it as? MultiTransferEvent.SingleTransferEvent)?.scanningFinished == true } }).hasSize(1) } } @@ -422,7 +419,7 @@ class DownloadNodesUseCaseTest { underTest(fileAndFolderNodes, DESTINATION_PATH_FOLDER, null, false).test { assertThat(cancelAndConsumeRemainingEvents().mapNotNull { event -> - (event as? Event.Item)?.value?.takeIf { it is MultiTransferEvent.ScanningFoldersFinished } + (event as? Event.Item)?.value?.takeIf { (it as? MultiTransferEvent.SingleTransferEvent)?.scanningFinished == true } }).hasSize(1) } } @@ -508,7 +505,7 @@ class DownloadNodesUseCaseTest { underTest(fileNodes, DESTINATION_PATH_FOLDER, null, false).test { assertThat(cancelAndConsumeRemainingEvents().mapNotNull { event -> - (event as? Event.Item)?.value?.takeIf { it is MultiTransferEvent.ScanningFoldersFinished } + (event as? Event.Item)?.value?.takeIf { (it as? MultiTransferEvent.SingleTransferEvent)?.scanningFinished == true } }).isEmpty() } } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt index 3c5d3a23a3..f7750c6971 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadsWithWorkerUseCaseTest.kt @@ -28,6 +28,7 @@ import org.junit.jupiter.api.TestInstance import org.mockito.AdditionalAnswers import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.reset @@ -106,7 +107,9 @@ class StartDownloadsWithWorkerUseCaseTest { @Test fun `test that single events are filtered out`() = runTest { - val mockFinish = mock() + val mockFinish = mock { + on { scanningFinished } doReturn true + } mockFlow( flowOf( mock(), @@ -121,7 +124,9 @@ class StartDownloadsWithWorkerUseCaseTest { @Test fun `test that flow completes when finish processing transfers is emitted`() = runTest { - val mockFinish = mock() + val mockFinish = mock { + on { scanningFinished } doReturn true + } mockFlow( flowOf( mockFinish, @@ -138,7 +143,9 @@ class StartDownloadsWithWorkerUseCaseTest { fun `test that download worker is started when start download finish correctly`() = runTest { mockFlow( flowOf( - mock(), + mock { + on { scanningFinished } doReturn true + } ) ) underTest(mockNodes(), DESTINATION_PATH_FOLDER, false).collect() @@ -150,7 +157,9 @@ class StartDownloadsWithWorkerUseCaseTest { var workerStarted = false mockFlow( flow { - emit(mock()) + emit(mock { + on { scanningFinished } doReturn true + }) awaitCancellation() } ) @@ -173,7 +182,9 @@ class StartDownloadsWithWorkerUseCaseTest { mockFlow( flow { delay(1000) - emit(mock()) + emit(mock { + on { scanningFinished } doReturn true + }) } ) val job = From ff0ed873a2e8a011401ffed0861f5d50ad191fa6 Mon Sep 17 00:00:00 2001 From: Yenel Date: Fri, 22 Mar 2024 12:12:59 +0100 Subject: [PATCH 050/261] MEET-3640 AND - History clearing setting is not updated --- .../activities/ManageChatHistoryActivity.kt | 22 ++++++ .../ManageChatHistoryViewModel.kt | 48 ++++++++++++ .../model/ManageChatHistoryUIState.kt | 10 +++ .../ManageChatHistoryViewModelTest.kt | 78 +++++++++++++++++++ .../MonitorChatRetentionTimeUpdateUseCase.kt | 24 ++++++ ...nitorChatRetentionTimeUpdateUseCaseTest.kt | 53 +++++++++++++ 6 files changed, 235 insertions(+) create mode 100644 app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModel.kt create mode 100644 app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/model/ManageChatHistoryUIState.kt create mode 100644 app/src/test/java/test/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModelTest.kt create mode 100644 domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCase.kt create mode 100644 domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCaseTest.kt diff --git a/app/src/main/java/mega/privacy/android/app/activities/ManageChatHistoryActivity.kt b/app/src/main/java/mega/privacy/android/app/activities/ManageChatHistoryActivity.kt index 2310ece589..5d47d26acb 100644 --- a/app/src/main/java/mega/privacy/android/app/activities/ManageChatHistoryActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/activities/ManageChatHistoryActivity.kt @@ -10,12 +10,16 @@ import android.view.View import android.widget.NumberPicker.OnScrollListener import android.widget.NumberPicker.OnValueChangeListener import androidx.activity.OnBackPressedCallback +import androidx.activity.viewModels +import androidx.lifecycle.Lifecycle import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.R +import mega.privacy.android.app.arch.extensions.collectFlow import mega.privacy.android.app.constants.BroadcastConstants import mega.privacy.android.app.constants.BroadcastConstants.ACTION_UPDATE_RETENTION_TIME import mega.privacy.android.app.databinding.ActivityManageChatHistoryBinding import mega.privacy.android.app.listeners.SetRetentionTimeListener +import mega.privacy.android.app.presentation.meeting.managechathistory.ManageChatHistoryViewModel import mega.privacy.android.app.utils.ChatUtil import mega.privacy.android.app.utils.ChatUtil.createHistoryRetentionAlertDialog import mega.privacy.android.app.utils.Constants.CHAT_ID @@ -52,6 +56,8 @@ class ManageChatHistoryActivity : PasscodeActivity(), View.OnClickListener { private const val MAXIMUM_VALUE_TEXT_PICKER = 4 } + internal val viewModel: ManageChatHistoryViewModel by viewModels() + private var chat: MegaChatRoom? = null private var chatId = MEGACHAT_INVALID_HANDLE private var contactHandle = INVALID_HANDLE @@ -111,6 +117,9 @@ class ManageChatHistoryActivity : PasscodeActivity(), View.OnClickListener { chatId = chat?.chatId!! } + monitorUpdates(chatId) + collectFlows() + registerReceiver( retentionTimeReceiver, IntentFilter(ACTION_UPDATE_RETENTION_TIME) @@ -165,6 +174,19 @@ class ManageChatHistoryActivity : PasscodeActivity(), View.OnClickListener { } } + private fun monitorUpdates(chatId: Long) { + viewModel.monitorChatRetentionTimeUpdate(chatId) + } + + private fun collectFlows() { + collectFlow(viewModel.state, Lifecycle.State.STARTED) { state -> + state.retentionTimeUpdate?.let { + updateRetentionTimeUI(it) + viewModel.onRetentionTimeUpdateConsumed() + } + } + } + private var onValueChangeListenerPickerNumber = OnValueChangeListener { _, oldValue, newValue -> updateTextPicker(oldValue, newValue) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModel.kt new file mode 100644 index 0000000000..3bc4fd5f15 --- /dev/null +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModel.kt @@ -0,0 +1,48 @@ +package mega.privacy.android.app.presentation.meeting.managechathistory + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import mega.privacy.android.app.presentation.meeting.managechathistory.model.ManageChatHistoryUIState +import mega.privacy.android.domain.usecase.chat.MonitorChatRetentionTimeUpdateUseCase +import javax.inject.Inject + +/** + * ViewModel to manage chat history. + * + * @property state The state of the UI. + */ +@HiltViewModel +class ManageChatHistoryViewModel @Inject constructor( + private val monitorChatRetentionTimeUpdateUseCase: MonitorChatRetentionTimeUpdateUseCase, +) : ViewModel() { + + private val _state = MutableStateFlow(ManageChatHistoryUIState()) + + val state: StateFlow = _state + + /** + * Monitor chat retention time update. + * + * @param chatId The chat id to monitor. + */ + fun monitorChatRetentionTimeUpdate(chatId: Long) { + viewModelScope.launch { + monitorChatRetentionTimeUpdateUseCase(chatId).collectLatest { retentionTime -> + _state.update { state -> state.copy(retentionTimeUpdate = retentionTime) } + } + } + } + + /** + * Update retention time. + */ + fun onRetentionTimeUpdateConsumed() { + _state.update { state -> state.copy(retentionTimeUpdate = null) } + } +} \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/model/ManageChatHistoryUIState.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/model/ManageChatHistoryUIState.kt new file mode 100644 index 0000000000..63a200f17f --- /dev/null +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/model/ManageChatHistoryUIState.kt @@ -0,0 +1,10 @@ +package mega.privacy.android.app.presentation.meeting.managechathistory.model + +/** + * UI state for manage chat history screen. + * + * @property retentionTimeUpdate The updated retention time. + */ +data class ManageChatHistoryUIState( + val retentionTimeUpdate: Long? = null, +) \ No newline at end of file diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModelTest.kt new file mode 100644 index 0000000000..0d2f7f6774 --- /dev/null +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/managechathistory/ManageChatHistoryViewModelTest.kt @@ -0,0 +1,78 @@ +package test.mega.privacy.android.app.presentation.meeting.managechathistory + +import app.cash.turbine.test +import com.google.common.truth.Truth +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import mega.privacy.android.app.presentation.meeting.managechathistory.ManageChatHistoryViewModel +import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension +import mega.privacy.android.domain.usecase.chat.MonitorChatRetentionTimeUpdateUseCase +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.extension.RegisterExtension +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.mockito.kotlin.wheneverBlocking +import test.mega.privacy.android.app.AnalyticsTestExtension + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class ManageChatHistoryViewModelTest { + + private lateinit var underTest: ManageChatHistoryViewModel + + private val monitorChatRetentionTimeUpdateUseCase = + mock() + + private val chatId = 123L + + companion object { + @OptIn(ExperimentalCoroutinesApi::class) + private val testDispatcher = UnconfinedTestDispatcher() + + @JvmField + @RegisterExtension + val extension = CoroutineMainDispatcherExtension(testDispatcher) + + @JvmField + @RegisterExtension + val analyticsTestExtension = AnalyticsTestExtension() + } + + @BeforeAll + fun setUp() { + underTest = ManageChatHistoryViewModel(monitorChatRetentionTimeUpdateUseCase) + } + + @BeforeEach + fun resetMocks() { + wheneverBlocking { monitorChatRetentionTimeUpdateUseCase(chatId) } doReturn emptyFlow() + } + + @Test + fun `test that retention time in state is updated when retention time update is received`() = + runTest { + val retentionTime = 100L + whenever(monitorChatRetentionTimeUpdateUseCase(chatId)).thenReturn(flowOf(retentionTime)) + underTest.monitorChatRetentionTimeUpdate(chatId) + underTest.state.test { + Truth.assertThat(awaitItem().retentionTimeUpdate).isEqualTo(retentionTime) + } + } + + @Test + fun `test that retention time in state is updated as null when update is consumed`() = runTest { + val retentionTime = 100L + whenever(monitorChatRetentionTimeUpdateUseCase(chatId)).thenReturn(flowOf(retentionTime)) + underTest.monitorChatRetentionTimeUpdate(chatId) + underTest.onRetentionTimeUpdateConsumed() + underTest.state.test { + Truth.assertThat(awaitItem().retentionTimeUpdate).isNull() + } + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCase.kt new file mode 100644 index 0000000000..3c4b201d09 --- /dev/null +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCase.kt @@ -0,0 +1,24 @@ +package mega.privacy.android.domain.usecase.chat + +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import mega.privacy.android.domain.entity.chat.ChatRoomChange +import mega.privacy.android.domain.repository.ChatRepository +import javax.inject.Inject + +/** + * Use case for monitoring chat retention time update. + */ +class MonitorChatRetentionTimeUpdateUseCase @Inject constructor( + private val chatRepository: ChatRepository, +) { + + /** + * Invoke + * + * @param chatId The chat id to monitor + */ + operator fun invoke(chatId: Long) = chatRepository.monitorChatRoomUpdates(chatId) + .filter { it.hasChanged(ChatRoomChange.RetentionTime) } + .map { it.retentionTime } +} \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCaseTest.kt new file mode 100644 index 0000000000..28a64a6f05 --- /dev/null +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/MonitorChatRetentionTimeUpdateUseCaseTest.kt @@ -0,0 +1,53 @@ +package mega.privacy.android.domain.usecase.chat + +import app.cash.turbine.test +import com.google.common.truth.Truth +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import mega.privacy.android.domain.entity.chat.ChatRoom +import mega.privacy.android.domain.entity.chat.ChatRoomChange +import mega.privacy.android.domain.repository.ChatRepository +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.mockito.Mockito.reset +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class MonitorChatRetentionTimeUpdateUseCaseTest { + + private lateinit var underTest: MonitorChatRetentionTimeUpdateUseCase + + private val chatRepository = mock() + + @BeforeAll + fun setUp() { + underTest = MonitorChatRetentionTimeUpdateUseCase(chatRepository) + } + + @BeforeEach + fun resetMocks() { + reset(chatRepository) + } + + @Test + fun `test that monitor chat retention time update returns retention time`() = runTest { + val chatId = 123L + val retentionTime = 100L + val chatUpdate = mock { + on { hasChanged(ChatRoomChange.RetentionTime) }.thenReturn(true) + on { this.retentionTime }.thenReturn(retentionTime) + } + whenever(chatRepository.monitorChatRoomUpdates(chatId)).thenReturn( + flowOf(chatUpdate) + ) + + underTest(chatId).test { + val actual = awaitItem() + awaitComplete() + Truth.assertThat(actual).isEqualTo(retentionTime) + } + } +} \ No newline at end of file From 95aec63ee857516aac9b4f8ea0e59393d8c2b494 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Mon, 25 Mar 2024 08:59:03 +1300 Subject: [PATCH 051/261] T15408267 - The "My Chat Files" folder" is duplicated. --- .../repository/FileSystemRepositoryImpl.kt | 1 + .../message/SendChatAttachmentsUseCase.kt | 5 ++- .../retry/RetryPendingMessageUseCase.kt | 8 ++++- .../GetMyChatsFilesFolderIdUseCase.kt | 6 ++-- .../StartChatUploadsWithWorkerUseCase.kt | 5 +-- .../message/SendChatAttachmentsUseCaseTest.kt | 36 ++++++++++++++++--- .../retry/RetryPendingMessageUseCaseTest.kt | 15 ++++++-- .../GetMyChatsFilesFolderIdUseCaseTest.kt | 36 ++++++++++++------- .../StartChatUploadsWithWorkerUseCaseTest.kt | 31 +++++++--------- 9 files changed, 99 insertions(+), 44 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt index e1cc1b0c8d..3b9e3f920e 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt @@ -219,6 +219,7 @@ internal class FileSystemRepositoryImpl @Inject constructor( override suspend fun setMyChatFilesFolder(nodeHandle: Long) = withContext(ioDispatcher) { suspendCancellableCoroutine { continuation -> val listener = continuation.getRequestListener("setMyChatFilesFolder") { + myChatsFilesFolderIdFlow.value = NodeId(nodeHandle) chatFilesFolderUserAttributeMapper(it.megaStringMap)?.let { value -> megaApiGateway.base64ToHandle(value) .takeIf { handle -> handle != megaApiGateway.getInvalidHandle() } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCase.kt index 0608609037..81d7d7204e 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCase.kt @@ -9,6 +9,7 @@ import mega.privacy.android.domain.entity.chat.messages.pending.SavePendingMessa import mega.privacy.android.domain.repository.chat.ChatMessageRepository import mega.privacy.android.domain.usecase.GetDeviceCurrentTimeUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.GetFileForChatUploadUseCase +import mega.privacy.android.domain.usecase.transfers.chatuploads.GetMyChatsFilesFolderIdUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.StartChatUploadsWithWorkerUseCase import javax.inject.Inject @@ -20,6 +21,7 @@ class SendChatAttachmentsUseCase @Inject constructor( private val getFileForChatUploadUseCase: GetFileForChatUploadUseCase, private val chatMessageRepository: ChatMessageRepository, private val deviceCurrentTimeUseCase: GetDeviceCurrentTimeUseCase, + private val getMyChatsFilesFolderIdUseCase: GetMyChatsFilesFolderIdUseCase, ) { /** * Invoke @@ -34,6 +36,7 @@ class SendChatAttachmentsUseCase @Inject constructor( isVoiceClip: Boolean = false, ) = flow { + val chatFolderId = getMyChatsFilesFolderIdUseCase() emitAll( //each file is sent as a single message in parallel urisWithNames.mapKeys { @@ -55,7 +58,7 @@ class SendChatAttachmentsUseCase @Inject constructor( transferTag = -1, ) ).id - startChatUploadsWithWorkerUseCase(file, pendingMessageId) + startChatUploadsWithWorkerUseCase(file, pendingMessageId, chatFolderId) } }.merge() ) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCase.kt index 591254a3dc..a6dcb8f39e 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCase.kt @@ -5,6 +5,7 @@ import mega.privacy.android.domain.entity.chat.PendingMessageState import mega.privacy.android.domain.entity.chat.messages.PendingAttachmentMessage import mega.privacy.android.domain.entity.chat.messages.TypedMessage import mega.privacy.android.domain.usecase.chat.message.AttachNodeWithPendingMessageUseCase +import mega.privacy.android.domain.usecase.transfers.chatuploads.GetMyChatsFilesFolderIdUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.StartChatUploadsWithWorkerUseCase import javax.inject.Inject @@ -14,6 +15,7 @@ import javax.inject.Inject class RetryPendingMessageUseCase @Inject constructor( private val startChatUploadsWithWorkerUseCase: StartChatUploadsWithWorkerUseCase, private val attachNodeWithPendingMessageUseCase: AttachNodeWithPendingMessageUseCase, + private val getMyChatsFilesFolderIdUseCase: GetMyChatsFilesFolderIdUseCase, ) : RetryMessageUseCase() { override fun canRetryMessage(message: TypedMessage): Boolean = message is PendingAttachmentMessage @@ -23,7 +25,11 @@ class RetryPendingMessageUseCase @Inject constructor( when (message.state) { PendingMessageState.ERROR_UPLOADING -> { message.file?.let { - startChatUploadsWithWorkerUseCase(it, message.msgId).collect() + startChatUploadsWithWorkerUseCase( + file = it, + pendingMessageId = message.msgId, + chatFilesFolderId = getMyChatsFilesFolderIdUseCase() + ).collect() } ?: throw IllegalArgumentException("Only messages with file can be retried when the state is ERROR_UPLOADING") } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCase.kt index d56c9c2bbe..ff1efc2bd2 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCase.kt @@ -3,8 +3,8 @@ package mega.privacy.android.domain.usecase.transfers.chatuploads import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.repository.ChatRepository import mega.privacy.android.domain.repository.FileSystemRepository -import mega.privacy.android.domain.repository.NodeRepository import mega.privacy.android.domain.usecase.node.CreateFolderNodeUseCase +import mega.privacy.android.domain.usecase.node.IsNodeInRubbishOrDeletedUseCase import javax.inject.Inject /** @@ -13,8 +13,8 @@ import javax.inject.Inject class GetMyChatsFilesFolderIdUseCase @Inject constructor( private val createFolderNodeUseCase: CreateFolderNodeUseCase, private val fileSystemRepository: FileSystemRepository, - private val nodeRepository: NodeRepository, private val chatRepository: ChatRepository, + private val isNodeInRubbishOrDeletedUseCase: IsNodeInRubbishOrDeletedUseCase, ) { /** @@ -22,7 +22,7 @@ class GetMyChatsFilesFolderIdUseCase @Inject constructor( */ suspend operator fun invoke(): NodeId { val nodeId = fileSystemRepository.getMyChatsFilesFolderId() - return if (nodeId == null || nodeRepository.getNodeById(nodeId) == null) { + return if (nodeId == null || isNodeInRubbishOrDeletedUseCase(nodeId.longValue)) { val handle = fileSystemRepository.setMyChatFilesFolder( createFolderNodeUseCase(chatRepository.getDefaultChatFolderName()).longValue diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt index d81dd3c6dd..47c0d832b2 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCase.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach import mega.privacy.android.domain.entity.chat.messages.pending.UpdatePendingMessageTransferTagRequest +import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.transfer.MultiTransferEvent import mega.privacy.android.domain.entity.transfer.TransferAppData import mega.privacy.android.domain.entity.transfer.TransferEvent @@ -29,7 +30,6 @@ import kotlin.coroutines.coroutineContext */ class StartChatUploadsWithWorkerUseCase @Inject constructor( private val uploadFilesUseCase: UploadFilesUseCase, - private val getMyChatsFilesFolderIdUseCase: GetMyChatsFilesFolderIdUseCase, private val startChatUploadsWorkerUseCase: StartChatUploadsWorkerUseCase, private val isChatUploadsWorkerStartedUseCase: IsChatUploadsWorkerStartedUseCase, private val compressFileForChatUseCase: CompressFileForChatUseCase, @@ -45,10 +45,12 @@ class StartChatUploadsWithWorkerUseCase @Inject constructor( * * @param file the file that will be uploaded to chats folder in the cloud drive. If it's a folder will be filtered out because folders are not allowed as chat uploads * @param pendingMessageId the message id to be included in the app data, so the ChatUploadsWorker can associate the files to the corresponding message + * @param chatFilesFolderId the id of the folder where the files will be uploaded */ operator fun invoke( file: File, pendingMessageId: Long, + chatFilesFolderId: NodeId, ): Flow = flow { if (!fileSystemRepository.isFilePath(file.path)) { emit( @@ -64,7 +66,6 @@ class StartChatUploadsWithWorkerUseCase @Inject constructor( to chatMessageRepository.getPendingMessage(pendingMessageId)?.name ) coroutineContext.ensureActive() - val chatFilesFolderId = getMyChatsFilesFolderIdUseCase() val appData = TransferAppData.ChatUpload(pendingMessageId) startTransfersAndWorker( doTransfers = { diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt index a9ea5d2321..7883bce274 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/SendChatAttachmentsUseCaseTest.kt @@ -4,10 +4,12 @@ import app.cash.turbine.test import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.chat.PendingMessage +import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.transfer.MultiTransferEvent import mega.privacy.android.domain.repository.chat.ChatMessageRepository import mega.privacy.android.domain.usecase.GetDeviceCurrentTimeUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.GetFileForChatUploadUseCase +import mega.privacy.android.domain.usecase.transfers.chatuploads.GetMyChatsFilesFolderIdUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.StartChatUploadsWithWorkerUseCase import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach @@ -32,6 +34,7 @@ class SendChatAttachmentsUseCaseTest { private val getFileForChatUploadUseCase = mock() private val chatMessageRepository = mock() private val deviceCurrentTimeUseCase = mock() + private val getMyChatsFilesFolderIdUseCase = mock() private val file = mockFile() @@ -43,6 +46,7 @@ class SendChatAttachmentsUseCaseTest { getFileForChatUploadUseCase, chatMessageRepository, deviceCurrentTimeUseCase, + getMyChatsFilesFolderIdUseCase, ) } @@ -53,6 +57,7 @@ class SendChatAttachmentsUseCaseTest { getFileForChatUploadUseCase, chatMessageRepository, deviceCurrentTimeUseCase, + getMyChatsFilesFolderIdUseCase, ) } @@ -64,7 +69,7 @@ class SendChatAttachmentsUseCaseTest { underTest(chatId, uris).test { cancelAndIgnoreRemainingEvents() } - verify(startChatUploadsWithWorkerUseCase)(eq(file), any()) + verify(startChatUploadsWithWorkerUseCase)(eq(file), any(), NodeId(any())) } @Test @@ -79,7 +84,7 @@ class SendChatAttachmentsUseCaseTest { underTest(chatId, uris).test { cancelAndIgnoreRemainingEvents() } - verify(startChatUploadsWithWorkerUseCase, times(uris.size))(any(), any()) + verify(startChatUploadsWithWorkerUseCase, times(uris.size))(any(), any(), NodeId(any())) } @Test @@ -91,7 +96,7 @@ class SendChatAttachmentsUseCaseTest { underTest(chatId, uris).test { cancelAndIgnoreRemainingEvents() } - verify(startChatUploadsWithWorkerUseCase)(eq(file), eq(pendingMsgId)) + verify(startChatUploadsWithWorkerUseCase)(eq(file), eq(pendingMsgId), NodeId(any())) } @Test @@ -125,7 +130,27 @@ class SendChatAttachmentsUseCaseTest { }) } - private suspend fun commonStub(pendingMsgId: Long = 1L) { + @Test + fun `test that getMyChatsFilesFolderIdUseCase is called only once for multiple files`() = + runTest { + val chatId = 123L + val myChatFolderId = NodeId(154L) + val uris = List(3) { "file$it" }.associateWith { null } + commonStub(myChatFolderId = myChatFolderId) + uris.keys.forEach { + val file = mockFile() + whenever(getFileForChatUploadUseCase(it)).thenReturn(file) + } + underTest(chatId, uris).test { + cancelAndConsumeRemainingEvents() + + verify(startChatUploadsWithWorkerUseCase, times(uris.size)) + .invoke(any(), any(), NodeId(eq(myChatFolderId.longValue))) + verify(getMyChatsFilesFolderIdUseCase).invoke() + } + } + + private suspend fun commonStub(pendingMsgId: Long = 1L, myChatFolderId: NodeId = NodeId(-1)) { val pendingMessage = mock { on { id } doReturn pendingMsgId } @@ -134,10 +159,11 @@ class SendChatAttachmentsUseCaseTest { val event = mock { on { scanningFinished } doReturn true } - whenever(startChatUploadsWithWorkerUseCase(any(), any())).thenReturn( + whenever(startChatUploadsWithWorkerUseCase(any(), any(), NodeId(any()))).thenReturn( flowOf(event) ) whenever(getFileForChatUploadUseCase(any())).thenReturn(file) + whenever(getMyChatsFilesFolderIdUseCase()).thenReturn(myChatFolderId) } private fun mockFile() = mock { diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCaseTest.kt index 54bd773829..b30b411519 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/retry/RetryPendingMessageUseCaseTest.kt @@ -9,6 +9,7 @@ import mega.privacy.android.domain.entity.chat.messages.PendingFileAttachmentMes import mega.privacy.android.domain.entity.chat.messages.PendingVoiceClipMessage import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.usecase.chat.message.AttachNodeWithPendingMessageUseCase +import mega.privacy.android.domain.usecase.transfers.chatuploads.GetMyChatsFilesFolderIdUseCase import mega.privacy.android.domain.usecase.transfers.chatuploads.StartChatUploadsWithWorkerUseCase import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach @@ -31,6 +32,7 @@ class RetryPendingMessageUseCaseTest { private val startChatUploadsWithWorkerUseCase = mock() private val attachNodeWithPendingMessageUseCase = mock() + private val getMyChatsFilesFolderIdUseCase = mock() @BeforeAll @@ -38,6 +40,7 @@ class RetryPendingMessageUseCaseTest { underTest = RetryPendingMessageUseCase( startChatUploadsWithWorkerUseCase, attachNodeWithPendingMessageUseCase, + getMyChatsFilesFolderIdUseCase, ) } @@ -89,16 +92,24 @@ class RetryPendingMessageUseCaseTest { runTest { val file = mock() val msgId = 15L + val myChatFilesFolderId = NodeId(11L) val message = mock { on { it.state } doReturn PendingMessageState.ERROR_UPLOADING on { it.file } doReturn file on { it.msgId } doReturn msgId } - whenever(startChatUploadsWithWorkerUseCase(any(), any())) doReturn emptyFlow() + whenever( + startChatUploadsWithWorkerUseCase( + any(), + any(), + NodeId(any()) + ) + ) doReturn emptyFlow() + whenever(getMyChatsFilesFolderIdUseCase()) doReturn myChatFilesFolderId underTest(message) - verify(startChatUploadsWithWorkerUseCase).invoke(file, msgId) + verify(startChatUploadsWithWorkerUseCase).invoke(file, msgId, myChatFilesFolderId) } @Test diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCaseTest.kt index e31ff42b71..94ad7eaa01 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/GetMyChatsFilesFolderIdUseCaseTest.kt @@ -5,8 +5,8 @@ import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.repository.ChatRepository import mega.privacy.android.domain.repository.FileSystemRepository -import mega.privacy.android.domain.repository.NodeRepository import mega.privacy.android.domain.usecase.node.CreateFolderNodeUseCase +import mega.privacy.android.domain.usecase.node.IsNodeInRubbishOrDeletedUseCase import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -18,24 +18,23 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.reset import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -import java.lang.IllegalArgumentException @TestInstance(TestInstance.Lifecycle.PER_CLASS) class GetMyChatsFilesFolderIdUseCaseTest { private lateinit var underTest: GetMyChatsFilesFolderIdUseCase private val fileSystemRepository = mock() - private val nodeRepository = mock() private val chatRepository = mock() private val createFolderNodeUseCase = mock() + private val isNodeInRubbishOrDeletedUseCase = mock() @BeforeAll fun setup() { underTest = GetMyChatsFilesFolderIdUseCase( createFolderNodeUseCase, fileSystemRepository, - nodeRepository, chatRepository, + isNodeInRubbishOrDeletedUseCase, ) } @@ -43,19 +42,20 @@ class GetMyChatsFilesFolderIdUseCaseTest { fun resetMocks() = reset( fileSystemRepository, - nodeRepository, chatRepository, createFolderNodeUseCase, + isNodeInRubbishOrDeletedUseCase, ) @Test - fun `test that repository folder id is returned when the folder exists`() = runTest { - val folderId = NodeId(11L) - whenever(fileSystemRepository.getMyChatsFilesFolderId()).thenReturn(folderId) - whenever(nodeRepository.getNodeById(folderId)).thenReturn(mock()) - val actual = underTest() - assertThat(actual).isEqualTo(folderId) - } + fun `test that repository folder id is returned when the folder exists and is not in the rubbish bin`() = + runTest { + val folderId = NodeId(11L) + whenever(fileSystemRepository.getMyChatsFilesFolderId()).thenReturn(folderId) + whenever(isNodeInRubbishOrDeletedUseCase(folderId.longValue)).thenReturn(false) + val actual = underTest() + assertThat(actual).isEqualTo(folderId) + } @Test fun `test that created folder is returned when existing folder id is null`() = runTest { @@ -66,6 +66,18 @@ class GetMyChatsFilesFolderIdUseCaseTest { assertThat(actual).isEqualTo(folderId) } + @Test + fun `test that created folder is returned when existing folder id is in rubbish bin`() = + runTest { + val handle = 11L + val folderId = NodeId(handle) + whenever(fileSystemRepository.getMyChatsFilesFolderId()).thenReturn(folderId) + whenever(isNodeInRubbishOrDeletedUseCase(folderId.longValue)).thenReturn(true) + stubFolderCreation() + val actual = underTest() + assertThat(actual).isEqualTo(folderId) + } + @Test fun `test that folder is created with the proper name`() = runTest { val folderName = "folder name" diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt index 5793146e61..947b90e132 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/chatuploads/StartChatUploadsWithWorkerUseCaseTest.kt @@ -44,7 +44,6 @@ class StartChatUploadsWithWorkerUseCaseTest { private lateinit var underTest: StartChatUploadsWithWorkerUseCase private val uploadFilesUseCase = mock() - private val getMyChatsFilesFolderIdUseCase = mock() private val cancelCancelTokenUseCase = mock() private val startChatUploadsWorkerUseCase = mock() private val isChatUploadsWorkerStartedUseCase = mock() @@ -58,7 +57,6 @@ class StartChatUploadsWithWorkerUseCaseTest { fun setup() { underTest = StartChatUploadsWithWorkerUseCase( uploadFilesUseCase, - getMyChatsFilesFolderIdUseCase, startChatUploadsWorkerUseCase, isChatUploadsWorkerStartedUseCase, compressFileForChatUseCase, @@ -74,7 +72,6 @@ class StartChatUploadsWithWorkerUseCaseTest { fun resetMocks() = runTest { reset( uploadFilesUseCase, - getMyChatsFilesFolderIdUseCase, startChatUploadsWorkerUseCase, isChatUploadsWorkerStartedUseCase, compressFileForChatUseCase, @@ -88,14 +85,13 @@ class StartChatUploadsWithWorkerUseCaseTest { } private suspend fun commonStub() { - whenever(getMyChatsFilesFolderIdUseCase()) doReturn NodeId(1L) whenever(fileSystemRepository.isFilePath(any())) doReturn true } @Test fun `test that the file is send to upload files use case`() = runTest { val file = mockFile() - underTest(file, 1L).test { + underTest(file, 1L, NodeId(11L)).test { verify(uploadFilesUseCase).invoke( eq(mapOf(file to null)), NodeId(any()), any(), any(), any() ) @@ -107,7 +103,7 @@ class StartChatUploadsWithWorkerUseCaseTest { fun `test that a folder emits TransferNotStarted event`() = runTest { val folder = mockFile() whenever(fileSystemRepository.isFilePath(any())) doReturn false - underTest(folder, 1L).test { + underTest(folder, 1L, NodeId(11L)).test { val notStartedEvents = cancelAndConsumeRemainingEvents() .filterIsInstance>() .map { it.value } @@ -117,10 +113,9 @@ class StartChatUploadsWithWorkerUseCaseTest { } @Test - fun `test that getMyChatsFilesFolderUseCase result is set as destination`() = runTest { - val chatFilesFolderId = NodeId(2L) - whenever(getMyChatsFilesFolderIdUseCase()).thenReturn(chatFilesFolderId) - underTest(mockFile(), 1L).test { + fun `test that chatFilesFolderId is used as destination`() = runTest { + val chatFilesFolderId = NodeId(11L) + underTest(mockFile(), 1L, chatFilesFolderId).test { verify(uploadFilesUseCase).invoke( any(), NodeId(eq(chatFilesFolderId.longValue)), @@ -128,14 +123,14 @@ class StartChatUploadsWithWorkerUseCaseTest { any(), any() ) - cancelAndIgnoreRemainingEvents() + cancelAndConsumeRemainingEvents() } } @Test fun `test that chat upload app data is set`() = runTest { val pendingMessageId = 1L - underTest(mockFile(), pendingMessageId).test { + underTest(mockFile(), pendingMessageId, NodeId(11L)).test { verify(uploadFilesUseCase).invoke( any(), NodeId(any()), @@ -156,7 +151,7 @@ class StartChatUploadsWithWorkerUseCaseTest { }, ) ) - underTest(mockFile(), 1L).collect() + underTest(mockFile(), 1L, NodeId(11L)).collect() verify(startChatUploadsWorkerUseCase).invoke() } @@ -177,7 +172,7 @@ class StartChatUploadsWithWorkerUseCaseTest { ) { workerStarted = true }) - underTest(mockFile(), 1L).test { + underTest(mockFile(), 1L, NodeId(11L)).test { awaitItem() awaitComplete() assertThat(workerStarted).isTrue() @@ -191,7 +186,7 @@ class StartChatUploadsWithWorkerUseCaseTest { val file = mockFile() val compressed = mockFile() whenever(compressFileForChatUseCase(file)).thenReturn(compressed) - underTest(file, 1L).test { + underTest(file, 1L, NodeId(11L)).test { verify(uploadFilesUseCase) .invoke(eq(mapOf(compressed to null)), NodeId(any()), any(), any(), any()) cancelAndIgnoreRemainingEvents() @@ -207,7 +202,7 @@ class StartChatUploadsWithWorkerUseCaseTest { on { name } doReturn pendingMessageName } whenever(chatMessageRepository.getPendingMessage(1L)) doReturn pendingMessage - underTest(file, pendingMessageId).test { + underTest(file, pendingMessageId, NodeId(11L)).test { verify(uploadFilesUseCase).invoke( eq(mapOf(file to pendingMessageName)), NodeId(any()), any(), any(), any() ) @@ -230,7 +225,7 @@ class StartChatUploadsWithWorkerUseCaseTest { uploadFilesUseCase(any(), NodeId(any()), any(), any(), any()) ) doReturn flowOf(event) - underTest(file, pendingMessageId).test { + underTest(file, pendingMessageId, NodeId(11L)).test { verify(updatePendingMessageUseCase).invoke( UpdatePendingMessageTransferTagRequest(pendingMessageId, transferTag) ) @@ -253,7 +248,7 @@ class StartChatUploadsWithWorkerUseCaseTest { uploadFilesUseCase(any(), NodeId(any()), any(), any(), any()) ) doReturn flowOf(event) - underTest(file, pendingMessageId).test { + underTest(file, pendingMessageId, NodeId(11L)).test { verify(attachNodeWithPendingMessageUseCase).invoke( pendingMessageId, NodeId(nodeHandle) From bf196feaf22b238aac3c815fd9a412b1d2523a7e Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Sat, 23 Mar 2024 05:27:20 +1300 Subject: [PATCH 052/261] AND-18489: Chat room keeps loading forever when creating new group chat (cherry picked from commit 3afb79da442edd361995cd8dae6347f8a443e98b) --- .../paging/PagedChatMessageRemoteMediator.kt | 7 ++++++- .../PagedChatMessageRemoteMediatorTest.kt | 14 ++++++++++++++ .../chat/message/GetMessageListUseCase.kt | 5 +++++ .../chat/message/GetMessageListUseCaseTest.kt | 18 ++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediator.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediator.kt index 7d30d2e652..220552617e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediator.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediator.kt @@ -7,6 +7,7 @@ import androidx.paging.RemoteMediator import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.isActive import mega.privacy.android.domain.entity.chat.ChatHistoryLoadStatus import mega.privacy.android.domain.entity.chat.ChatMessage @@ -70,7 +71,11 @@ class PagedChatMessageRemoteMediator @AssistedInject constructor( MediatorResult.Success(endOfPaginationReached = response.loadResponse == ChatHistoryLoadStatus.NONE) } catch (e: Exception) { - Timber.e(e, "Paging mediator load: error") + if (e is TimeoutCancellationException) { + Timber.d("Paging mediator load: timeout") + } else { + Timber.e(e, "Paging mediator load: error") + } MediatorResult.Error(e) } } diff --git a/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediatorTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediatorTest.kt index 6c21519bb0..49d2d6448a 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediatorTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/model/paging/PagedChatMessageRemoteMediatorTest.kt @@ -6,6 +6,7 @@ import androidx.paging.PagingConfig import androidx.paging.PagingState import androidx.paging.RemoteMediator import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.chat.ChatHistoryLoadStatus @@ -24,6 +25,7 @@ import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.stub import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever @OptIn(ExperimentalPagingApi::class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -165,4 +167,16 @@ class PagedChatMessageRemoteMediatorTest { assertThat((firstResult as? RemoteMediator.MediatorResult.Success)?.endOfPaginationReached).isTrue() } + @Test + internal fun `test that timeout cancel exception returns when fetch message throw exception`() = + runTest { + val exception = mock() + whenever(fetchMessages(any(), any())).thenAnswer { throw exception } + + val result = underTest.load(LoadType.APPEND, state) + + assertThat(result).isInstanceOf(RemoteMediator.MediatorResult.Error::class.java) + assertThat((result as RemoteMediator.MediatorResult.Error).throwable) + .isInstanceOf(TimeoutCancellationException::class.java) + } } \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCase.kt index 357aa26d0b..c7f0de8ed5 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCase.kt @@ -1,14 +1,17 @@ package mega.privacy.android.domain.usecase.chat.message +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.take import kotlinx.coroutines.flow.takeWhile +import kotlinx.coroutines.flow.timeout import kotlinx.coroutines.flow.toList import mega.privacy.android.domain.entity.chat.ChatMessage import mega.privacy.android.domain.entity.chat.ChatMessageType import javax.inject.Inject +import kotlin.time.Duration.Companion.seconds /** * Get message list use case @@ -20,8 +23,10 @@ class GetMessageListUseCase @Inject constructor() { * * @param messageFlow */ + @OptIn(FlowPreview::class) suspend operator fun invoke(messageFlow: Flow) = messageFlow + .timeout(5.seconds) .takeWhile { it != null } .take(32) .filterNotNull() diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCaseTest.kt index 7367d442ce..66d514d749 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/chat/message/GetMessageListUseCaseTest.kt @@ -1,14 +1,18 @@ package mega.privacy.android.domain.usecase.chat.message import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.chat.ChatMessage import mega.privacy.android.domain.entity.chat.ChatMessageType import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.mockito.kotlin.mock +import kotlin.time.Duration.Companion.seconds class GetMessageListUseCaseTest { @@ -128,4 +132,18 @@ class GetMessageListUseCaseTest { assertThat(actual).isEmpty() } + @Test + internal fun `test that timeout exception is thrown when flow takes too long`() = runTest { + val flow = flow { + delay(6.seconds) // delay is more than the timeout duration + emit(mock()) + awaitCancellation() + } + + initUseCase() + + assertThrows { + underTest(flow) + } + } } \ No newline at end of file From 7d304db3be77edcc21a5bc40b294b9cdd16b7be3 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 25 Mar 2024 07:44:00 +0700 Subject: [PATCH 053/261] AND-18490: Create Image content uri for android below Q (cherry picked from commit 070aa35b50f1e74521ea95bdae3379eb0f8dfc74) --- .../mega/privacy/android/data/facade/FileFacade.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt index af23e45a4d..0485c18cf8 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt @@ -319,10 +319,13 @@ class FileFacade @Inject constructor( val contentValues = ContentValues().apply { put(MediaStore.Images.Media.DISPLAY_NAME, fileName) put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") - put( - MediaStore.Images.Media.RELATIVE_PATH, - "${Environment.DIRECTORY_PICTURES}/$PHOTO_DIR" - ) + // use default location for below Android Q + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { + put( + MediaStore.Images.Media.RELATIVE_PATH, + "${Environment.DIRECTORY_PICTURES}/$PHOTO_DIR" + ) + } } val contentResolver = context.contentResolver From a879c62fec576f2ffa1344c0fe5de0499c6b573a Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Mon, 25 Mar 2024 11:03:57 +0600 Subject: [PATCH 054/261] MEET-3610: Fix call banner failed test cases --- .../android/app/meeting/fragments/InMeetingFragment.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt index 4b99b2cbc6..c4806c4c7c 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt @@ -682,6 +682,7 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn binding.hostLeaveCallDialogComposeView.apply { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { + val sharedState by sharedModel.state.collectAsStateWithLifecycle() val state by inMeetingViewModel.state.collectAsStateWithLifecycle() MegaAppTheme(isDark = true) { @@ -694,7 +695,7 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn onEndForAllClick = inMeetingViewModel::endCallForAll, onDismiss = inMeetingViewModel::hideBottomPanels ) - if (state.showMeetingEndWarningDialog) { + if (sharedState.isCallUnlimitedProPlanFeatureFlagEnabled && state.showMeetingEndWarningDialog) { MegaAlertDialog( title = pluralStringResource( R.plurals.meetings_in_call_warning_dialog_title, @@ -1138,7 +1139,7 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn endMeetingAsModeratorDialog?.dismissAllowingStateLoss() endMeetingAsModeratorDialog = null } - if (state.minutesToEndMeeting != null) { + if (sharedModel.state.value.isCallUnlimitedProPlanFeatureFlagEnabled && state.minutesToEndMeeting != null) { callBanner?.apply { isVisible = true text = getString( @@ -1150,8 +1151,6 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn ) ) } - } else { - callBanner?.isVisible = false } } From 385a4b4ea37babea5d55249ff4ffbfaf677187ed Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 21 Mar 2024 16:46:38 +0100 Subject: [PATCH 055/261] TRAN-322: AND - "Download complete" is not always showing --- .../StartDownloadComponentViewModel.kt | 53 ++++------ .../StartDownloadComponentViewModelTest.kt | 5 +- .../MonitorActiveTransferFinishedUseCase.kt | 31 ++++++ .../shared/AbstractTransferNodesUseCase.kt | 2 - ...onitorActiveTransferFinishedUseCaseTest.kt | 100 ++++++++++++++++++ 5 files changed, 157 insertions(+), 34 deletions(-) create mode 100644 domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt create mode 100644 domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt index 007e86f334..cbc628dec7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModel.kt @@ -13,8 +13,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.last -import kotlinx.coroutines.flow.lastOrNull -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.update @@ -41,6 +39,7 @@ import mega.privacy.android.domain.usecase.offline.GetOfflinePathForNodeUseCase import mega.privacy.android.domain.usecase.setting.IsAskBeforeLargeDownloadsSettingUseCase import mega.privacy.android.domain.usecase.setting.SetAskBeforeLargeDownloadsSettingUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase +import mega.privacy.android.domain.usecase.transfers.active.MonitorActiveTransferFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.MonitorOngoingActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.downloads.GetCurrentDownloadSpeedUseCase import mega.privacy.android.domain.usecase.transfers.downloads.GetOrCreateStorageDownloadLocationUseCase @@ -75,6 +74,7 @@ internal class StartDownloadComponentViewModel @Inject constructor( private val setStorageDownloadAskAlwaysUseCase: SetStorageDownloadAskAlwaysUseCase, private val setStorageDownloadLocationUseCase: SetStorageDownloadLocationUseCase, private val getExternalPathByContentUriUseCase: GetExternalPathByContentUriUseCase, + private val monitorActiveTransferFinishedUseCase: MonitorActiveTransferFinishedUseCase, ) : ViewModel() { private var currentInProgressJob: Job? = null @@ -251,7 +251,9 @@ internal class StartDownloadComponentViewModel @Inject constructor( isHighPriority: Boolean, getPath: suspend () -> String?, ) { + monitorDownloadFinishJob?.cancel() clearActiveTransfersIfFinishedUseCase(TransferType.DOWNLOAD) + monitorDownloadFinish() _uiState.update { it.copy(jobInProgressState = StartDownloadTransferJobInProgress.ProcessingFiles) } @@ -277,7 +279,6 @@ internal class StartDownloadComponentViewModel @Inject constructor( } }.last() } - monitorFinish() checkRating() _uiState.updateEventAndClearProgress( when (terminalEvent) { @@ -409,40 +410,30 @@ internal class StartDownloadComponentViewModel @Inject constructor( } } - private var monitorFinishJob: Job? = null + private var monitorDownloadFinishJob: Job? = null /** * Monitor finish to send the corresponding event (will display a "Download Finished" snackbar or similar) */ - private fun monitorFinish() { - if (monitorFinishJob == null) { - monitorFinishJob = viewModelScope.launch { - val lastBeforeClear = - monitorOngoingActiveTransfersUseCase(TransferType.DOWNLOAD) - .conflate() - .map { it.activeTransferTotals } - .takeWhile { - it.totalTransfers > 0 - }.lastOrNull() ?: return@launch - (lastBeforeClear.totalFilesDownloaded).takeIf { it > 0 } - ?.let { - when (_uiState.value.transferTriggerEvent) { - is TransferTriggerEvent.StartDownloadForOffline -> { - StartDownloadTransferEvent.Message.FinishOffline - } - - is TransferTriggerEvent.StartDownloadNode -> { - StartDownloadTransferEvent.MessagePlural.FinishDownloading( - it - ) - } + private fun monitorDownloadFinish() { + monitorDownloadFinishJob?.cancel() + monitorDownloadFinishJob = viewModelScope.launch { + monitorActiveTransferFinishedUseCase(TransferType.DOWNLOAD).collect { totalNodes -> + when (_uiState.value.transferTriggerEvent) { + is TransferTriggerEvent.StartDownloadForOffline -> { + StartDownloadTransferEvent.Message.FinishOffline + } - else -> null - }?.let { finishEvent -> - _uiState.updateEventAndClearProgress(finishEvent) - } + is TransferTriggerEvent.StartDownloadNode -> { + StartDownloadTransferEvent.MessagePlural.FinishDownloading( + totalNodes + ) } - monitorFinishJob = null + + else -> null + }?.let { finishEvent -> + _uiState.updateEventAndClearProgress(finishEvent) + } } } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt index 6e2dbc1fd1..105c647803 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/transfers/startdownload/StartDownloadComponentViewModelTest.kt @@ -31,6 +31,7 @@ import mega.privacy.android.domain.usecase.offline.GetOfflinePathForNodeUseCase import mega.privacy.android.domain.usecase.setting.IsAskBeforeLargeDownloadsSettingUseCase import mega.privacy.android.domain.usecase.setting.SetAskBeforeLargeDownloadsSettingUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase +import mega.privacy.android.domain.usecase.transfers.active.MonitorActiveTransferFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.MonitorOngoingActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.downloads.GetCurrentDownloadSpeedUseCase import mega.privacy.android.domain.usecase.transfers.downloads.GetOrCreateStorageDownloadLocationUseCase @@ -84,6 +85,7 @@ class StartDownloadComponentViewModelTest { private val setStorageDownloadAskAlwaysUseCase = mock() private val setStorageDownloadLocationUseCase = mock() private val getExternalPathByContentUriUseCase = mock() + private val monitorActiveTransferFinishedUseCase = mock() private val node: TypedFileNode = mock() @@ -112,8 +114,8 @@ class StartDownloadComponentViewModelTest { setStorageDownloadAskAlwaysUseCase, setStorageDownloadLocationUseCase, getExternalPathByContentUriUseCase, + monitorActiveTransferFinishedUseCase, ) - } @BeforeEach @@ -144,6 +146,7 @@ class StartDownloadComponentViewModelTest { private fun initialStub() { whenever(monitorOngoingActiveTransfersUseCase(any())).thenReturn(emptyFlow()) + whenever(monitorActiveTransferFinishedUseCase(any())).thenReturn(emptyFlow()) } @ParameterizedTest diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt new file mode 100644 index 0000000000..ba955f47b8 --- /dev/null +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt @@ -0,0 +1,31 @@ +package mega.privacy.android.domain.usecase.transfers.active + +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.mapNotNull +import kotlinx.coroutines.flow.scan +import mega.privacy.android.domain.entity.transfer.TransferType +import mega.privacy.android.domain.repository.TransferRepository +import javax.inject.Inject + +/** + * Monitor active transfers and emits last total files transfers once the totals is back to 0 (that means it has finished) + */ +class MonitorActiveTransferFinishedUseCase @Inject constructor( + private val transferRepository: TransferRepository, +) { + + /** + * Invoke + * @return flow emitting last non-zero totalFileTransfers when it goes back to 0 + */ + operator fun invoke(transferType: TransferType) = + transferRepository.getActiveTransferTotalsByType(transferType) + .map { it.totalFileTransfers } + .distinctUntilChanged() + .scan(0 to 0) { (_, prev), new -> + prev to new + }.mapNotNull { (prev, current) -> + prev.takeIf { prev != 0 && current == 0 } + } +} \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt index 457251b254..6efff0937f 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/shared/AbstractTransferNodesUseCase.kt @@ -104,8 +104,6 @@ abstract class AbstractTransferNodesUseCase( } } - - send( MultiTransferEvent.SingleTransferEvent( transferEvent = transferEvent, diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt new file mode 100644 index 0000000000..cbe2892bc7 --- /dev/null +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt @@ -0,0 +1,100 @@ +package mega.privacy.android.domain.usecase.transfers.active + +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.asFlow +import kotlinx.coroutines.test.runTest +import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals +import mega.privacy.android.domain.entity.transfer.TransferType +import mega.privacy.android.domain.repository.TransferRepository +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.EnumSource +import org.mockito.kotlin.any +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.reset +import org.mockito.kotlin.whenever + + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class MonitorActiveTransferFinishedUseCaseTest { + private lateinit var underTest: MonitorActiveTransferFinishedUseCase + + private val transferRepository = mock() + + @BeforeAll + fun setUp() { + underTest = MonitorActiveTransferFinishedUseCase(transferRepository) + } + + @BeforeEach + fun resetMocks() { + reset(transferRepository) + } + + @ParameterizedTest + @EnumSource(TransferType::class) + fun `test that last non zero totalFileTransfers is emitted when active transfers totals with 0 totalFileTransfers is received`( + type: TransferType, + ) = runTest { + val flow = createTotals(5, 6, 7, 0) + whenever(transferRepository.getActiveTransferTotalsByType(any())) doReturn flow.asFlow() + + underTest(type).test { + assertThat(awaitItem()).isEqualTo(7) + awaitComplete() + } + } + + @ParameterizedTest + @EnumSource(TransferType::class) + fun `test that last non zero totalFileTransfers are emitted for multiple active transfers totals with 0 totalFileTransfers is received`( + type: TransferType, + ) = runTest { + val flow = createTotals(5, 0, 6, 0, 0, 7, 0) + whenever(transferRepository.getActiveTransferTotalsByType(any())) doReturn flow.asFlow() + + underTest(type).test { + assertThat(awaitItem()).isEqualTo(5) + assertThat(awaitItem()).isEqualTo(6) + assertThat(awaitItem()).isEqualTo(7) + awaitComplete() + } + } + + @ParameterizedTest + @EnumSource(TransferType::class) + fun `test that no value is emmited when active transfers totals with 0 totalFileTransfers is not received`( + type: TransferType, + ) = runTest { + val flow = createTotals(5, 6, 7) + whenever(transferRepository.getActiveTransferTotalsByType(any())) doReturn flow.asFlow() + + underTest(type).test { + awaitComplete() + } + } + + @ParameterizedTest + @EnumSource(TransferType::class) + fun `test that no value is emmited when first active transfers totals has 0 totalFileTransfers`( + type: TransferType, + ) = runTest { + val flow = createTotals(0, 5, 6, 7) + whenever(transferRepository.getActiveTransferTotalsByType(any())) doReturn flow.asFlow() + + underTest(type).test { + awaitComplete() + } + } + + private fun createTotals(vararg totals: Int) = totals.map { mockTotal(it) } + + private fun mockTotal(total: Int) = mock { + on { totalFileTransfers } doReturn total + } + +} \ No newline at end of file From e817f91a7a9885af919359689f9088065e19f9cf Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Mon, 25 Mar 2024 17:25:36 +0100 Subject: [PATCH 056/261] T15478886: The confirmation message after a download starts is sometimes missing --- .../view/StartDownloadComponent.kt | 1 + .../MonitorActiveTransferFinishedUseCase.kt | 25 ++++++++++++---- ...onitorActiveTransferFinishedUseCaseTest.kt | 30 ++++++++++++++++--- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt index f9a9324f95..326bbcb9bc 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/startdownload/view/StartDownloadComponent.kt @@ -158,6 +158,7 @@ fun createStartDownloadView( snackbarHostState.currentSnackbarData?.message?.let { Util.showSnackbar(activity, it) } + snackbarHostState.currentSnackbarData?.dismiss() } StartDownloadComponent( downloadEvent, diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt index ba955f47b8..10499eabf3 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCase.kt @@ -1,9 +1,9 @@ package mega.privacy.android.domain.usecase.transfers.active import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.scan +import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferType import mega.privacy.android.domain.repository.TransferRepository import javax.inject.Inject @@ -17,15 +17,30 @@ class MonitorActiveTransferFinishedUseCase @Inject constructor( /** * Invoke - * @return flow emitting last non-zero totalFileTransfers when it goes back to 0 + * @return flow emitting last non-zero totalFileTransfers when it goes back to 0 (unless they all were already downloaded files) */ operator fun invoke(transferType: TransferType) = transferRepository.getActiveTransferTotalsByType(transferType) - .map { it.totalFileTransfers } .distinctUntilChanged() - .scan(0 to 0) { (_, prev), new -> + .scan(emptyTotals(transferType) to emptyTotals(transferType)) { (_, prev), new -> prev to new }.mapNotNull { (prev, current) -> - prev.takeIf { prev != 0 && current == 0 } + prev.takeIf { + prev.totalFileTransfers != 0 && current.totalFileTransfers == 0 + && prev.totalFinishedTransfers > prev.totalAlreadyDownloadedFiles + }?.totalFileTransfers } + + private fun emptyTotals(transferType: TransferType) = ActiveTransferTotals( + transfersType = transferType, + totalTransfers = 0, + totalFileTransfers = 0, + pausedFileTransfers = 0, + totalFinishedTransfers = 0, + totalFinishedFileTransfers = 0, + totalCompletedFileTransfers = 0, + totalBytes = 0L, + transferredBytes = 0L, + totalAlreadyDownloadedFiles = 0 + ) } \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt index cbe2892bc7..cb428fc6a2 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/MonitorActiveTransferFinishedUseCaseTest.kt @@ -67,7 +67,7 @@ class MonitorActiveTransferFinishedUseCaseTest { @ParameterizedTest @EnumSource(TransferType::class) - fun `test that no value is emmited when active transfers totals with 0 totalFileTransfers is not received`( + fun `test that no value is emitted when active transfers totals with 0 totalFileTransfers is not received`( type: TransferType, ) = runTest { val flow = createTotals(5, 6, 7) @@ -80,7 +80,7 @@ class MonitorActiveTransferFinishedUseCaseTest { @ParameterizedTest @EnumSource(TransferType::class) - fun `test that no value is emmited when first active transfers totals has 0 totalFileTransfers`( + fun `test that no value is emitted when first active transfers totals has 0 totalFileTransfers`( type: TransferType, ) = runTest { val flow = createTotals(0, 5, 6, 7) @@ -91,10 +91,32 @@ class MonitorActiveTransferFinishedUseCaseTest { } } + @ParameterizedTest + @EnumSource(TransferType::class) + fun `test that no value is emitted when all transfers were already downloaded`( + type: TransferType, + ) = runTest { + val flow = listOf( + mockTotal(5, 5, 5), + mockTotal(0) + ) + whenever(transferRepository.getActiveTransferTotalsByType(any())) doReturn flow.asFlow() + + underTest(type).test { + awaitComplete() + } + } + private fun createTotals(vararg totals: Int) = totals.map { mockTotal(it) } - private fun mockTotal(total: Int) = mock { - on { totalFileTransfers } doReturn total + private fun mockTotal( + totalFileTransfers: Int, + totalFinishedTransfers: Int = totalFileTransfers, + totalAlreadyDownloadedFiles: Int = 0, + ) = mock { + on { this.totalFileTransfers } doReturn totalFileTransfers + on { this.totalFinishedTransfers } doReturn totalFinishedTransfers + on { this.totalAlreadyDownloadedFiles } doReturn totalAlreadyDownloadedFiles } } \ No newline at end of file From 08ccd0832db8be31163de6ea50b2916ae54ab7f5 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Wed, 27 Mar 2024 20:43:46 +1300 Subject: [PATCH 057/261] Pre-release - v11.9 --- app/src/main/res/values-ar/strings.xml | 57 ++++++++----- app/src/main/res/values-de/strings.xml | 63 ++++++++++----- app/src/main/res/values-es/strings.xml | 57 +++++++++---- app/src/main/res/values-fr/strings.xml | 61 +++++++++----- app/src/main/res/values-in/strings.xml | 52 ++++++++---- app/src/main/res/values-it/strings.xml | 59 +++++++++----- app/src/main/res/values-ja/strings.xml | 51 ++++++++---- app/src/main/res/values-ko/strings.xml | 52 ++++++++---- app/src/main/res/values-nl/strings.xml | 53 +++++++++---- app/src/main/res/values-pl/strings.xml | 55 +++++++++---- app/src/main/res/values-pt/strings.xml | 59 +++++++++----- app/src/main/res/values-ro/strings.xml | 56 +++++++++---- app/src/main/res/values-ru/strings.xml | 55 +++++++++---- app/src/main/res/values-th/strings.xml | 68 ++++++++++------ app/src/main/res/values-vi/strings.xml | 52 ++++++++---- app/src/main/res/values-zh-rCN/strings.xml | 79 ++++++++++++------- app/src/main/res/values-zh-rTW/strings.xml | 54 +++++++++---- app/src/main/res/values/strings.xml | 55 +++++++++---- build.gradle.kts | 2 +- .../strings_device_center_feature.xml | 5 +- .../strings_device_center_feature.xml | 5 +- .../strings_device_center_feature.xml | 3 +- sdk/src/main/jni/megachat/sdk | 2 +- 23 files changed, 732 insertions(+), 323 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 9314a16995..02897c728a 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -2913,12 +2913,6 @@ لا يمكنك إزالة %1$s كجهة اتصال لأنها جزء من حساب الأعمال الخاص بك. حدثت مشكلة في الدفعة الأخيرة. يرجى الوصول إلى ميغا MEGA باستخدام متصفح سطح المكتب لمزيد من المعلومات. - - الحساب غير مفعل - - تم إلغاء تفعيل حساب الأعمال Business الخاص بك بسبب فشل الدفع. لن تتمكن من الوصول إلى البيانات المخزنة في حسابك. للقيام بالدفع وإعادة تفعيل اشتراكك، قم بتسجيل الدخول إلى ميغا MEGA من المتصفح. - - حسابك [B]معلق[/B] حالياً. يمكنك فقط تصفح بياناتك. لا يمكن لميغا MEGA الوصول إلى بياناتك. ومع ذلك، يمكن لمسؤول حساب الأعمال الوصول إلى ترفيعات الكاميرا الخاصة بك. @@ -3383,15 +3377,6 @@ أشهر سنين - - - جاري الترفيع، %1$d ملف معلق - جاري الترفيع، %1$d ملف معلق - جاري الترفيع، %1$d ملفان معلقان - جاري الترفيع، %1$d ملفات معلقة - جاري الترفيع، %1$d ملف معلق - جاري الترفيع، %1$d ملف معلق - Production @@ -5616,8 +5601,6 @@ اشتر برو Pro II اشتر برو Pro III - - شروط الخدمة يمكن فقط للأشخاص الذين لديهم كلمة المرور فتح الرابط @@ -6210,6 +6193,7 @@ يتم تجديد الاشتراكات تلقائيًا لفترات اشتراك متتالية من نفس المدة وبنفس سعر الفترة الأولية المختارة. يمكنك إيقاف التجديد التلقائي لاشتراك ميغا برو MEGA Pro الخاص بك في موعد لا يتجاوز 24 ساعة قبل استحقاق دفعة الاشتراك التالية عبر الاشتراكات في [A]غوغل بلاي Google Play[/A]. السماح بالوصول إلى معرض الصور الخاص بك + منح اذن الوصول التحديث مطلوب @@ -6272,7 +6256,7 @@ تغيير - الباقات المجانية لها حد 60 دقيقة لكل اجتماع. [A]قم بالترقية الآن.[/A] + [A]باقتك المجانية لها حد 60 دقيقة للاجتماعات. يتمتع مستخدمو برو Pro بمكالمات غير محدودة وما يصل إلى 1000 مشارك.[/A] [B]قم بالترقية الآن.[/B] سيتم محاسبتك بمبلغ %1$s على الفور وسيتم تجديد اشتراكك تلقائيًا بعد 1 شهر بمبلغ %2$s في الشهر. سيتم فرض رسوم على حساب غوغل بلاي Google Play الخاص بك للتجديد في غضون 24 ساعة من نهاية كل فترة دفع. لإلغاء اشتراكك يجب عليك إيقاف التجديد التلقائي لاشتراك MEGA Pro ميغا برو الخاص بك قبل 24 ساعة على الأقل من نهاية فترة الفاتورة عبر الاشتراكات في [A]غوغل بلاي Google Play[/A].\nمن خلال ترقية حسابك فإنك توافق على [B]شروط خدمة[/B] و [C]سياسة الخصوصية[/C] الخاصين بميغا MEGA. @@ -6313,7 +6297,42 @@ تنتهي الصلاحية في %1$s الساعة %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. يمكن لـ 100 مشارك فقط الانضمام إلى المكالمة. لن يتمكن أي مشارك إضافي إلا من إرسال المحادثات وقراءتها. اطلب من المنظم إزالة هذا التقييد. + + منخفضة + + متوسط + + عالية + + الأصلي + + You denied MEGA access to your microphone. If you’d like to record a voice clip, allow MEGA permission to do so. + + لا يمكن الانضمام + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + حسنًا، فهمت ذلك + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 968abb5ba8..11081f7304 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1286,7 +1286,7 @@ Mobildatennutzung erlauben - Videos uploaden + Videos hochladen Profilbild aktualisiert @@ -1545,7 +1545,7 @@ Bei der Freigabe der QR-Datei ist ein Fehler aufgetreten. - Es ist ein Fehler beim Uploaden der QR-Datei aufgetreten. Die Datei existiert möglicherweise nicht. + Es ist ein Fehler beim Hochladen der QR-Datei aufgetreten. Die Datei existiert möglicherweise nicht. Es ist ein Fehler beim Herunterladen der QR-Datei aufgetreten. Die Datei existiert möglicherweise nicht. @@ -2641,12 +2641,6 @@ Sie können %1$s nicht aus Ihren Kontakten entfernen, da diese Person Ihrem Business-Account angehört. Bei Ihrer letzten Zahlung ist ein Problem aufgetreten. Bitte öffnen Sie MEGA in einem Desktop-Browser, um weitere Informationen zu erhalten. - - Account deaktiviert - - Ihr Business-Account wurde aufgrund einer fehlenden Zahlung deaktiviert. Sie können auf die Daten in Ihrem Account nicht zugreifen. Um eine Zahlung vorzunehmen und Ihr Abonnement erneut zu aktivieren, melden Sie sich in einem Browser bei MEGA an. - - Ihr Account ist [B]gesperrt[/B]. Sie können lediglich lesend auf Ihre Daten zugreifen. MEGA kann nicht auf Ihre Daten zugreifen. Der Administrator Ihres Business-Accounts kann jedoch auf Ihre Kamera-Uploads zugreifen. @@ -3071,11 +3065,6 @@ Monate Jahre - - - Upload läuft, noch %1$d Datei - Upload läuft, noch %1$d Dateien - Produktion @@ -4764,8 +4753,6 @@ Pro II kaufen Pro III kaufen - - Nutzungsbedingungen Den Link können nur Personen öffnen, die das Passwort kennen @@ -5270,6 +5257,7 @@ Abonnements werden automatisch für den ursprünglich gewählten Abonnementzeitraum und zum gleichen Preis verlängert. Sie können die automatische Verlängerung Ihres MEGA-Pro-Abonnements bis spätestens 24 Stunden vor Fälligkeit Ihrer nächsten Abonnementzahlung in [A]Google Play[/A] unter Abonnements deaktivieren. Gewähren Sie Zugriff auf Ihre Galerie + Zugriff gewähren Update erforderlich @@ -5324,7 +5312,7 @@ Ändern - Kostenlose Pakete sind auf 60 Minuten pro Meeting begrenzt. [A]Jetzt upgraden.[/A] + [A]Bei Ihrem kostenlosen Paket sind Meetings auf 60 Minuten begrenzt. Pro-Pakete unterliegen keinen zeitlichen Begrenzungen und erlauben bis zu 1000 Teilnehmer.[/A] [B]Jetzt upgraden.[/B] Ihnen werden sofort %1$s abgebucht, und Ihr Abonnement wird nach einem Monat automatisch für %2$s pro Monat verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und der [C]Datenschutzerklärung[/C] von MEGA einverstanden. @@ -5352,16 +5340,51 @@ Jetzt nicht - This free call will end in %s + Dieser kostenlose Anruf endet in %s - Your free call will end in %d minute - Your free call will end in %d minutes + Ihr kostenloser Anruf endet in %d Minute + Ihr kostenloser Anruf endet in %d Minuten Gültig bis %1$s %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Nur 100 Teilnehmer können der Konferenz beitreten. Alle weiteren Teilnehmer können nur Chatnachrichten senden und lesen. Bitten Sie den Organisator, diese Einschränkung aufzuheben. + + Niedrig + + Mittel + + Hoch + + Original + + Sie haben MEGA den Zugriff auf Ihr Mikrofon verweigert. Wenn Sie eine Sprachnotiz aufnehmen möchten, gewähren Sie MEGA die entsprechende Berechtigung. + + Beitritt nicht möglich + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + Alles klar + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 09596a903b..5dbe13a476 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -2709,12 +2709,6 @@ No puedes eliminar %1$s como contacto porque es parte de tu cuenta Business. Ha habido un problema con tu último pago. Accede a MEGA utilizando el navegador de tu pc para obtener más información. - - Cuenta desactivada - - Tu cuenta Business ha sido desactivada porque el pago ha fallado. No podrás acceder a los datos almacenados en tu cuenta. Para realizar el pago y reactivar tu suscripción, inicia sesión en MEGA a través de un navegador. - - Tu cuenta está [B]suspendida[/B]. Solo puedes ver tus datos. Si bien MEGA no tiene acceso a tus datos, el administrador de la cuenta Business puede acceder a tus Subídas de la cámara. @@ -3149,12 +3143,6 @@ Meses Años - - - Subida en curso, %1$d archivo pendiente - Subida en curso, %1$d de archivos pendientes - Subida en curso, %1$d archivos pendientes - Producción @@ -4977,8 +4965,6 @@ Comprar Pro II Comprar Pro III - - Términos de servicio Solo quien tenga la contraseña podrá acceder al enlace @@ -5505,6 +5491,7 @@ La suscripción se renueva automáticamente con la misma duración y precio elegidos inicialmente. Puedes desactivar la renovación automática de la suscripción a MEGA Pro en la página de suscripciones de [A]Google Play[/A] hasta 24 horas antes de la renovación programada. Permitir acceso a la galería + Conceder acceso Actualización requerida @@ -5561,7 +5548,7 @@ Cambiar - Los planes gratuitos tienen un límite de 60 minutos por reunión. [A]Amplía ahora.[/A] + [A]Tu plan gratuito tiene un límite de 60 minutos por reunión. Los usuarios Pro tienen llamadas ilimitadas y hasta 1000 participantes.[/A] [B]Amplía ahora.[/B] Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 1 mes a %2$s por mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. @@ -5597,9 +5584,45 @@ Esta llamada gratuita finalizará en %d minutos - Expires on %1$s at %2$s + Caduca el %1$s a las %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Only 100 participants can join the call. Any additional participants will only be able to send and read chats. Ask the organiser to remove this restriction. + + Baja + + Media + + Alta + + Original + + Has denegado el acceso a tu micrófono para MEGA. Si quieres grabar un clip de voz, concede a MEGA el permiso para hacerlo. + + No es posible unirse + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + Entendido + + Archivos y carpetas ocultos + + Oculta archivos y carpetas importantes + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Excluye de la cronología + + Los elementos ocultos solo son accesibles a través de la Nube y no aparecerán en tus Fotos, Álbumes o Recientes. + + Elementos ocultos + + Tú decides cuándo hacer visibles los archivos ocultos. Hay un nuevo ajuste para mostrar temporalmente los elementos ocultos. + + + %1$d elemento oculto + %1$d de elementos ocultos + %1$d elementos ocultos + \ 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 e9ae2eec5e..57bbd5208d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -2709,16 +2709,10 @@ Vous ne pouvez pas supprimer %1$s de vos contacts, car ce contact fait parti de votre compte Pour entreprise. Un problème est survenu lors de votre dernier paiement. Pour plus de précisions, veuillez accéder à MEGA en utilisant un navigateur pour ordinateur. - - Le compte est désactivé - - Votre compte Pour entreprise a été désactivé pour défaut de paiement. Vous ne pourrez plus accéder aux données stockées dans votre compte. Pour effectuer un paiement et réactiver votre abonnement, connectez-vous à MEGA dans un navigateur. - - Votre compte est actuellement [B]désactivé[/B]. Vous ne pouvez que parcourir vos données. MEGA ne peut pas accéder à vos données. Cependant, l’administrateur de votre compte Pour entreprise peut accéder à vos Téléversements de l’appareil photo. - Quelque chose a mal tourné + Un problème est survenu Contactez l’administrateur de votre compte Pour entreprise pour résoudre la situation et activer votre compte. @@ -3149,12 +3143,6 @@ Mois Années - - - Téléversement en cours, %1$d fichier en attente - Téléversement en cours, %1$d de fichiers en attente - Téléversement en cours, %1$d fichiers en attente - Production @@ -3760,7 +3748,7 @@ Numériser - Insert parlé + Message vocal GIF @@ -4977,8 +4965,6 @@ Acheter Pro II Acheter Pro III - - Conditions générales d’utilisation Seules les personnes qui connaissent le mot de passe peuvent ouvrir le lien @@ -5505,6 +5491,7 @@ Les abonnements sont renouvelés automatiquement pour des périodes d’abonnement successives de même durée et au même prix que la période initiale choisie. Vous pouvez désactiver le renouvellement automatique de votre abonnement MEGA Pro au plus tard 24 heures avant la date de paiement de votre prochain abonnement dans Abonnements de [A]Google Play[/A]. Autoriser l’accès à votre galerie + Accorder l’accès Une mise à jour est nécessaire @@ -5561,7 +5548,7 @@ Changer - Les abonnements gratuits sont limités à 60 minutes par réunion. [A]Surclassez votre compte maintenant.[/A] + [A]Votre abonnement gratuit limite les réunions à 60 minutes. Les utilisateurs MEGA Pro bénéficient d’une durée d’appel illimitée et d’un maximum de 1 000 participants.[/A] [B]Surclassez votre compte maintenant.[/B] %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 1 mois pour %2$s par mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels[/C] de MEGA. @@ -5589,7 +5576,7 @@ Pas maintenant - This free call will end in %s + Cet appel gratuit se terminera dans %s Votre appel gratuit se terminera dans %d minute. @@ -5599,7 +5586,43 @@ Expire le %1$s à %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Seuls 100 participants peuvent participer à l’appel. Tout participant supplémentaire ne pourra qu’envoyer et lire les conversations. Demandez à la personne qui l’organise de lever cette restriction. + + Basse + + Moyen + + Haute + + Originale + + Si vous souhaitez enregistrer un message vocal, autorisez MEGA à accéder à votre microphone. + + Impossible de vous joindre + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + D’accord, j’ai compris + + Fichiers et dossiers cachés + + Cacher les fichiers et dossiers importants + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclure de la Vue chronologique + + Les éléments cachés ne sont accessibles que dans le Disque nuagique et n’apparaissent pas dans vos Photos, Albums ou Récents. + + À l’abri des regards + + Vous décidez si les fichiers cachés sont visibles. Un nouveau paramètre permet d’afficher temporairement les éléments cachés. + + + %1$d élément caché + %1$d d’éléments cachés + %1$d éléments cachés + \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 2df5bc4242..e2abe43e6f 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -2573,12 +2573,6 @@ Anda tidak dapat menghapus %1$s sebagai kontak karena itu adalah bagian dari akun Bisnis anda. Terjadi masalah dengan pembayaran terakhir anda. Silakan akses MEGA menggunakan browser desktop untuk informasi lebih lanjut. - - Akun dinonaktifkan - - Akun Bisnis anda telah dinonaktifkan karena kegagalan pembayaran. Anda tidak akan dapat mengakses data yang disimpan di akun anda. Untuk melakukan pembayaran dan mengaktifkan kembali langganan anda, masuk ke MEGA melalui browser. - - Akun anda saat ini [B]ditangguhkan[/B]. Anda hanya dapat menelusuri data anda. MEGA tidak dapat mengakses data anda. Namun, administrator akun bisnis anda dapat mengakses Unggahan camera anda. @@ -2993,10 +2987,6 @@ Bulan Tahun - - - Unggah sedang berlangsung, %1$dfile tertunda - Produksi @@ -4551,8 +4541,6 @@ Beli Pro II Beli Pro III - - Persyaratan Layanan Hanya orang yang memiliki kata sandi yang dapat membuka tautan tersebut @@ -5035,6 +5023,7 @@ Langganan diperpanjang secara otomatis untuk periode berlangganan berturut-turut dengan durasi yang sama dan dengan harga yang sama dengan periode awal yang dipilih. Anda dapat mematikan perpanjangan otomatis langganan MEGA   Pro anda selambat-lambatnya 24 jam sebelum pembayaran langganan berikutnya jatuh tempo melalui Langganan di [A]Google Play[/A]. Izinkan akses ke galeri anda + Berikan akses Diperlukan pembaruan @@ -5087,7 +5076,7 @@ Ganti - Paket gratis memiliki batas 60 menit per rapat. [A]Tingkatkan sekarang.[/A] + [A]Paket gratis anda memiliki batas 60 menit untuk rapat. Pengguna pro memiliki panggilan tak terbatas dan hingga 1000 peserta.[/A] [B]Tingkatkan sekarang.[/B] Anda akan dikenakan biaya %1$s segera dan langganan anda akan diperpanjang secara otomatis setelah 1 bulan untuk %2$s per bulan. Akun Google Play anda akan dikenakan biaya untuk pembaruan dalam waktu 24 jam setelah akhir setiap periode penagihan. Untuk membatalkan langganan anda, anda harus menonaktifkan perpanjangan otomatis langganan MEGA Pro anda setidaknya 24 jam sebelum akhir periode penagihan anda melalui Langganan di [A]Google Play[/A].\nDengan memutakhirkan akun anda, anda menyetujui [B]Ketentuan Layanan[/B] dan [C]Kebijakan Privasi[/C] MEGA. @@ -5123,7 +5112,42 @@ Kedaluwarsa pada %1$s pukul %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Hanya 100 peserta yang dapat bergabung dengan panggilan. Setiap peserta tambahan hanya akan dapat mengirim dan membaca obrolan. Minta penyelenggara untuk menghapus batasan ini. + + Rendah + + Sedang + + Tinggi + + Original + + You denied MEGA access to your microphone. If you’d like to record a voice clip, allow MEGA permission to do so. + + Tidak dapat bergabung + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, mengerti + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3a45204761..73f448c401 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -2709,12 +2709,6 @@ Non puoi rimuovere %1$s come contatto in quanto fa parte del tuo account Business. È stato riscontrato un errore con il tuo ultimo pagamento. Per favore, accedi a MEGA utilizzando un browser web per maggiori informazioni. - - Account disattivato - - Il tuo account Business è stato disattivato a causa del fallimento del pagamento. Non potrai accedere ai dati archiviati nel tuo account. Per effettuare un pagamento e riattivare il tuo abbonamento, effettua il login in MEGA tramite browser. - - Il tuo account è [B]sospeso[/B] al momento. Puoi solo sfogliare tra i tuoi dati. MEGA non può accedere ai tuoi dati. Comunque, l\’amministratore del tuo account Business può accedere ai tuoi Caricamenti da fotocamera. @@ -3149,12 +3143,6 @@ Mesi Anni - - - Caricamento in corso, %1$d file in attesa - Caricamento in corso, %1$d file in attesa - Caricamento in corso, %1$d file in attesa - Produzione @@ -4977,8 +4965,6 @@ Compra Pro II Compra Pro III - - Termini di Servizio Solo le persone con la password possono aprire il link @@ -5505,6 +5491,7 @@ Gli abbonamenti vengono rinnovati automaticamente per periodi di abbonamento successivi della stessa durata e allo stesso prezzo del periodo iniziale scelto. Puoi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro entro 24 ore prima della scadenza del prossimo pagamento dell\’abbonamento tramite Abbonamenti nel [A]Google Play[/A]. Permetti l\’accesso alla tua galleria + Garantisci l\’accesso Aggiornamento necessario @@ -5561,7 +5548,7 @@ Cambia - I piani gratuiti hanno un limite di 60 minuti per meeting. [A]Effettua l\’upgrade adesso.[/A] + [A]Il tuo piano gratuito prevede un limite di 60 minuti per i meeting. Gli utenti Pro hanno chiamate illimitate e fino a 1000 partecipanti.[/A] [B]Effettua l\’upgrade adesso.[/B] Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese al costo di %2$s al mese. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. @@ -5592,13 +5579,49 @@ This free call will end in %s - Your free call will end in %d minute - Your free call will end in %d minutes + La tua chiamata gratuita terminerà tra %d minuto + La tua chiamata gratuita terminerà tra %d di minuti + La tua chiamata gratuita terminerà tra %d minuti Scade il giorno %1$s alle ore %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Only 100 participants can join the call. Any additional participants will only be able to send and read chats. Ask the organiser to remove this restriction. + + Bassa + + Media + + Alta + + Originale + + Hai negato a MEGA l\’accesso al tuo microfono. Se desideri registrare un messaggio vocale, consenti a MEGA di farlo. + + Impossibile unirsi + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, capito + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 05b783652e..d971780b52 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -2573,12 +2573,6 @@ %1$sさんはあなたのビジネスアカウントの一部であるため、連絡先から削除できません。 最後のお支払いで問題がありました。詳細については、デスクトップブラウザを使用してMEGAにアクセスしてください。 - - アカウントが無効になっています - - お支払いが失敗したため、お客様のビジネスアカウントが無効化されました。そのため、アカウントに保存されているデータにアクセスできなくなります。お支払いを行ってサブスクリプションを再開するには、ブラウザからMEGAにログインしてください。 - - あなたのアカウントは現在[B]凍結[/B]されています。あなたのデータの閲覧のみ可能です。 MEGAはお客様のデータにアクセスできません。ただし、ビジネスアカウントの管理者様は、あなたのカメラアップロードにアクセスすることができます。 @@ -2993,10 +2987,6 @@ - - - アップロード中、%1$d個のファイルを保留中 - 本番 @@ -4551,8 +4541,6 @@ Pro IIを購入 Pro IIIを購入 - - ご利用規約 パスワードを知っている人だけがリンクを開けます @@ -5035,6 +5023,7 @@ サブスクリプションは、最初に選択した期間と同じ期間および同じ価格で、連続するサブスクリプション期間に対して自動的に更新されます。次のサブスクリプションのお支払い期日の24時間前までに、MEGA Proサブスクリプションの自動更新をオフに切り替えることができます。これは、[A]Google Play[/A]の「サブスクリプション」から実行できます。 ギャラリーへのアクセスを許可する + アクセスを許可 アップデートが必要です @@ -5087,7 +5076,7 @@ 変更 - 無料プランでは、1回のミーティングあたり60分の制限があります。[A]ぜひ今すぐアップグレードしてください。[/A] + [A]無料プランではミーティングに60分の制限があります。Proユーザー様は無制限の通話と、最大1000人の参加者まで可能です。[/A][B]ぜひ今すぐアップグレードしてください。[/B] すぐに%1$sが請求され、お客様のサブスクリプションは1 か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 @@ -5123,7 +5112,41 @@ %1$s %2$sに期限切れになります - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + 通話に参加できる参加者は100名のみです。追加の参加者は、メッセージの送受信のみが可能になります。主催者様はProにアップグレードして、これらの制限を解除できます。 通話に参加できる参加者は100名のみです。追加の参加者は、チャットの送信と読み取りのみが可能になります。主催者にこの制限を解除するよう依頼してください。 + + 低い + + 普通 + + 高い + + オリジナル + + MEGAによるマイクへのアクセスを拒否しました。ボイスクリップを録音されたい場合は、MEGAに録音許可を与えてください。 + + 参加できません + + 通話に参加できる参加者は100名のみです。追加の参加者は、メッセージの送受信のみが可能になります。主催者様はProにアップグレードして、これらの制限を解除できます。 + + はい、わかりました。 + + ファイルとフォルダを隠す + + 重要なファイルやフォルダを隠す + + 機密性の高いファイルやフォルダを非表示にして、プライバシーを確​​保できます。あなただけが、個別に、または一時的に、設定から非表示項目を表示できます。 + + タイムラインから除外 + + 非表示項目にはクラウドドライブからのみアクセスでき、写真、アルバム、最近の項目には表示されません。 + + 非表示の解除 + + 隠しファイルをいつ表示するかを決定します。非表示の項目を一時的に表示する新しい設定が追加されました。 + + + %1$d項目非表示 + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 0f9d23d418..e28df6e4b5 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -2573,12 +2573,6 @@ %1$s님의 연락처는 당신의 비즈니스 계정의 일부이기 때문에 삭제할 수 없습니다. 지난 결제에 문제가 있었습니다. 자세한 정보를 보려면 데스크톱 브라우저를 이용하여 MEGA에 접속하세요. - - 계정 비활성화됨 - - 당신의 비즈니스 계정은 결제 실패로 인해 비활성화 되었습니다. 계정 안에 있는 데이터에 접근하지 못할 것입니다. 결제를 하고 구독을 재활성화 하려면, 브라우저에서 MEGA에 로그인 하세요. - - 당신의 계정은 현재 [B]정지[/B]되었습니다. 당신의 데이터를 탐색만할 수 있습니다. MEGA는 당신의 데이터에 접근할 수 없습니다. 그러나 당신의 비즈니스 계정 관리자는 당신의 카메라 업로드에 접근할 수 있습니다. @@ -2993,10 +2987,6 @@ - - - 업로드 진행 중, 파일 %1$d개 대기 중 - 운영 @@ -4551,8 +4541,6 @@ Pro II 구입 Pro III 구입 - - 이용 약관 비밀번호가 있는 사람만 링크를 열 수 있습니다 @@ -5035,6 +5023,7 @@ 구독은 처음 선택한 기간과 같은 기간 그리고 같은 가격으로 연속적으로 자동 갱신 됩니다. MEGA Pro 구독 자동 갱신을 [A]Google Play[/A]의 구독을 통해 다음 구독의 결제 24시간 전에 취소할 수 있습니다. 갤러리에 접근 허용 + 접근 허가 업데이트가 필요합니다 @@ -5087,7 +5076,7 @@ 변경 - 무료 요금제는 회의마다 60분의 제한이 있습니다. [A]지금 업그레이드.[/A] + [A]무료 요금제는 회의에 60분 제한이 있습니다. Pro 이용자는 무제한 통화와 최대 1,000명의 참여자가 가능합니다.[/A] [B]지금 업그레이드.[/B] 즉시 %1$s이/가 청구될 것이며 구독은 1개월 후 자동으로 매월 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. @@ -5124,7 +5113,42 @@ %1$s %2$s에 만료됨 - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. 100명의 참여자만 통화에 참여할 수 있습니다. 추가 참여자는 대화를 읽고 보내기만 할 수 있습니다. 주최자에게 이 제한을 없애달라고 요청하세요. + + 낮음 + + 보통 + + 높음 + + 원본 + + You denied MEGA access to your microphone. If you’d like to record a voice clip, allow MEGA permission to do so. + + 참여할 수 없음 + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + 알겠습니다 + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 0bccb244cc..d1616c3e88 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -2641,12 +2641,6 @@ U kunt %1$s niet verwijderen als contact omdat deze deel uitmaakt van uw zakelijke account. Er is een probleem opgetreden met uw laatste betaling. Ga voor meer informatie naar MEGA met een desktopbrowser. - - Account gedeactiveerd - - Uw Zakelijke account is gedeactiveerd vanwege een mislukte betaling. U heeft geen toegang tot de gegevens die in uw account zijn opgeslagen. Om een ​​betaling uit te voeren en uw abonnement opnieuw te activeren, logt u in op MEGA via een browser. - - Uw account is momenteel [B]geschorst[/B]. U kunt alleen door uw gegevens bladeren. MEGA heeft geen toegang tot uw gegevens. Uw zakelijke accountbeheerder heeft echter wel toegang tot uw Camera uploads. @@ -3071,11 +3065,6 @@ Maanden Jaren - - - Upload in behandeling, %1$d bestand wachtend - Upload in behandeling, %1$d bestanden wachtend - Productie @@ -4764,8 +4753,6 @@ Pro II kopen Pro III kopen - - Algemene Voorwaarden Alleen personen met het wachtwoord kunnen de link openen @@ -5270,6 +5257,7 @@ Abonnementen worden automatisch verlengd voor opeenvolgende abonnementsperioden van dezelfde duur en tegen dezelfde prijs als de gekozen initiële periode. U kunt de automatische verlenging van uw MEGA   Pro-abonnement uiterlijk 24 uur voordat uw volgende abonnementsbetaling verschuldigd is, uitschakelen via Abonnementen in [A]Google Play[/A]. Geef toegang tot uw gallerij + Toegang verlenen Update vereist @@ -5324,7 +5312,7 @@ Wijzigen - Gratis abonnementen hebben een limiet van 60 minuten per vergadering. [A]Nu upgraden.[/A] + [A]Uw gratis abonnement heeft een limiet van 60 minuten voor vergaderingen. Pro-gebruikers kunnen onbeperkt bellen en tot 1000 deelnemers.[/A] [B]Nu upgraden.[/B] Er worden onmiddelijk kosten in rekening gebracht %1$s en uw abonnement wordt na 1   maand automatisch verlengd voor %2$s per maand. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. @@ -5361,7 +5349,42 @@ Vervalt op %1$s om %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Slechts 100 deelnemers kunnen deelnemen aan de oproep. Eventuele extra deelnemers kunnen alleen gesprekken verzenden en lezen. Vraag de organisator om deze beperking op te heffen. + + Laag + + Gemiddeld + + Hoog + + Orgineel + + U hebt MEGA-toegang tot uw microfoon geweigerd. Als u een stemclip wilt opnemen, geef dan MEGA toestemming om dit te doen. + + Kan niet aansluiten + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + Ok, ik snap het + + Verborgen bestanden en mappen + + Belangrijke bestanden en mappen verbergen + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Verborgen items zijn alleen toegankelijk via de Cloud-schijf en verschijnen niet in uw Foto\’s, Albums of Recent. + + Uit het zicht + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a376d52f85..03367bb519 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -2777,12 +2777,6 @@ Nie możesz usunąć %1$s jako kontaktu, ponieważ są one częścią twojego konta firmowego. Wystąpił problem z ostatnią płatnością. Aby uzyskać więcej informacji, skorzystaj z MEGA przeglądarki na komputerze. - - Konto dezaktywowane - - Twoje konto Business zostało dezaktywowane z powodu braku płatności. Nie będziesz miał dostępu do danych przechowywanych na swoim koncie. Aby dokonać płatności i reaktywować subskrypcję, zaloguj się do MEGA przez przeglądarkę. - - Twoje konto jest obecnie [B]zawieszone[/B]. Możesz tylko przeglądać swoje dane. MEGA nie ma dostępu do Państwa danych. Administrator konta biznesowego ma jednak dostęp do danych Przesyłane z kamery. @@ -3227,13 +3221,6 @@ Miesiące Lata - - - Trwa przesyłanie, %1$d plik czeka na przesłanie - Trwa przesyłanie, %1$d plików czeka na przesłanie - Trwa przesyłanie, %1$d plików czeka na przesłanie - Trwa przesyłanie, %1$d plików czeka na przesłanie - Produkcyjny @@ -5190,8 +5177,6 @@ Kup Pro II Kup Pro III - - Regulamin serwisu Tylko osoby posiadające hasło mogą otworzyć łącze @@ -5740,6 +5725,7 @@ Subskrypcje są odnawiane automatycznie na kolejne okresy subskrypcji o tym samym czasie trwania i w tej samej cenie, co wybrany okres początkowy. Użytkownik może wyłączyć automatyczne odnawianie subskrypcji MEGA Pro nie później niż 24 godziny przed terminem płatności kolejnej subskrypcji za pośrednictwem Subskrypcji w [A]Google Play[/A]. Zezwalaj na dostęp do swojej galerii + Przyznaj dostęp Wymagana aktualizacja @@ -5798,7 +5784,7 @@ Zmień - Bezpłatne plan mają limit 60 minut na spotkanie. [A]Uaktualnij teraz.[/A] + [A]Twój darmowy plan ma limit 60 minut na spotkania. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000 uczestników.[/A] [B]Uaktualnij teraz.[/B] Zostaniesz obciążony %1$s natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 1   miesiącu %2$s miesięcznie. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godziny przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. @@ -5837,7 +5823,42 @@ Wygasa dnia %1$s o %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Do rozmowy może dołączyć tylko 100 uczestników. Dodatkowi uczestnicy będą mogli jedynie wysyłać i odczytywać czaty. Poproś organizatora o usunięcie tego ograniczenia. + + Niska + + Średnie + + Wysoka + + Oryginalny + + Odmówiłeś dostępu MEGA do mikrofon. Jeśli chcesz nagrać klip głosowy, zezwolić na to zezwolenie MEGA. + + Nie można dołączyć + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, rozumiem + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 81d3888093..c75549a3f1 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -1315,7 +1315,7 @@ O usuário não é um contato - Usar dados celulares + Usar dados móveis Fazer upload de vídeos @@ -2709,12 +2709,6 @@ Você não pode remover a %1$s dos seus contatos, por fazer parte da sua conta Business. Não foi possível processar o seu último pagamento. Por favor, acesse o MEGA usando um navegador em um computador para obter mais informações. - - Conta desativada - - A sua conta Business foi desativada porque o pagamento falhou, e já não será possível acessar os dados armazenados na sua conta. Para fazer o pagamento e assim reativar a sua assinatura, faça login no MEGA por meio de um navegador. - - A sua conta [B]expirou[/B]. Somente é possível visualizar os seus dados. Embora o MEGA não tenha acesso aos seus dados, o administrador da sua conta Business pode acessar os seus Uploads da câmera. @@ -3149,12 +3143,6 @@ Meses Anos - - - Upload em andamento, %1$d arquivo pendente - Upload em andamento, %1$d arquivos pendentes - Upload em andamento, %1$d arquivos pendentes - Produção @@ -4977,8 +4965,6 @@ Comprar Pro II Comprar Pro III - - Termos de serviço Somente quem tiver a senha poderá acessar o link @@ -5462,7 +5448,7 @@ O MEGA precisa acessar a sua câmera para fazer fotos e gravar vídeos. - Você não permitiu que o MEGA acesse à sua localização. Se você quiser compartilhar a sua localização, dê permissão à MEGA para fazer isso. + Você não permitiu que o MEGA acesse à sua localização. Se você quiser compartilhar a sua localização, dê permissão ao MEGA para fazer isso. Download grande @@ -5505,6 +5491,7 @@ As assinaturas serão renovadas automaticamente por períodos sucessivos com a mesma duração e pelo mesmo preço do período inicial. Você pode desativar a renovação automática da sua assinatura Pro do MEGA até 24 horas antes do vencimento do próximo pagamento nas Assinaturas da [A]Google Play[/A]. Permitir o acesso à sua galeria + Permitir acesso Atualização necessária @@ -5561,7 +5548,7 @@ Alterar - Os planos gratuitos têm um limite de 60 minutos por reunião. [A]Faça um upgrade.[/A] + [A]O seu plano gratuito tem um limite de 60 minutos para reuniões. Usuários com planos Pro podem fazer chamadas ilimitadas com até 1000 participantes.[/A] [B]Faça um upgrade.[/B] Neste momento, você receberá uma cobrança no valor de %1$s e a sua assinatura será renovada automaticamente depois de 1 mês por %2$s ao mês. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada mês do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do mês adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade[/C] do MEGA. @@ -5599,7 +5586,43 @@ Expira às %2$s do dia %1$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Somente 100 participantes podem entrar na chamada. Participantes adicionais só poderão enviar e ler mensagens. Solicite ao organizador que elimine essa restrição. + + Baixa + + Média + + Alta + + Original + + Você não permitiu que o MEGA acesse ao seu microfone. Se você quiser gravar um clipe de voz, dê permissão ao MEGA para fazer isso. + + Não foi possível entrar + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + Entendi + + Arquivos e pastas ocultos + + Oculte arquivos e pastas importantes + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclua da Linha do tempo + + Somente é possível acessar itens ocultos por meio da Nuvem de arquivos: eles não aparecerão nas suas Fotos, nos Álbuns ou nas Atividades recentes. + + Fora do alcance + + Você decide quando os arquivos ocultos ficam visíveis. Há uma nova configuração para mostrar itens ocultos temporariamente. + + + %1$d item oculto + %1$d de itens ocultos + %1$d itens ocultos + \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 9edc55560e..895c25a5d3 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -2709,12 +2709,6 @@ Nu puteți elimina %1$s ca contact, deoarece fac parte din contul dvs. Business. A apărut o problemă cu ultima plată. Vă rugăm să accesați MEGA folosind un browser desktop pentru mai multe informații. - - Cont dezactivat - - Contul tău Business a fost dezactivat din cauza unei plăți nereușite. Nu vei putea accesa datele stocate în contul tău. Pentru a efectua o plată și a-ți reactiva abonamentul, autentifică-te pe MEGA printr-un browser. - - În prezent, contul tău este [B]suspendat[/B]. Poți răsfoi numai prin datele tale. MEGA nu vă poate accesa datele. Cu toate acestea, administratorul contului dvs. Business poate accesa Încărcările camerei. @@ -3149,12 +3143,6 @@ Luni Ani - - - Încărcare în curs, %1$d fișier în așteptare - Încărcare în curs, %1$d fișiere în așteptare - Încărcare în curs, %1$d de fișiere în așteptare - Producție @@ -3760,7 +3748,7 @@ Scanează - Clip vocal + Mesaj vocal GIF @@ -4977,8 +4965,6 @@ Cumpara Pro II Cumpara Pro III - - Termenii de utilizare a serviciului Doar persoanele cu parola pot deschide linkul @@ -5505,6 +5491,7 @@ Abonamentele sunt reînnoite automat pentru perioade succesive de abonament cu aceeași durată și la același preț ca perioada inițială aleasă. Puteți dezactiva reînnoirea automată a abonamentului MEGA Pro cu cel mult 24 de ore înainte de scadența următoarei plăți a abonamentului prin Abonamente în [A]Google Play[/A]. Permiteți accesul la galeria dvs. + Acordă acces Actualizarea necesară @@ -5561,7 +5548,7 @@ Schimbă - Abonamentele gratuite au o limită de 60 de minute pe întâlnire. [A]Upgradați acum.[/A] + [A]Abonamentul dvs. gratuit are o limită de 60 de minute pentru întâlniri. Utilizatorii Pro au apeluri nelimitate și până la 1000 de participanți.[/A] [B]Upgradați acum.[/B] Veți fi taxat %1$s imediat și abonamentul dvs. se va reînnoi automat după 1 lună pentru %2$s pe lună. Contul dvs. Google Play va fi taxat pentru reînnoire în termen de 24 de ore de la sfârșitul fiecărei perioade de facturare. Pentru a vă anula abonamentul, trebuie să dezactivați reînnoirea automată a abonamentului MEGA Pro cu cel puțin 24 de ore înainte de sfârșitul perioadei de facturare prin Abonamente în [A]Google Play[/A].\nPrin actualizarea contului dvs., sunteți de acord cu MEGA [B]Termenii de utilizare a serviciului[/B] și [C]Politica de confidențialitate[/C]. @@ -5599,7 +5586,42 @@ Expiră la %1$s la ora %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Doar 100 de participanți se pot alătura apelului. Orice participanți suplimentari vor putea trimite și citi doar chat-uri. Solicitați organizatorului să elimine această restricție. + + Scăzută + + Medie + + Ridicată + + Originală + + Dacă doriți să înregistrați un mesaj vocal, permiteți accesul MEGA la microfonul dvs. + + Imposibil de a participa + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, am înțeles + + Fișiere și foldere ascunse + + Ascundeți fișierele și folderele importante + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Elementele ascunse sunt accesibile numai prin Unitatea cloud și nu vor apărea în Fotografii, Albume sau Recente. + + Invizibile + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index fb9f813a84..ccb17d6c57 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -2777,12 +2777,6 @@ Вы не можете удалить %1$s как контакт, поскольку он является частью вашего бизнес-аккаунта. Возникла проблема с вашим последним платежом. Пожалуйста, войдите в MEGA с помощью настольного браузера для получения дополнительной информации. - - Аккаунт деактивирован - - Ваш бизнес-аккаунт был деактивирован из-за сбоя оплаты. Вы не сможете получить доступ к данным, хранящимся в вашем аккаунте. Для оплаты и возобновления подписки войдите в MEGA через веб-браузер. - - Ваш аккаунт [B]приостановлен[/B]. Вы можете только просматривать данные. MEGA не может получить доступ к вашим данным. Однако администратор вашего бизнес-аккаунта может получить доступ к вашим загрузкам из камеры. @@ -3227,13 +3221,6 @@ Месяцы Годы - - - Загрузка, %1$d файл ожидает обработки - Загрузка, %1$d файла ожидает обработки - Загрузка, %1$d файлов ожидает обработки - Загрузка, %1$d файла ожидает обработки - Производство @@ -5190,8 +5177,6 @@ Купить Pro II Купить Pro III - - Условия использования Только люди с паролем могут открыть ссылку @@ -5740,6 +5725,7 @@ Подписки продлеваются автоматически на последующие периоды той же продолжительности и по той же цене, что и первоначально выбранный период. Вы можете отключить автоматическое продление подписки MEGA Pro не позднее чем за 24 часа до следующего платежа за подписку на странице «Подписки» в [A]Google Play[/A]. Разрешите доступ к галерее + Открыть доступ Требуется обновление @@ -5798,7 +5784,7 @@ Изменить - В бесплатных планах встречи ограничены 60 минутами. [A]Улучшить план.[/A] + [A]В бесплатном плане встречи ограничены 60 минутами. У пользователей Pro звонки не ограничены по длительности и могут включать до 1000 участников.[/A] [B]Улучшить план.[/B] У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 1 месяц за %2$s в месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. @@ -5837,7 +5823,42 @@ Истекает %1$s в %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. К звонку могут присоединиться до 100 участников. Остальные участники смогут только читать чаты и писать в них. Попросите организатора снять это ограничение. + + Низкое + + Среднее + + Высокое + + Исходное + + Вы запретили MEGA доступ к микрофону. Если вы хотите записать голосовое сообщение, выдайте MEGA это разрешение. + + Не удалось войти + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + Понятно + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 8031cc336e..91ffe85582 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -772,7 +772,7 @@ เก็บบัญชี - This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, contact support@mega.nz + นี่เป็นขั้นตอนสุดท้ายในการเก็บบัญชีของคุณ กรุณากรอกรหัสผ่านใหม่ของคุณ ข้อมูลของคุณจะถูกเก็บไว้อย่างน้อย 60 วัน ถ้าคุณจำรหัสผ่านของบัญชีที่เก็บไว้ได้ ติดต่อ support@mega.nz กรอกรหัสผ่านใหม่ @@ -2573,12 +2573,6 @@ คุณไม่สามารถลบ %1$s ออกจากการเป็นผู้ติดต่อได้เนื่องจากเป็นส่วนหนึ่งของบัญชีธุรกิจของคุณ เกิดปัญหากับการชำระเงินครั้งล่าสุดของคุณ กรุณาไปที่เว็บ MEGA ผ่านเบราว์เซอร์เดสก์ท็อปเพื่อดูข้อมูลเพิ่มเติม - - บัญชีถูกปิดใช้งาน - - บัญชีธุรกิจของคุณถูกปิดใช้งานเนื่องจากการชำระเงินไม่สำเร็จ คุณจะไม่สามารถเข้าถึงข้อมูลของคุณได้ กรุณาเข้าสู่ระบบ MEGA ผ่านเบราว์เซอร์เพื่อดำเนินการชำระเงินและเปิดใช้การสมัครใช้งานของคุณอีกครั้ง - - บัญชีของคุณ[B]ถูกระงับ[/B]ในขณะนี้ คุณสามารถเรียกดูได้แค่ข้อมูลของคุณเท่านั้น MEGA ไม่สามารถเข้าถึงข้อมูลของคุณได้ อย่างไรก็ตาม ผู้ดูแลระบบบัญชีธุรกิจของคุณจะยังสามารถเข้าถึงการอัปโหลดจากกล้องของคุณได้ @@ -2993,10 +2987,6 @@ เดือน ปี - - - กำลังอยู่ในระหว่างอัปโหลด มี %1$d ไฟล์รอดำเนินการ - โปรดักชั่น (ใช้งานจริง) @@ -4540,7 +4530,7 @@ • ตั้งค่าการสำรองข้อมูลอัตโนมัติได้ - • Rewind up to 90 days of deleted data on Pro Lite and up to 180 days on Pro I, II, and III + • ใช้ฟีเจอร์ย้อนกลับไฟล์ที่ถูกลบได้ โดย Pro Lite ย้อนกลับได้ถึง 90 วัน ส่วน Pro I, II และ III ย้อนกลับได้ถึง 180 วัน • สร้างกำหนดการล้างถังขยะได้ตั้งแต่ 7 วันถึง 10 ปี @@ -4551,8 +4541,6 @@ ซื้อ Pro II ซื้อ Pro III - - เงื่อนไขการให้บริการ เฉพาะผู้ที่มีรหัสผ่านเท่านั้นที่สามารถเปิดลิงก์ได้ @@ -5035,6 +5023,7 @@ เมื่อสมัครใช้งานแล้ว ระบบจะต่ออายุสมาชิกให้อัตโนมัติตามระยะเวลาและราคาเดิมที่เลือกไว้ คุณสามารถยกเลิกการต่ออายุสมาชิก MEGA Pro อัตโนมัติได้ไม่เกิน 24 ชั่วโมงก่อนวันครบกำหนดชำระค่าสมาชิกครั้งต่อไปผ่านระบบสมาชิกใน [A]Google Play[/A] อนุญาตให้เข้าถึงแกลเลอรี่ของคุณ + ให้สิทธิ์เข้าถึง จำเป็นต้องได้รับการอัปเดต @@ -5069,7 +5058,7 @@ การอัปโหลดจากกล้องเสร็จสมบูรณ์ มี %1$d ไฟล์ที่อัปโหลดแล้ว - [A]Your free plan has a 60-minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]แผนฟรีของคุณมีข้อจำกัดเวลาการประชุม 60 นาที ผู้ใช้ Pro สามารถโทรได้ไม่จำกัดและมีผู้เข้าร่วมประชุมได้สูงสุด 1000 คน[/A] [B]อัปเกรดเลย[/B] ซ่อน @@ -5087,7 +5076,7 @@ เปลี่ยน - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + [A]แผนฟรีของคุณมีข้อจำกัดเวลาการประชุม 60 นาที ผู้ใช้ Pro สามารถโทรได้ไม่จำกัดและมีผู้เข้าร่วมประชุมได้สูงสุด 1000 คน[/A] [B]อัปเกรดเลย[/B] คุณจะถูกเรียกเก็บเงิน %1$s ทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน ในราคา %2$s ต่อเดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA @@ -5095,7 +5084,7 @@ คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA - คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 12 เดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุหลังจาก 12 เดือนโดยอัตโนมัติ บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA บัญชีธุรกิจถูกปิดการใช้งานแล้ว @@ -5105,9 +5094,9 @@ โอเค เข้าใจแล้ว - • Host calls and meetings with unlimited participants and no time restrictions + • โทรและประชุมได้แบบไม่จำกัดจำนวนผู้เข้าร่วมและไม่มีข้อจำกัดด้านเวลา - • Stay private online with our high-speed VPN + • ปกป้องความเป็นส่วนตัวของคุณบนโลกออนไลน์ด้วย VPN ความเร็วสูงของเรา ต้องการคุยต่อนานกว่านี้หรือไม่ สมัครใช้งานแผน Pro จะสามารถโทรได้ไม่อั้น @@ -5115,16 +5104,49 @@ ไม่ใช่ตอนนี้ - This free call will end in %s + การโทรฟรีนี้จะสิ้นสุดลงใน %s - Your free call will end in %d minute - Your free call will end in %d minutes + การโทรฟรีของคุณจะสิ้นสุดลงใน %d นาที หมดอายุในวันที่ %1$s เวลา %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + ผู้เข้าร่วมสามารถเข้าร่วมการโทรได้สูงสุด 100 คนเท่านั้น หากมีผู้เข้าร่วมมากกว่านั้น จะสามารถส่งและรับข้อความได้อย่างเดียว ผู้จัดการประชุมสามารถอัปเกรดเป็นแผน Pro เพื่อยกเลิกข้อจำกัดนี้ได้ ผู้เข้าร่วมสามารถเข้าร่วมการโทรได้สูงสุด 100 คนเท่านั้น หากมีผู้เข้าร่วมเพิ่มเติม จะสามารถส่งและอ่านข้อความในแชทได้เท่านั้น กรุณาขอให้ผู้จัดการประชุมยกเลิกข้อจำกัดนี้ก่อน + + ต่ำ + + ปานกลาง + + สูง + + ต้นฉบับ + + MEGA ไม่สามารถเข้าถึงไมโครโฟนของคุณได้ หากคุณต้องการบันทึกคลิปเสียง ต้องอนุญาต MEGA ให้สามารถเข้าถึงไมโครโฟนของคุณ + + ไม่สามารถเข้าร่วมได้ + + ผู้เข้าร่วมสามารถเข้าร่วมการโทรได้สูงสุด 100 คนเท่านั้น หากมีผู้เข้าร่วมมากกว่านั้น จะสามารถส่งและรับข้อความได้อย่างเดียว ผู้จัดการประชุมสามารถอัปเกรดเป็นแผน Pro เพื่อยกเลิกข้อจำกัดนี้ได้ + + โอเค เข้าใจแล้ว + + ซ่อนไฟล์และโฟลเดอร์ + + ซ่อนไฟล์และโฟลเดอร์สำคัญ + + เก็บไฟล์และโฟลเดอร์ลับไว้ส่วนตัว เฉพาะคุณเท่านั้นที่สามารถดูได้ โดยสามารถเลือกดูทีละรายการ หรือแสดงไฟล์ที่ซ่อนไว้ชั่วคราวจากการตั้งค่า + + ไม่แสดงในไทม์ไลน์ + + รายการที่ซ่อนจะมองเห็นได้เฉพาะในคลาวด์ไดร์ฟเท่านั้น และจะไม่ปรากฏในรูปภาพ อัลบั้ม หรือรายการล่าสุด + + แสดงไฟล์ที่ซ่อนอยู่ + + คุณสามารถเลือกได้ว่าต้องการให้ไฟล์ที่ซ่อนอยู่ปรากฏหรือไม่ มีการตั้งค่าใหม่ที่ช่วยให้คุณแสดงไฟล์ที่ซ่อนอยู่ชั่วคราวได้ + + + %1$d รายการถูกซ่อน + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 81deccd9b0..f81f243f50 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -2573,12 +2573,6 @@ Không thể xóa tên %1$s khỏi sổ liên lạc vì đây là nhân viên trong tài khoản Doanh Nghiệp này. Có vấn đề phát sinh với việc thanh toán gần đây. Xin truy cập MEGA bằng trình duyệt web trên máy tính để biết thêm thông tin. - - Tài khoản đã bị vô hiệu hóa - - Tài khoản Doanh Nghiệp của bạn đã bị vô hiệu hóa do việc thanh toán đã không thành công. Bạn sẽ không thể truy cập vào dữ liệu đã được lưu trữ trong tài khoản của mình. Để thanh toán và kích hoạt lại gói đăng ký của bạn, hãy đăng nhập vào MEGA bằng trình duyệt web. - - Tài khoản của bạn hiện đang bị [B]đình chỉ[/B]. Bạn chỉ có khả năng xem duyệt dữ liệu của mình. MEGA không thể truy cập vào dữ liệu của bạn. Tuy nhiên, chủ điều hành tài khoản doanh nghiệp sẽ có quyền truy cập vào nội dung Đăng Tải Camêra của bạn. @@ -2993,10 +2987,6 @@ Tháng Năm - - - Việc tải lên đang được thực hiện, %1$d tệp đang chờ - Production @@ -4551,8 +4541,6 @@ Mua Pro II Mua Pro III - - Điều Khoản Dịch Vụ Chỉ những người có mật khẩu mới có thể mở đường liên kết @@ -5035,6 +5023,7 @@ Các gói đăng ký được tự động gia hạn cho khoảng thời gian đăng ký kế tiếp có cùng thời lượng và ở cùng mức giá như khoảng thời gian ban đầu đã chọn. Bạn có thể tắt tự động gia hạn gói đăng ký MEGA Pro của mình không được ít hơn 24 giờ trước khi đến kỳ hạn thanh toán cho gói đăng ký tiếp theo thông qua trang Gói thuê bao trong [A]Google Play[/A]. Cho phép truy cập vào thư viện hình ảnh của bạn + Cấp quyền Cần phải cập nhật @@ -5087,7 +5076,7 @@ Thay đổi - Gói miễn phí có giới hạn thời lượng cuộc họp là 60 phút mỗi cuộc. [A]Nâng cấp ngay.[/A] + [A]Gói miễn phí của bạn có giới hạn cuộc họp là 60 phút. Người dùng Pro có thời lượng cuộc gọi không giới hạn và có tối đa 1000 người tham gia.[/A] [B]Nâng cấp ngay bây giờ.[/B] Quý khách sẽ phải chi trả %1$s ngay lập tức và gói đăng ký của quý khách sẽ tự động gia hạn sau 1 tháng với giá %2$s mỗi tháng. Tài khoản Google Play của quý khách sẽ bị tính phí gia hạn trong vòng 24 giờ từ thời điểm kết thúc của mỗi kỳ thanh toán. Để hủy gói đăng ký của mình, quý khách phải tắt tự động gia hạn gói đăng ký MEGA Pro của mình ít nhất là 24 giờ trước lúc kết thúc thời hạn thanh toán trong trang Gói thuê bao của [A]Google Play[/A].\nVới việc nâng cấp tài khoản của mình, quý khách đồng ý với[B]Điều Khoản Dịch Vụ[/B] và [C]Chính Sách Riêng Tư[/C] của MEGA. @@ -5123,7 +5112,42 @@ Hết hạn vào %1$s lúc %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Chỉ có 100 người mới có thể tham gia cuộc gọi. Bất kỳ người tham gia nào thêm sẽ chỉ có thể gửi và đọc các cuộc chat. Yêu cầu ban tổ chức để loại bỏ hạn chế này. + + Thấp + + Thường + + Cao + + Nguyên gốc + + You denied MEGA access to your microphone. If you’d like to record a voice clip, allow MEGA permission to do so. + + Không thể tham gia + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, hiểu rồi + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c6d8bfc98a..02e57f5582 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -772,7 +772,7 @@ 封存 - This is the last step to park your account, please enter your new password. Your data will be retained for at least 60 days. If you recall your parked account’s password, contact support@mega.nz + 这是封存您的帐户的最后一步,请输入您的新密码。您的数据将保留至少60天。在此期间,如果您想起了已封存帐户的密码,联系support@mega.nz 请输入新密码 @@ -1810,7 +1810,7 @@ 下次登录您的帐户时,系统会要求您输入身份验证应用程序中提供的6位数验证码。 - Save your recovery key in a safe location, to avoid issues in case you lose access to your app, or if you want to disable two-factor authentication. + 为避免您无法访问应用程序或想要禁用双重验证时出现问题,请将您的恢复密钥保存到安全的位置。 验证码无效 @@ -2573,12 +2573,6 @@ 您无法移除联系人%1$s,因为他们是您企业帐户的用户。 您的上一笔付款未成功。请使用网络浏览器登录MEGA后获取详情。 - - 帐户已停用 - - 由于付款失败,您的企业帐户已被停用。您将无法访问存储在您帐户中的资料。若要付款并重新激活您的订阅,请通过网页浏览器登入MEGA进行。 - - 您的帐户目前已被[B]暂停[/B]。您只能浏览您的数据。 MEGA无法访问您的数据,而您的企业帐户管理员可以查看并删除您的相机上传文件。 @@ -2993,10 +2987,6 @@ - - - 正在上传,%1$d个文件待上传 - Production @@ -4540,7 +4530,7 @@ • 自动备份 - • Rewind up to 90 days of deleted data on Pro Lite and up to 180 days on Pro I, II, and III + • Pro Lite最多可还原90天已删除的数据,Pro I、II和III则最多可还原180天 • 安排垃圾桶清理工作7天至10年 @@ -4551,8 +4541,6 @@ 购买Pro II 购买Pro III - - 服务条款 只有拥有密码的人才能打开链接 @@ -5035,6 +5023,7 @@ 订阅将自动续订,续订周期与初始选择的周期相同,并且以相同的价格进行续订。您可以在下一次订阅付款到期前24小时以内,通过[A]Google Play[/A]订阅界面关闭MEGA Pro订阅的自动续订功能。 允许访问您的图库 + 授予权限 需要更新 @@ -5059,7 +5048,7 @@ 上传已暂停。电量低于%1$d%%而且不在充电。 - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. + 相机上传功能已停止运行。尝试重新启用相机上传功能来解决问题。如果问题仍然存在,请联系客服人员。 正在相机上传,%1$d个文件待处理 @@ -5069,7 +5058,7 @@ 相机上传完成,%1$d个文件已上传 - [A]Your free plan has a 60-minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] + [A]您的免费方案有60分钟的会议时间限制。Pro会员用户具有无限通话时间,并且最多可达1000名参与者。[/A][B]立即升级。[/B] 隐藏 @@ -5087,7 +5076,7 @@ 更改 - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + [A]您的免费方案有60分钟的会议时间限制。Pro会员用户具有无限通话时间,并且最多可达1000名参与者。[/A][B]立即升级。[/B] 您将被立即收取%1$s的费用,并且您的订阅将在1 个月后自动以每月%2$s续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 @@ -5097,34 +5086,68 @@ 您将立即被收取费用,并且您的订阅将在12 个月后自动续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 - Business account deactivated + 企业帐户已停用 - Your Business account has been deactivated due to payment failure. You can only browse your data.\nAsk your Business account administrator to resolve the issue. + 由于付款失败,您的企业帐户已被停用。您只能浏览您的数据。\n请您的企业帐户管理员解决此问题。 - Your Business account has been deactivated due to payment failure. You can only browse your data.\nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + 由于付款失败,您的企业帐户已被停用。您只能浏览您的数据。\n若要付款并重新激活您的订阅,请通过浏览器登入MEGA。 好的,明白了 - • Host calls and meetings with unlimited participants and no time restrictions + • 主持通话和会议,参与者人数和通话时间无限 - • Stay private online with our high-speed VPN + • 使用我们的高速VPN保持在线隐私 - Need more time? Pro plans have unlimited calls. + 需要更多时间?Pro方案具有无限通话。 升级为Pro帐户 现在不用 - This free call will end in %s + 此免费通话将在%s结束 - Your free call will end in %d minute - Your free call will end in %d minutes + 您的免费通话将在%d分钟后结束 %1$s%2$s到期 - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. 只有100位 参与者可以加入通话。任何其他参与者将只能发送和阅读聊天记录。请求组织者取消此限制。 + + + + + + + + 原画 + + 您拒绝MEGA访问您的麦克风。如果您想录制语音片段,请授予MEGA权限。 + + 无法加入 + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + 好的,明白了 + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9648036997..79bf40e585 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -2573,12 +2573,6 @@ 您無法以刪除聯絡人的方式刪除%1$s,因為他們是您商業帳戶的成員之一。 您最近一次的付款發生問題。請使用電腦版瀏覽器登入MEGA以查看更多訊息。 - - 帳戶已停用 - - 由於付款失敗,您的商業帳戶已被停用。您將無法存取儲存在您帳戶中的資料。若要付款並重新啟用您的訂閱,請透過網頁瀏覽器登入MEGA進行。 - - 您的帳戶目前[B]暫停使用[/B]。您只能瀏覽您的資料。 MEGA無法存取您的資料。然而,您的商業帳戶管理員可以存取您的相機上傳。 @@ -2993,10 +2987,6 @@ - - - 正在上傳,%1$d個待處理檔案 - 生產力 @@ -3752,7 +3742,7 @@ 不允許使用此相簿名稱。請輸入不同的名稱。 - 已存在有此名稱的相簿。請輸入不同的名稱。 + 已存在具有此名稱的相簿。請輸入不同的名稱。 新增項目到「%s」 @@ -4551,8 +4541,6 @@ 購買Pro II 購買Pro III - - 服務條款 只有擁有密碼的人才能開啟連結 @@ -5035,6 +5023,7 @@ 訂閱會自動續訂,續訂的訂閱期間與初始選擇的周期相同,價格也相同。您可以在下次訂閱付款到期前24小時內,透過[A]Google Play[/A]中的訂閱關閉MEGA Pro訂閱的自動續訂功能。 允許存取您的相簿 + 授予權限 需要更新 @@ -5087,7 +5076,7 @@ 變更 - 免費方案每次會議有60分鐘的限制。[A]立即升級。[/A] + [A]您的免費方案有60分鐘的會議時間限制。Pro會員的通話時間不受限制,而且最多可容納1000位與會者。[/A][B]立即升級。[/B] 您將立即被收取%1$s的費用,而且您的訂閱將在1 個月後自動以每月%2$s續訂。您的Google Play帳戶將在每個計費週期結束後24 小時內被收取續訂費用。若要取消訂閱,您必須在計費週期結束前至少24 小時透過[A]Google Play[/A]中的訂閱停用MEGA Pro訂閱的自動續訂。\n升級您的帳戶即表示您同意MEGA的[B]服務條款[/B]和[C]隱私權政策[/C]。 @@ -5123,7 +5112,42 @@ %1$s%2$s到期 - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. 只有100個與會者可以加入通話。任何其他與會者將只能發送和讀取對話記錄。請召集人取消此限制。 + + + + 普通 + + + + 原始檔 + + 您拒絕MEGA存取您的麥克風。如果您想錄製語音片段,請授予MEGA權限。 + + 無法登入 + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + 好的,明白了 + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae70a90b3d..5c6f339065 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ - + Pro Lite @@ -2641,12 +2641,6 @@ You cannot remove %1$s as a contact because they are part of your Business account. A problem occurred with your last payment. Please access MEGA using a desktop browser for more information. - - Account deactivated - - Your Business account has been deactivated due to payment failure. You won’t be able to access the data stored in your account. To make a payment and reactivate your subscription, log in to MEGA through a browser. - - Your account is currently [B]suspended[/B]. You can only browse your data. MEGA cannot access your data. However, your Business account administrator can access your Camera uploads. @@ -3071,11 +3065,6 @@ Months Years - - - Upload in progress, %1$d file pending - Upload in progress, %1$d files pending - Production @@ -4770,8 +4759,6 @@ Buy Pro II Buy Pro III - - Terms of Service Only people with the password can open the link @@ -5276,6 +5263,7 @@ Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen. You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. Allow access to your gallery + Grant access Update required @@ -5330,7 +5318,7 @@ Change - Free plans have a limit of 60 minutes per meeting. [A]Upgrade now.[/A] + [A]Your free plan has a 60-minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. @@ -5367,7 +5355,42 @@ Expires on %1$s at %2$s - [A]As a free user, you can only add up to 100 participants to this call. Need more?[/A] [B]Upgrade now[/B] + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. Only 100 participants can join the call. Any additional participants will only be able to send and read chats. Ask the organiser to remove this restriction. + + Low + + Medium + + High + + Original + + You denied MEGA access to your microphone. If you’d like to record a voice clip, allow MEGA permission to do so. + + Cannot join + + Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + + OK, got it + + Hidden files and folders + + Hide important files and folders + + You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + + Exclude from Timeline + + Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + + Out of sight + + You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + + + %1$d item hidden + %1$d items hidden + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 5b6a408753..9ae60eba1c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -82,7 +82,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "34.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240320.031033-rel" +extra["megaSdkVersion"] = "20240327.042257-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml index ed882f7574..be8e4c67d0 100644 --- a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml @@ -178,8 +178,9 @@ - %1$d folder - %1$d folders + %1$d dossier + %1$d de dossiers + %1$d dossiers diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index 37d4b9f3bd..168f1d6000 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -178,8 +178,9 @@ - %1$d folder - %1$d folders + %1$d cartella + %1$d di cartelle + %1$d cartelle diff --git a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml index c74548788c..2eb444eebe 100644 --- a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml @@ -176,8 +176,7 @@ - %1$d folder - %1$d folders + %1$d个文件夹 diff --git a/sdk/src/main/jni/megachat/sdk b/sdk/src/main/jni/megachat/sdk index 1a1e0f5dcf..ba8b607181 160000 --- a/sdk/src/main/jni/megachat/sdk +++ b/sdk/src/main/jni/megachat/sdk @@ -1 +1 @@ -Subproject commit 1a1e0f5dcfd04703f55f58ef36d4c5338c9b51d5 +Subproject commit ba8b607181df99d04a3855cd3015eca05956d937 From 00c66c507f7c79b18b1f3372f703b1737f6d4a6e Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Wed, 27 Mar 2024 21:07:52 +1300 Subject: [PATCH 058/261] SAT-817 (T15408114) Fix keyboard not showing up on search bar open bug --- .../core/ui/controls/appbar/LegacySearchAppBar.kt | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt index bdddc34421..ce67653c56 100644 --- a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt +++ b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt @@ -20,9 +20,8 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.remember -import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -31,7 +30,6 @@ import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.compose.ui.platform.LocalWindowInfo import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle @@ -234,13 +232,8 @@ fun ExpandedSearchAppBar( ) ) - val windowInfo = LocalWindowInfo.current - LaunchedEffect(windowInfo) { - snapshotFlow { windowInfo.isWindowFocused }.collect { isWindowFocused -> - if (isWindowFocused) { - focusRequester.requestFocus() - } - } + SideEffect { + focusRequester.requestFocus() } } } From a45805127caa6f08fdba47ee6e0b40e0857f8869 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 28 Mar 2024 16:44:02 +1300 Subject: [PATCH 059/261] T15414632: Fix archive and unarchive behavior in chat --- .../meeting/chat/model/ActionToManage.kt | 8 ++++-- .../meeting/chat/model/ChatViewModel.kt | 25 ++++++++++++++++++- .../meeting/chat/view/ChatView.kt | 2 ++ .../meeting/chat/ChatViewModelTest.kt | 15 ++++++++--- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ActionToManage.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ActionToManage.kt index b4b0d388c8..b01759636d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ActionToManage.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ActionToManage.kt @@ -1,7 +1,5 @@ package mega.privacy.android.app.presentation.meeting.chat.model -import mega.privacy.android.domain.entity.chat.messages.TypedMessage - /** * Sealed class defining all the possible actions to manage in view. */ @@ -25,4 +23,10 @@ sealed class ActionToManage { * @property email Contact email. */ data class OpenContactInfo(val email: String) : ActionToManage() + + /** + * Close chat + * + */ + data object CloseChat : ActionToManage() } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt index 7658457d32..58adce64bf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt @@ -69,6 +69,7 @@ import mega.privacy.android.domain.usecase.MonitorChatRoomUpdates import mega.privacy.android.domain.usecase.account.MonitorStorageStateEventUseCase import mega.privacy.android.domain.usecase.cache.GetCacheFileUseCase import mega.privacy.android.domain.usecase.chat.ArchiveChatUseCase +import mega.privacy.android.domain.usecase.chat.BroadcastChatArchivedUseCase import mega.privacy.android.domain.usecase.chat.ClearChatHistoryUseCase import mega.privacy.android.domain.usecase.chat.CloseChatPreviewUseCase import mega.privacy.android.domain.usecase.chat.EnableGeolocationUseCase @@ -188,6 +189,7 @@ class ChatViewModel @Inject constructor( private val unmuteChatNotificationUseCase: UnmuteChatNotificationUseCase, private val clearChatHistoryUseCase: ClearChatHistoryUseCase, private val archiveChatUseCase: ArchiveChatUseCase, + private val broadcastChatArchivedUseCase: BroadcastChatArchivedUseCase, private val endCallUseCase: EndCallUseCase, private val sendStatisticsMeetingsUseCase: SendStatisticsMeetingsUseCase, private val startCallUseCase: StartCallUseCase, @@ -845,7 +847,16 @@ class ChatViewModel @Inject constructor( fun archiveChat() { viewModelScope.launch { runCatching { archiveChatUseCase(chatId, true) } - .onFailure { + .onSuccess { + broadcastChatArchivedUseCase(_state.value.title.orEmpty()) + _state.update { state -> + state.copy( + actionToManageEvent = triggered( + ActionToManage.CloseChat + ) + ) + } + }.onFailure { Timber.e("Error archiving chat $it") _state.update { state -> state.copy( @@ -867,6 +878,18 @@ class ChatViewModel @Inject constructor( fun unarchiveChat() { viewModelScope.launch { runCatching { archiveChatUseCase(chatId, false) } + .onSuccess { + _state.update { state -> + state.copy( + infoToShowEvent = triggered( + InfoToShow.StringWithParams( + stringId = R.string.success_unarchive_chat, + args = state.title?.let { title -> listOf(title) }.orEmpty() + ) + ) + ) + } + } .onFailure { Timber.e("Error unarchiving chat $it") _state.update { state -> diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/ChatView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/ChatView.kt index 78ad6e7057..a858b2effa 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/ChatView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/ChatView.kt @@ -1015,6 +1015,8 @@ internal fun ChatView( context, action.email ) + + is ActionToManage.CloseChat -> onBackPressed() } } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt index 3fb3958ae1..8ab8222bec 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/ChatViewModelTest.kt @@ -76,6 +76,7 @@ import mega.privacy.android.domain.usecase.MonitorChatRoomUpdates import mega.privacy.android.domain.usecase.account.MonitorStorageStateEventUseCase import mega.privacy.android.domain.usecase.cache.GetCacheFileUseCase import mega.privacy.android.domain.usecase.chat.ArchiveChatUseCase +import mega.privacy.android.domain.usecase.chat.BroadcastChatArchivedUseCase import mega.privacy.android.domain.usecase.chat.ClearChatHistoryUseCase import mega.privacy.android.domain.usecase.chat.CloseChatPreviewUseCase import mega.privacy.android.domain.usecase.chat.EnableGeolocationUseCase @@ -301,6 +302,7 @@ internal class ChatViewModelTest { on { invoke() } doReturn emptyFlow() } private val leaveChatUseCase = mock() + private val broadcastChatArchivedUseCase = mock() @BeforeEach @@ -364,7 +366,8 @@ internal class ChatViewModelTest { getCacheFileUseCase, recordAudioUseCase, deleteFileUseCase, - leaveChatUseCase + leaveChatUseCase, + broadcastChatArchivedUseCase ) whenever(savedStateHandle.get(Constants.CHAT_ID)).thenReturn(chatId) wheneverBlocking { isAnonymousModeUseCase() } doReturn false @@ -470,7 +473,8 @@ internal class ChatViewModelTest { recordAudioUseCase = recordAudioUseCase, deleteFileUseCase = deleteFileUseCase, leaveChatUseCase = leaveChatUseCase, - monitorLeaveChatUseCase = monitorLeaveChatUseCase + monitorLeaveChatUseCase = monitorLeaveChatUseCase, + broadcastChatArchivedUseCase = broadcastChatArchivedUseCase ) } @@ -1750,6 +1754,7 @@ internal class ChatViewModelTest { fun `test that archive finish with error and shows it`() = runTest { whenever(archiveChatUseCase(chatId = chatId, true)).thenThrow(RuntimeException()) underTest.archiveChat() + verifyNoInteractions(broadcastChatArchivedUseCase) underTest.state.test { val result = ((awaitItem().infoToShowEvent as StateEventWithContentTriggered).content as InfoToShow.StringWithParams).stringId @@ -1761,8 +1766,12 @@ internal class ChatViewModelTest { fun `test that archive finish with success`() = runTest { whenever(archiveChatUseCase(chatId = chatId, true)).thenReturn(Unit) underTest.archiveChat() + verify(broadcastChatArchivedUseCase).invoke(any()) underTest.state.test { - assertThat(awaitItem().infoToShowEvent) + val item = awaitItem() + assertThat((item.actionToManageEvent as StateEventWithContentTriggered).content) + .isInstanceOf(ActionToManage.CloseChat::class.java) + assertThat(item.infoToShowEvent) .isInstanceOf(StateEventWithContentConsumed::class.java) } } From 0687864f314aee1b8187ce904f6a0b7e71998abb Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Mon, 1 Apr 2024 08:59:43 +0600 Subject: [PATCH 060/261] AND-18487: Remove singleTask launch mode removed --- app/src/main/AndroidManifest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ca908690cd..7a14fcbcbd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -344,7 +344,6 @@ android:windowSoftInputMode="stateHidden|adjustResize" /> @@ -718,4 +717,4 @@ android:windowSoftInputMode="stateHidden|adjustResize" /> - \ No newline at end of file + From 309373fc6c334a44d7be1ca10ee73f830104cb6a Mon Sep 17 00:00:00 2001 From: mega-vap Date: Fri, 29 Mar 2024 23:14:44 +0700 Subject: [PATCH 061/261] AND-18512: AND - "Phone Contacts" are duplicated and overlapping texts when adding contacts --- .../android/app/main/InviteContactActivity.java | 6 ++---- .../android/app/main/InviteContactViewModel.kt | 7 ++++--- .../android/app/main/InviteContactViewModelTest.kt | 13 ++----------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/InviteContactActivity.java b/app/src/main/java/mega/privacy/android/app/main/InviteContactActivity.java index da0876af54..2a76b76ca5 100644 --- a/app/src/main/java/mega/privacy/android/app/main/InviteContactActivity.java +++ b/app/src/main/java/mega/privacy/android/app/main/InviteContactActivity.java @@ -334,10 +334,8 @@ public void onRequestTemporaryError(@NonNull MegaApiJava api, @NonNull MegaReque private void collectFlows() { ViewExtensionsKt.collectFlow(this, viewModel.getFilterUiState(), Lifecycle.State.STARTED, filterUiState -> { - if (!filterUiState.getFilteredContacts().isEmpty()) { - refreshList(); - visibilityFastScroller(); - } + refreshList(); + visibilityFastScroller(); return Unit.INSTANCE; }); } diff --git a/app/src/main/java/mega/privacy/android/app/main/InviteContactViewModel.kt b/app/src/main/java/mega/privacy/android/app/main/InviteContactViewModel.kt index fa38ec204b..80af3604fe 100644 --- a/app/src/main/java/mega/privacy/android/app/main/InviteContactViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/main/InviteContactViewModel.kt @@ -172,8 +172,8 @@ class InviteContactViewModel @Inject constructor( } _filterUiState.update { - it.copy( - filteredContacts = listOf( + val newFilteredContacts = if (phoneContacts.isNotEmpty()) { + listOf( // Header InvitationContactInfo( ID_PHONE_CONTACTS_HEADER, @@ -181,7 +181,8 @@ class InviteContactViewModel @Inject constructor( TYPE_PHONE_CONTACT_HEADER ) ).plus(phoneContacts) - ) + } else emptyList() + it.copy(filteredContacts = newFilteredContacts) } } } diff --git a/app/src/test/java/mega/privacy/android/app/main/InviteContactViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/main/InviteContactViewModelTest.kt index 48dbfc4573..0f655039ec 100644 --- a/app/src/test/java/mega/privacy/android/app/main/InviteContactViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/main/InviteContactViewModelTest.kt @@ -130,21 +130,12 @@ class InviteContactViewModelTest { } @Test - fun `test that the filtered contact list contains only a header item when there are no contacts available`() = + fun `test that an empty list is returned as the filtered contacts when there are no contacts available`() = runTest { - whenever(context.getString(R.string.contacts_phone)).thenReturn("Phone contacts") - underTest.filterContacts("query") underTest.filterUiState.test { - val expected = listOf( - InvitationContactInfo( - ID_PHONE_CONTACTS_HEADER, - "Phone contacts", - TYPE_PHONE_CONTACT_HEADER - ) - ) - assertThat(expectMostRecentItem().filteredContacts).isEqualTo(expected) + assertThat(expectMostRecentItem().filteredContacts).isEqualTo(emptyList()) } } From 633702eb48f2fe6b7d6921b240dbb8ad6c9c0fa7 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Tue, 2 Apr 2024 15:27:52 +1300 Subject: [PATCH 062/261] AND-18487: Revert launchMode to singleTask and introduce onNewIntent --- app/src/main/AndroidManifest.xml | 1 + .../meeting/chat/ChatHostActivity.kt | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7a14fcbcbd..c521b1acd1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -344,6 +344,7 @@ android:windowSoftInputMode="stateHidden|adjustResize" /> diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatHostActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatHostActivity.kt index 5b622aa364..13d506131b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatHostActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatHostActivity.kt @@ -1,10 +1,14 @@ package mega.privacy.android.app.presentation.meeting.chat +import android.content.Intent import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.view.WindowCompat import androidx.fragment.app.commit import dagger.hilt.android.AndroidEntryPoint +import mega.privacy.android.app.presentation.meeting.chat.model.EXTRA_LINK +import mega.privacy.android.app.presentation.meeting.chat.view.navigation.openChatFragment +import mega.privacy.android.app.utils.Constants /** * Host Activity for new chat room @@ -25,4 +29,16 @@ class ChatHostActivity : AppCompatActivity() { } } } -} \ No newline at end of file + + /** + * Handle the intent to open chat room + */ + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + val chatId = intent?.getLongExtra(Constants.CHAT_ID, -1L) + val link = intent?.getStringExtra(EXTRA_LINK) + chatId?.let { + openChatFragment(this, chatId = it, chatLink = link) + } + } +} From a1d671eb2d5dbae4bb35914fbcca57977311ea1b Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 2 Apr 2024 16:47:59 +0700 Subject: [PATCH 063/261] T15424336: Can't send a message from meeting screen (cherry picked from commit dd9b0f3db219a10e2dfd082555e8fa4d3d023151) --- .../fragments/MeetingParticipantBottomSheetDialogFragment.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/fragments/MeetingParticipantBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/meeting/fragments/MeetingParticipantBottomSheetDialogFragment.kt index 6469e8a6ec..8167bc0404 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/fragments/MeetingParticipantBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/fragments/MeetingParticipantBottomSheetDialogFragment.kt @@ -19,7 +19,8 @@ import mega.privacy.android.app.modalbottomsheet.BaseBottomSheetDialogFragment import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.ContactUtil import mega.privacy.android.navigation.MegaNavigator -import nz.mega.sdk.* +import nz.mega.sdk.MegaChatApiJava +import nz.mega.sdk.MegaChatRoom import javax.inject.Inject /** @@ -113,7 +114,7 @@ class MeetingParticipantBottomSheetDialogFragment : BaseBottomSheetDialogFragmen listenAction(binding.sendMessage) { // Open chat page val chatId = bottomViewModel.sendMessage() - if (chatId > 0L) { + if (chatId != -1L) { navigator.openChat( context = requireActivity(), chatId = chatId, From 15af5feac120c87981d24e3368de88b2323d44e9 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Wed, 3 Apr 2024 15:59:02 +0700 Subject: [PATCH 064/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 92852be0cb..d26a94f8a6 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240319.060714" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 004d864589d37abf6fd79785ae190e6e91fb0437 Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Thu, 4 Apr 2024 10:30:26 +0600 Subject: [PATCH 065/261] AND-18567: Fix T15672937 - Placeholder text is shown in skeleton of Photos --- .../timeline/view/PhotosSkeletonView.kt | 109 +++++++++++++++--- 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/PhotosSkeletonView.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/PhotosSkeletonView.kt index 7ff9f6813b..a45b5acb48 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/PhotosSkeletonView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/PhotosSkeletonView.kt @@ -1,6 +1,7 @@ package mega.privacy.android.app.presentation.photos.timeline.view import android.content.res.Configuration +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -18,14 +19,19 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.utils.shimmerEffect +import mega.privacy.android.shared.theme.MegaAppTheme @Composable internal fun PhotosSkeletonView() { @@ -61,7 +67,8 @@ internal fun PhotosSkeletonView() { modifier = Modifier .wrapContentSize() .padding(start = 16.dp, top = 14.dp, bottom = 14.dp) - .shimmerEffect(), + .shimmerEffectSquare(), + color = Color.Transparent ) } } else { @@ -70,7 +77,7 @@ internal fun PhotosSkeletonView() { .padding(all = 1.5.dp) .fillMaxWidth() .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) } } @@ -107,20 +114,22 @@ internal fun AlbumListSkeletonView() { .padding(all = 1.5.dp) .fillMaxWidth() .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Text( text = "Album names", modifier = Modifier .wrapContentSize() .padding(top = 10.dp, bottom = 3.dp) - .shimmerEffect(), + .shimmerEffectSquare(), + color = Color.Transparent ) Text( text = "number", modifier = Modifier .wrapContentSize() - .shimmerEffect(), + .shimmerEffectSquare(), + color = Color.Transparent ) } } @@ -161,7 +170,7 @@ private fun AlbumBig2SmallSkeletonView( .width(smallWidth * 2) .height(smallWidth * 2 + 1.dp) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Column( verticalArrangement = Arrangement.SpaceBetween, @@ -171,7 +180,7 @@ private fun AlbumBig2SmallSkeletonView( .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Spacer( modifier = Modifier.height(1.dp) @@ -181,7 +190,7 @@ private fun AlbumBig2SmallSkeletonView( .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) } } @@ -200,21 +209,21 @@ private fun AlbumSmall3ItemSkeletonView( .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Spacer( modifier = Modifier .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Spacer( modifier = Modifier .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) } } @@ -235,7 +244,7 @@ private fun AlbumSmall2BigSkeletonView( .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) Spacer( modifier = Modifier.height(1.dp) @@ -245,7 +254,7 @@ private fun AlbumSmall2BigSkeletonView( .width(smallWidth) .height(smallWidth) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) } Spacer( @@ -253,7 +262,79 @@ private fun AlbumSmall2BigSkeletonView( .width(smallWidth * 2) .height(smallWidth * 2 + 1.dp) .aspectRatio(1f) - .shimmerEffect(), + .shimmerEffectSquare(), ) } } + +private fun Modifier.shimmerEffectSquare(): Modifier { + return this.shimmerEffect( + shape = RoundedCornerShape(4.dp) + ) +} + +@CombinedThemePreviews +@Composable +private fun PhotosSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + PhotosSkeletonView() + } +} + +@CombinedThemePreviews +@Composable +private fun AlbumListSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + AlbumListSkeletonView() + } +} + +@CombinedThemePreviews +@Composable +private fun AlbumContentSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + val configuration = LocalConfiguration.current + val smallWidth = remember(configuration) { + (configuration.screenWidthDp.dp - 1.dp) / 3 + } + AlbumContentSkeletonView(smallWidth) + } +} + +@CombinedThemePreviews +@Composable +private fun AlbumBig2SmallSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + val configuration = LocalConfiguration.current + val smallWidth = remember(configuration) { + (configuration.screenWidthDp.dp - 1.dp) / 3 + } + AlbumBig2SmallSkeletonView(smallWidth) + } +} + +@CombinedThemePreviews +@Composable +private fun AlbumSmall3ItemSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + val configuration = LocalConfiguration.current + val smallWidth = remember(configuration) { + (configuration.screenWidthDp.dp - 1.dp) / 3 + } + AlbumSmall3ItemSkeletonView(smallWidth) + } +} + + +@CombinedThemePreviews +@Composable +private fun AlbumSmall2BigSkeletonViewPreview() { + MegaAppTheme(isDark = isSystemInDarkTheme()) { + val configuration = LocalConfiguration.current + val smallWidth = remember(configuration) { + (configuration.screenWidthDp.dp - 1.dp) / 3 + } + AlbumSmall2BigSkeletonView(smallWidth) + } +} + From 772aefcf51a72265c6b308d14cc3548db888717e Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Thu, 4 Apr 2024 10:51:25 +0530 Subject: [PATCH 066/261] SAO-52: (T15424038,T15423978) Enable feature flag for new search activity --- .../app/presentation/search/SearchActivity.kt | 23 +++------ .../search/SearchActivityViewModel.kt | 44 ++++++++++++++-- .../search/model/SearchActivityState.kt | 4 +- .../search/view/SearchComposeView.kt | 10 ++-- .../presentation/search/view/SearchToolbar.kt | 47 ++++++++++++++--- .../model/SearchActivityViewModelTest.kt | 24 +++++++++ .../usecase/search/SearchNodesUseCase.kt | 51 ++++++++++++++----- .../ui/controls/appbar/LegacySearchAppBar.kt | 33 +++++++----- 8 files changed, 178 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt index 833bdd778b..90fbe6ecea 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt @@ -292,7 +292,11 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { coroutineScope.launch { when (it) { is TypedFileNode -> openFileClicked(it) - is TypedFolderNode -> openFolderClicked(it.id.longValue) + is TypedFolderNode -> viewModel.openFolder( + folderHandle = it.id.longValue, + name = it.name + ) + else -> Timber.e("Unsupported click") } } @@ -300,6 +304,8 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { onBackPressed = { if (viewModel.state.value.selectedNodes.isNotEmpty()) { viewModel.clearSelection() + } else if (viewModel.state.value.navigationLevel.isNotEmpty()) { + viewModel.navigateBack() } else { onBackPressedDispatcher.onBackPressed() } @@ -376,21 +382,6 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { startActivity(launchBrowser) } - /** - * On Item click event received from [FileBrowserViewModel] - * - * @param folderHandle FolderHandle of current selected Folder - */ - private fun openFolderClicked(folderHandle: Long?) { - folderHandle?.let { - val intent = Intent().apply { - putExtra(SEARCH_NODE_HANDLE, it) - } - setResult(RESULT_OK, intent) - finish() - } - } - /** * On Item click event received from [FileBrowserViewModel] * diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index 77148eefba..f0098be29e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -165,8 +165,8 @@ class SearchActivityViewModel @Inject constructor( cancelCancelTokenUseCase() if (state.value.dropdownChipsEnabled == true) { searchNodesUseCase( - query = state.value.searchQuery, - parentHandle = parentHandle, + query = getCurrentSearchQuery(), + parentHandle = getCurrentParentHandle(), nodeSourceType = nodeSourceType, isFirstLevel = isFirstLevel, searchCategory = typeFilterToSearchMapper(state.value.typeSelectedFilterOption), @@ -175,8 +175,8 @@ class SearchActivityViewModel @Inject constructor( ) } else { searchNodesUseCase( - query = state.value.searchQuery, - parentHandle = parentHandle, + query = getCurrentSearchQuery(), + parentHandle = getCurrentParentHandle(), nodeSourceType = nodeSourceType, isFirstLevel = isFirstLevel, searchCategory = state.value.selectedFilter?.filter ?: SearchCategory.ALL @@ -190,6 +190,13 @@ class SearchActivityViewModel @Inject constructor( } } + //If folder is opened from search screen we are setting query as empty + private fun getCurrentSearchQuery() = + state.value.searchQuery.takeIf { state.value.navigationLevel.isEmpty() }.orEmpty() + + private fun getCurrentParentHandle() = + state.value.navigationLevel.lastOrNull()?.first ?: parentHandle + private fun onSearchFailure(ex: Throwable) { if (ex is CancellationException) { return @@ -505,4 +512,33 @@ class SearchActivityViewModel @Inject constructor( it.copy(resetScroll = consumed) } } + + /** + * Open folder from search screen + * + * @param folderHandle folder handle + * @param name folder name + */ + fun openFolder(folderHandle: Long, name: String) { + val list = _state.value.navigationLevel.toMutableList() + list.add(Pair(folderHandle, name)) + _state.update { state -> + state.copy(navigationLevel = list) + } + performSearch() + } + + /** + * Handle back press + * + * navigates back to previous folder + */ + fun navigateBack() { + val list = _state.value.navigationLevel.toMutableList() + list.remove(list.last()) + _state.update { state -> + state.copy(navigationLevel = list) + } + performSearch() + } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt index 6c9879672f..df7c2861e3 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt @@ -37,6 +37,7 @@ import mega.privacy.android.domain.entity.search.TypeFilterOption * @property nodeNameCollisionResult result of node name collision * @property moveRequestResult result of move request * @property resetScroll to reset scroll position + * @property navigationLevel list of parent handles */ data class SearchActivityState( val dropdownChipsEnabled: Boolean? = null, @@ -58,5 +59,6 @@ data class SearchActivityState( val nodeSourceType: NodeSourceType = NodeSourceType.OTHER, val nodeNameCollisionResult: NodeNameCollisionResult? = null, val moveRequestResult: Result? = null, - val resetScroll: StateEvent = consumed + val resetScroll: StateEvent = consumed, + val navigationLevel: List> = emptyList(), ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index 90ffbcf7aa..441ee3978d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.testTagsAsResourceId +import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import de.palm.composestateevents.EventEffect @@ -89,7 +90,7 @@ fun SearchComposeView( val gridState = rememberLazyGridState() val scaffoldState = rememberScaffoldState() val snackBarHostState = remember { SnackbarHostState() } - + var topBarPadding by remember { mutableStateOf(0.dp) } var searchQuery by rememberSaveable { mutableStateOf(state.searchQuery) } @@ -104,6 +105,8 @@ fun SearchComposeView( listState.scrollToItem(0) gridState.scrollToItem(0) } + topBarPadding = + if (state.navigationLevel.isNotEmpty() && state.nodeSourceType != NodeSourceType.CLOUD_DRIVE && state.nodeSourceType != NodeSourceType.HOME) 8.dp else 0.dp state.errorMessageId?.let { val errorMessage = stringResource(id = it) @@ -132,7 +135,8 @@ fun SearchComposeView( navHostController = navHostController, nodeActionHandler = nodeActionHandler, clearSelection = clearSelection, - nodeSourceType = state.nodeSourceType + nodeSourceType = state.nodeSourceType, + navigationLevel = state.navigationLevel ) }, snackbarHost = { @@ -141,7 +145,7 @@ fun SearchComposeView( } } ) { padding -> - Column { + Column(modifier = Modifier.padding(top = topBarPadding)) { if (state.nodeSourceType == NodeSourceType.CLOUD_DRIVE || state.nodeSourceType == NodeSourceType.HOME) { FilterChipsView(state, onFilterClicked, updateFilter, trackAnalytics) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchToolbar.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchToolbar.kt index 96785ce00b..c243609c9f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchToolbar.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchToolbar.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavHostController @@ -14,11 +15,14 @@ import mega.privacy.android.app.presentation.node.NodeActionHandler import mega.privacy.android.app.presentation.node.view.ToolbarMenuItem import mega.privacy.android.app.presentation.node.view.toolbar.NodeToolbarViewModel import mega.privacy.android.app.presentation.search.SearchActivity +import mega.privacy.android.app.presentation.search.navigation.nodeBottomSheetRoute import mega.privacy.android.core.ui.controls.appbar.SelectModeAppBar import mega.privacy.android.core.ui.model.MenuActionWithClick +import mega.privacy.android.core.ui.model.MenuActionWithIcon import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.domain.entity.node.NodeSourceType import mega.privacy.android.domain.entity.node.TypedNode +import mega.privacy.android.legacy.core.ui.controls.appbar.CollapsedSearchAppBar import mega.privacy.android.legacy.core.ui.controls.appbar.ExpandedSearchAppBar import mega.privacy.android.shared.theme.MegaAppTheme @@ -47,6 +51,7 @@ fun SearchToolBar( clearSelection: () -> Unit, nodeSourceType: NodeSourceType, toolbarViewModel: NodeToolbarViewModel = hiltViewModel(), + navigationLevel: List>, ) { LaunchedEffect(key1 = selectedNodes.size) { toolbarViewModel.updateToolbarState( @@ -65,6 +70,7 @@ fun SearchToolBar( navHostController = navHostController, handler = nodeActionHandler, clearSelection = clearSelection, + navigationLevel = navigationLevel.lastOrNull(), ) } @@ -78,6 +84,7 @@ private fun SearchToolbarBody( navHostController: NavHostController, handler: NodeActionHandler, clearSelection: () -> Unit, + navigationLevel: Pair?, ) { val scope = rememberCoroutineScope() if (selectedNodes.isNotEmpty()) { @@ -98,13 +105,36 @@ private fun SearchToolbarBody( onNavigationPressed = { onBackPressed() } ) } else { - ExpandedSearchAppBar( - text = searchQuery, - hintId = R.string.hint_action_search, - onSearchTextChange = { updateSearchQuery(it) }, - onCloseClicked = { onBackPressed() }, - elevation = false - ) + val moreAction = object : MenuActionWithIcon { + @Composable + override fun getIconPainter() = painterResource(id = R.drawable.ic_more) + + @Composable + override fun getDescription() = "" + override val testTag: String = "moreAction" + } + if (navigationLevel?.second?.isNotEmpty() == true) { + CollapsedSearchAppBar( + onBackPressed = { onBackPressed() }, + elevation = true, + showSearchButton = false, + title = navigationLevel.second, + actions = listOf(moreAction), + onActionPressed = { + navHostController.navigate( + route = nodeBottomSheetRoute.plus("/${navigationLevel.first}") + ) + } + ) + } else { + ExpandedSearchAppBar( + text = searchQuery, + hintId = R.string.hint_action_search, + onSearchTextChange = { updateSearchQuery(it) }, + onCloseClicked = { onBackPressed() }, + elevation = false + ) + } } } @@ -123,7 +153,8 @@ private fun PreviewSearchToolbarBody() { LocalContext.current as SearchActivity, hiltViewModel(), ), - clearSelection = {} + clearSelection = {}, + navigationLevel = null, ) } } \ No newline at end of file diff --git a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt index a61529966d..93f44d79ce 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt @@ -430,6 +430,30 @@ class SearchActivityViewModelTest { ) } + @Test + fun `test that navigation level is updated when open folder and navigate back is clicked`() = + runTest { + val typedFolderNode = mock { + on { id }.thenReturn(NodeId(345L)) + on { name }.thenReturn("folder node") + } + whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) + whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) + underTest.onSortOrderChanged() + underTest.openFolder(typedFolderNode.id.longValue, typedFolderNode.name) + underTest.state.test { + val state = awaitItem() + assertThat(state.navigationLevel.size).isEqualTo(1) + } + + underTest.navigateBack() + underTest.state.test { + val state = awaitItem() + assertThat(state.navigationLevel.size).isEqualTo(0) + } + + } + @AfterEach fun tearDown() { nodeList.clear() diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/SearchNodesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/SearchNodesUseCase.kt index ab2fe253cb..4f9cbe4080 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/SearchNodesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/SearchNodesUseCase.kt @@ -61,7 +61,8 @@ class SearchNodesUseCase @Inject constructor( parentNodeId = NodeId(longValue = parentHandle), order = getCloudSortOrder() ) - return when (nodeSourceType) { + + return if (parentHandle == invalidNodeHandle) return when (nodeSourceType) { NodeSourceType.INCOMING_SHARES -> incomingSharesTabSearchUseCase(query = query) NodeSourceType.OUTGOING_SHARES -> outgoingSharesTabSearchUseCase(query = query) NodeSourceType.LINKS -> linkSharesTabSearchUseCase( @@ -69,17 +70,43 @@ class SearchNodesUseCase @Inject constructor( isFirstLevel = isFirstLevel ) - else -> { - val node = getSearchParentNode(nodeSourceType, parentHandle, invalidNodeHandle) - searchInNodesUseCase( - nodeId = node?.id, - query = query, - searchCategory = searchCategory, - modificationDate = modificationDate, - creationDate = creationDate, - ) - } - } + else -> searchInNodes( + nodeSourceType = nodeSourceType, + parentHandle = parentHandle, + invalidNodeHandle = invalidNodeHandle, + query = query, + searchCategory = searchCategory, + modificationDate = modificationDate, + creationDate = creationDate + ) + } else searchInNodes( + nodeSourceType = nodeSourceType, + parentHandle = parentHandle, + invalidNodeHandle = invalidNodeHandle, + query = query, + searchCategory = searchCategory, + modificationDate = modificationDate, + creationDate = creationDate + ) + } + + private suspend fun searchInNodes( + nodeSourceType: NodeSourceType, + parentHandle: Long, + invalidNodeHandle: Long, + query: String, + searchCategory: SearchCategory, + modificationDate: DateFilterOption?, + creationDate: DateFilterOption?, + ): List { + val node = getSearchParentNode(nodeSourceType, parentHandle, invalidNodeHandle) + return searchInNodesUseCase( + nodeId = node?.id, + query = query, + searchCategory = searchCategory, + modificationDate = modificationDate, + creationDate = creationDate, + ) } /** diff --git a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt index 5b158c5fbf..31283bf825 100644 --- a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt +++ b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt @@ -42,9 +42,11 @@ import androidx.compose.ui.platform.LocalWindowInfo import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.view.ViewCompat @@ -115,14 +117,15 @@ fun LegacySearchAppBar( @Composable fun CollapsedSearchAppBar( onBackPressed: () -> Unit, - onSearchClicked: () -> Unit, elevation: Boolean, title: String, modifier: Modifier = Modifier, + onSearchClicked: (() -> Unit)? = null, actions: List? = null, onActionPressed: ((MenuAction) -> Unit)? = null, maxActionsToShow: Int = 3, enabled: Boolean = true, + showSearchButton: Boolean = true, ) { val iconColor = if (MaterialTheme.colors.isLight) Color.Black else Color.White @@ -132,7 +135,7 @@ fun CollapsedSearchAppBar( modifier = Modifier.testTag(SEARCH_TOOLBAR_TITLE_VIEW_TEST_TAG), text = title, style = MaterialTheme.typography.subtitle1, - fontWeight = FontWeight.Medium + fontWeight = FontWeight.Medium, ) }, navigationIcon = { @@ -148,15 +151,17 @@ fun CollapsedSearchAppBar( } }, actions = { - IconButton( - modifier = Modifier.testTag(SEARCH_TOOLBAR_SEARCH_BUTTON_TEST_TAG), - onClick = { onSearchClicked() }, - ) { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_search), - contentDescription = "Search Icon", - tint = iconColor - ) + if (showSearchButton) { + IconButton( + modifier = Modifier.testTag(SEARCH_TOOLBAR_SEARCH_BUTTON_TEST_TAG), + onClick = { onSearchClicked?.invoke() }, + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_search), + contentDescription = "Search Icon", + tint = iconColor + ) + } } actions?.let { MenuActions( @@ -205,8 +210,8 @@ fun ExpandedSearchAppBar( .padding(start = 5.dp, end = 5.dp) .focusRequester(focusRequester) .testTag(SEARCH_TOOLBAR_TEXT_VIEW_TEST_TAG), - value = text, - onValueChange = { onSearchTextChange(it) }, + value = TextFieldValue(text, TextRange(text.length)), + onValueChange = { onSearchTextChange(it.text) }, placeholder = { Text( modifier = Modifier.alpha(ContentAlpha.medium), @@ -296,7 +301,7 @@ fun AppBarPreview() { onBackPressed = {}, onSearchClicked = {}, elevation = false, - "Screen Title" + title = "Screen Title" ) } From 0ae8fd4d2c74bb39f180bac25ce3bc6ef5843a25 Mon Sep 17 00:00:00 2001 From: Rohit Soni Date: Thu, 4 Apr 2024 19:37:49 +1300 Subject: [PATCH 067/261] SAO-52 Fixed issues for Search --- .../GeneralChatMessageBottomSheet.kt | 2 +- .../search/SearchActivityViewModel.kt | 13 ---------- .../app/presentation/search/SearchScreen.kt | 1 - .../search/model/SearchActivityState.kt | 2 -- .../search/view/SearchComposeView.kt | 26 +++++++++++++------ .../search/OutgoingSharesTabSearchUseCase.kt | 4 +-- .../OutgoingSharesTabSearchUseCaseTest.kt | 9 +++---- 7 files changed, 25 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/modalbottomsheet/chatmodalbottomsheet/GeneralChatMessageBottomSheet.kt b/app/src/main/java/mega/privacy/android/app/modalbottomsheet/chatmodalbottomsheet/GeneralChatMessageBottomSheet.kt index b2ba7da56a..9756a6f713 100644 --- a/app/src/main/java/mega/privacy/android/app/modalbottomsheet/chatmodalbottomsheet/GeneralChatMessageBottomSheet.kt +++ b/app/src/main/java/mega/privacy/android/app/modalbottomsheet/chatmodalbottomsheet/GeneralChatMessageBottomSheet.kt @@ -156,7 +156,7 @@ class GeneralChatMessageBottomSheet : BaseBottomSheetDialogFragment(), View.OnCl forwardSeparator = contentView.findViewById(R.id.forward_separator) optionForward = contentView.findViewById(R.id.forward) editSeparator = contentView.findViewById(R.id.edit_separator) - optionEdit = contentView.findViewById(R.id.edit_layout) + optionEdit = contentView.findViewById(R.id.edit) copySeparator = contentView.findViewById(R.id.copy_separator) optionCopy = contentView.findViewById(R.id.copy) shareSeparator = contentView.findViewById(R.id.share_separator) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index f0098be29e..0851718ee6 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -261,7 +261,6 @@ class SearchActivityViewModel @Inject constructor( _state.update { it.copy( selectedFilter = selectedChip.takeIf { selectedChip?.filter != state.value.selectedFilter?.filter }, - resetScroll = triggered ) } viewModelScope.launch { performSearch() } @@ -368,7 +367,6 @@ class SearchActivityViewModel @Inject constructor( _state.update { it.copy( typeSelectedFilterOption = typeFilterOption, - resetScroll = triggered ) } viewModelScope.launch { performSearch() } @@ -381,7 +379,6 @@ class SearchActivityViewModel @Inject constructor( _state.update { it.copy( dateModifiedSelectedFilterOption = dateFilterOption, - resetScroll = triggered ) } viewModelScope.launch { performSearch() } @@ -394,7 +391,6 @@ class SearchActivityViewModel @Inject constructor( _state.update { it.copy( dateAddedSelectedFilterOption = dateFilterOption, - resetScroll = triggered ) } viewModelScope.launch { performSearch() } @@ -504,15 +500,6 @@ class SearchActivityViewModel @Inject constructor( } } - /** - * Clear reset scroll - */ - fun clearResetScroll() { - _state.update { - it.copy(resetScroll = consumed) - } - } - /** * Open folder from search screen * diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt index 793ef03eab..173ac0103d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt @@ -101,6 +101,5 @@ fun SearchScreen( onBackPressed = onBackPressed, navHostController = navHostController, nodeActionHandler = nodeActionHandler, - clearResetScrollEvent = searchActivityViewModel::clearResetScroll, ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt index df7c2861e3..075feb7323 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/model/SearchActivityState.kt @@ -36,7 +36,6 @@ import mega.privacy.android.domain.entity.search.TypeFilterOption * @property selectedNodes selected nodes * @property nodeNameCollisionResult result of node name collision * @property moveRequestResult result of move request - * @property resetScroll to reset scroll position * @property navigationLevel list of parent handles */ data class SearchActivityState( @@ -59,6 +58,5 @@ data class SearchActivityState( val nodeSourceType: NodeSourceType = NodeSourceType.OTHER, val nodeNameCollisionResult: NodeNameCollisionResult? = null, val moveRequestResult: Result? = null, - val resetScroll: StateEvent = consumed, val navigationLevel: List> = emptyList(), ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index 441ee3978d..3e87881409 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -30,7 +30,6 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController -import de.palm.composestateevents.EventEffect import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -83,14 +82,23 @@ fun SearchComposeView( navHostController: NavHostController, nodeActionHandler: NodeActionHandler, clearSelection: () -> Unit, - clearResetScrollEvent: () -> Unit, modifier: Modifier = Modifier, ) { + var resetScroll by rememberSaveable { + mutableStateOf(false) + } + val listState = rememberLazyListState() val gridState = rememberLazyGridState() val scaffoldState = rememberScaffoldState() val snackBarHostState = remember { SnackbarHostState() } var topBarPadding by remember { mutableStateOf(0.dp) } + + LaunchedEffect(key1 = resetScroll) { + listState.scrollToItem(0) + gridState.scrollToItem(0) + } + var searchQuery by rememberSaveable { mutableStateOf(state.searchQuery) } @@ -98,13 +106,10 @@ fun SearchComposeView( searchQuery.useDebounce( onChange = { updateSearchQuery(it) + resetScroll = !resetScroll }, ) - EventEffect(event = state.resetScroll, onConsumed = clearResetScrollEvent) { - listState.scrollToItem(0) - gridState.scrollToItem(0) - } topBarPadding = if (state.navigationLevel.isNotEmpty() && state.nodeSourceType != NodeSourceType.CLOUD_DRIVE && state.nodeSourceType != NodeSourceType.HOME) 8.dp else 0.dp @@ -147,7 +152,13 @@ fun SearchComposeView( ) { padding -> Column(modifier = Modifier.padding(top = topBarPadding)) { if (state.nodeSourceType == NodeSourceType.CLOUD_DRIVE || state.nodeSourceType == NodeSourceType.HOME) { - FilterChipsView(state, onFilterClicked, updateFilter, trackAnalytics) + FilterChipsView(state, onFilterClicked = { + resetScroll = !resetScroll + onFilterClicked(it) + }, updateFilter = { + resetScroll = !resetScroll + updateFilter(it) + }, trackAnalytics) } if (state.isSearching) { LoadingStateView( @@ -231,7 +242,6 @@ private fun PreviewSearchComposeView() { hiltViewModel() ), clearSelection = {}, - clearResetScrollEvent = {} ) } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt index 71f7e48f8a..54f0f436cd 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt @@ -32,11 +32,11 @@ class OutgoingSharesTabSearchUseCase @Inject constructor( return list.sortedWith( if (getCloudSortOrder() == SortOrder.ORDER_DEFAULT_DESC) { compareByDescending { it is FolderNode } - .thenBy(String.CASE_INSENSITIVE_ORDER) { it.name } + .thenBy(String.CASE_INSENSITIVE_ORDER) { it.name }.reversed() } else { compareBy { it is FolderNode }.thenBy( String.CASE_INSENSITIVE_ORDER - ) { it.name } + ) { it.name }.reversed() } ).map { addNodeType(it) } } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCaseTest.kt index 75982496b4..d38e625140 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCaseTest.kt @@ -15,7 +15,6 @@ import org.junit.Test import org.mockito.kotlin.mock import org.mockito.kotlin.whenever -@OptIn(ExperimentalCoroutinesApi::class) class OutgoingSharesTabSearchUseCaseTest { private lateinit var underTest: OutgoingSharesTabSearchUseCase private val addNodeType: AddNodeType = mock() @@ -42,13 +41,13 @@ class OutgoingSharesTabSearchUseCaseTest { on { id }.thenReturn(NodeId(nodeId)) on { name }.thenReturn(nodeName[index]) } - } + }.reversed() val typedFolderNodes = nodeHandles.mapIndexed { index, nodeId -> mock { on { id }.thenReturn(NodeId(nodeId)) on { name }.thenReturn(nodeName[index]) } - } + }.reversed() folderNodes.forEachIndexed { index, node -> whenever(addNodeType(node)).thenReturn(typedFolderNodes[index]) } @@ -74,13 +73,13 @@ class OutgoingSharesTabSearchUseCaseTest { on { id }.thenReturn(NodeId(nodeId)) on { name }.thenReturn(nodeName[index]) } - } + }.reversed() val typedFolderNodes = nodeHandles.mapIndexed { index, nodeId -> mock { on { id }.thenReturn(NodeId(nodeId)) on { name }.thenReturn(nodeName[index]) } - } + }.reversed() folderNodes.forEachIndexed { index, node -> whenever(addNodeType(node)).thenReturn(typedFolderNodes[index]) } From 6e186e799ffad4e157768f62c0a61e57c6b22f27 Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Thu, 4 Apr 2024 23:34:21 +1300 Subject: [PATCH 068/261] T15699911 Join a meeting via link --- .../android/app/meeting/activity/MeetingActivityViewModel.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt index c2ed52ba74..0580116d06 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt @@ -531,10 +531,6 @@ class MeetingActivityViewModel @Inject constructor( runCatching { getChatCallUseCase(_state.value.chatId) }.onSuccess { call -> - if (call == null) { - finishMeetingActivity() - } - call?.let { when (call.status) { ChatCallStatus.UserNoPresent -> { From d10d5f5dcfaf1bdf9c144f14a9bf8f528f6c7872 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Fri, 5 Apr 2024 00:32:51 +1300 Subject: [PATCH 069/261] T15667742/AND-18547: Message not marked as read --- .../meeting/chat/model/MessageListViewModel.kt | 18 +++++++++++------- .../meeting/chat/view/MessageListView.kt | 2 +- .../chat/model/MessageListViewModelTest.kt | 11 +++++++++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModel.kt index 8cb04cf113..575c0fd716 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModel.kt @@ -35,7 +35,7 @@ import mega.privacy.android.app.presentation.meeting.chat.model.messages.UiChatM import mega.privacy.android.app.presentation.meeting.chat.model.messages.header.ChatUnreadHeaderMessage import mega.privacy.android.app.presentation.meeting.chat.model.messages.header.HeaderMessage import mega.privacy.android.app.utils.Constants -import mega.privacy.android.domain.entity.chat.messages.TypedMessage +import mega.privacy.android.domain.entity.chat.ChatMessageStatus import mega.privacy.android.domain.entity.chat.room.update.MessageReceived import mega.privacy.android.domain.usecase.MonitorContactCacheUpdates import mega.privacy.android.domain.usecase.chat.message.GetLastMessageSeenIdUseCase @@ -242,14 +242,18 @@ class MessageListViewModel @Inject constructor( /** * Update latest message * - * @param message Message + * @param messages list of messages reversed order, latest message is the first */ - fun updateLatestMessage(message: TypedMessage?) { - if (latestMessageId.longValue == -1L && message != null) { - setMessageSeen(message.msgId) + fun updateLatestMessage(messages: List) { + if (latestMessageId.longValue == -1L && messages.isNotEmpty()) { + // mark first time user enter chat room as seen + messages.find { it?.message?.status == ChatMessageStatus.NOT_SEEN }?.let { + setMessageSeen(it.id) + } } - latestMessageId.longValue = message?.msgId ?: -1L - if (message?.isMine == true) { + val lastMessage = messages.firstOrNull()?.message + latestMessageId.longValue = lastMessage?.msgId ?: -1L + if (lastMessage?.isMine == true) { // if user sent a message, reset the extraUnreadCount and remove unread header _state.update { state -> state.copy(extraUnreadCount = 0, lastSeenMessageId = -1) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/MessageListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/MessageListView.kt index 838d470029..cc0d50c2de 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/MessageListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/MessageListView.kt @@ -153,7 +153,7 @@ internal fun MessageListView( ) { scrollState.scrollToItem(0, 0) } - viewModel.updateLatestMessage(latestMessage) + viewModel.updateLatestMessage(pagingItems.itemSnapshotList) } LaunchedEffect(state.userUpdate) { diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModelTest.kt index 73d67e1527..bc5c5c97af 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/chat/model/MessageListViewModelTest.kt @@ -13,8 +13,10 @@ import mega.privacy.android.app.presentation.meeting.chat.mapper.ChatMessageDate import mega.privacy.android.app.presentation.meeting.chat.mapper.ChatMessageTimeSeparatorMapper import mega.privacy.android.app.presentation.meeting.chat.mapper.UiChatMessageMapper import mega.privacy.android.app.presentation.meeting.chat.model.MessageListViewModel + import mega.privacy.android.app.presentation.meeting.chat.model.messages.normal.TextUiMessage import mega.privacy.android.app.utils.Constants import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension +import mega.privacy.android.domain.entity.chat.ChatMessageStatus import mega.privacy.android.domain.entity.chat.messages.normal.TextMessage import mega.privacy.android.domain.entity.user.UserChanges import mega.privacy.android.domain.entity.user.UserId @@ -144,11 +146,16 @@ internal class MessageListViewModelTest { val typedMessage = mock { on { msgId } doReturn messageId on { isMine } doReturn true + on { status } doReturn ChatMessageStatus.NOT_SEEN + } + val uiMessage = mock { + on { message } doReturn typedMessage + on { id } doReturn messageId } assertThat(underTest.latestMessageId.longValue).isEqualTo(-1L) - underTest.updateLatestMessage(typedMessage) + underTest.updateLatestMessage(listOf(uiMessage)) assertThat(underTest.latestMessageId.longValue).isEqualTo(messageId) - underTest.updateLatestMessage(typedMessage) + underTest.updateLatestMessage(listOf(uiMessage)) // verify call only once verify(setMessageSeenUseCase).invoke(chatId, messageId) underTest.state.test { From 8a1ae24d3a6412327724f49685ef56d1aec0e807 Mon Sep 17 00:00:00 2001 From: rohitsoni Date: Thu, 4 Apr 2024 17:01:31 +0530 Subject: [PATCH 070/261] SAO-52 Change sort order outgoing shares issues fix --- .../domain/usecase/search/OutgoingSharesTabSearchUseCase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt index 54f0f436cd..1c3b57fe4d 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/search/OutgoingSharesTabSearchUseCase.kt @@ -31,7 +31,7 @@ class OutgoingSharesTabSearchUseCase @Inject constructor( ) return list.sortedWith( if (getCloudSortOrder() == SortOrder.ORDER_DEFAULT_DESC) { - compareByDescending { it is FolderNode } + compareByDescending { it is FolderNode }.reversed() .thenBy(String.CASE_INSENSITIVE_ORDER) { it.name }.reversed() } else { compareBy { it is FolderNode }.thenBy( From 70c07bb07d4b0a21fb78f68576503b7dd913a5ae Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Fri, 5 Apr 2024 04:16:33 +1300 Subject: [PATCH 071/261] MEET-3693: Fix bottom navigation menu click overlap --- .../android/app/main/ManagerActivity.kt | 66 +++++++++++-------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 1ff524bef1..2960a9729d 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -44,13 +44,18 @@ import androidx.activity.viewModels import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView +import androidx.compose.foundation.background import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -1253,43 +1258,52 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf upgradeToProPlanBottomSheetState.currentValue != ModalBottomSheetValue.Hidden } - val noBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) MegaAppTheme(isDark = isDark) { + + var showUpgradeDialog by rememberSaveable() { + mutableStateOf(false) + } LaunchedEffect(state.shouldUpgradeToProPlan) { + Timber.d("shouldUpgradeToProPlan ${state.shouldUpgradeToProPlan}") if (state.shouldUpgradeToProPlan) { + showUpgradeDialog = true upgradeToProPlanBottomSheetState.show() viewModel.onConsumeShouldUpgradeToProPlan() } } + LaunchedEffect(upgradeToProPlanBottomSheetState.currentValue) { + if (upgradeToProPlanBottomSheetState.currentValue == ModalBottomSheetValue.Hidden) { + showUpgradeDialog = false + } + } - BottomSheet( - modifier = Modifier.semantics { - testTagsAsResourceId = true - }, - modalSheetState = when { - isUpgradeToProPlanShown -> upgradeToProPlanBottomSheetState - else -> noBottomSheetState - }, - sheetBody = { - when { - isUpgradeToProPlanShown -> { - UpgradeProPlanBottomSheet { - coroutineScope.launch { - upgradeToProPlanBottomSheetState.hide() + if (state.callEndedDueToFreePlanLimits && state.isCallUnlimitedProPlanFeatureFlagEnabled && + state.usersCallLimitReminders == UsersCallLimitReminders.Enabled + ) { + FreePlanLimitParticipantsDialog( + onConfirm = { + viewModel.onConsumeShowFreePlanParticipantsLimitDialogEvent() + }, + ) + } + if (showUpgradeDialog) { + BottomSheet( + modifier = Modifier + .semantics { + testTagsAsResourceId = true + }, + modalSheetState = upgradeToProPlanBottomSheetState, + sheetBody = { + when { + isUpgradeToProPlanShown -> { + UpgradeProPlanBottomSheet { + coroutineScope.launch { + upgradeToProPlanBottomSheetState.hide() + } } } } - } - }) { - if (state.callEndedDueToFreePlanLimits && state.isCallUnlimitedProPlanFeatureFlagEnabled && - state.usersCallLimitReminders == UsersCallLimitReminders.Enabled - ) { - FreePlanLimitParticipantsDialog( - onConfirm = { - viewModel.onConsumeShowFreePlanParticipantsLimitDialogEvent() - }, - ) - } + }) } } } From 3bd3105921221da1a5297a1a95bd456e49ac4b3d Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Fri, 5 Apr 2024 12:00:20 +1300 Subject: [PATCH 072/261] AND-18552 fix intent not finding email clients --- .../app/presentation/settings/FeedBackDialog.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt index a1a5d86eb4..7ed5004135 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt @@ -12,6 +12,7 @@ import android.widget.CheckedTextView import androidx.fragment.app.DialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder import mega.privacy.android.app.R +import mega.privacy.android.app.presentation.extensions.canBeHandled import mega.privacy.android.app.service.RATE_APP_URL import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.Util @@ -102,15 +103,16 @@ class FeedBackDialog : DialogFragment() { } private fun sendEmail(subject: String, body: String) { - val emailIntent = Intent(Intent.ACTION_SENDTO) - emailIntent.type = Constants.TYPE_TEXT_PLAIN - emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(Constants.MAIL_ANDROID)) + val emailIntent = Intent( + Intent.ACTION_SENDTO, Uri.fromParts( + "mailto", Constants.MAIL_ANDROID, null + ) + ) emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) emailIntent.putExtra(Intent.EXTRA_TEXT, body) - context?.packageManager?.let { packageManager -> - if (emailIntent.resolveActivity(packageManager) != null) { - startActivity(emailIntent) - } + + if (emailIntent.canBeHandled(requireContext())) { + startActivity(emailIntent) } } From be6f3c35ee46f09449ed5e042cab59457882b64b Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Fri, 5 Apr 2024 21:06:09 +1300 Subject: [PATCH 073/261] AP-1268: Fix for TC T15710188 --- .../java/mega/privacy/android/app/main/ManagerActivity.kt | 4 +--- .../photos/mediadiscovery/MediaDiscoveryFragment.kt | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 2960a9729d..d619991b5e 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -44,7 +44,6 @@ import androidx.activity.viewModels import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView -import androidx.compose.foundation.background import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.rememberModalBottomSheetState @@ -55,7 +54,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -9070,7 +9068,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf adsViewModel.onAdConsumed() } - fun showAdsView() { + private fun showAdsView() { adsComposeView.isVisible = true } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt index ca250521cc..70ae073921 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt @@ -129,7 +129,7 @@ class MediaDiscoveryFragment : Fragment() { if (isVisible) { managerActivity?.hideAdsView() } else { - managerActivity?.showAdsView() + managerActivity?.handleShowingAds(TAB_CLOUD_SLOT_ID) } } From e2911b5b84dbf8cf2cd19efd155e0e94a771e617 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Fri, 5 Apr 2024 13:25:52 +0200 Subject: [PATCH 074/261] TRAN-337: Reported not-fatal exception:ForegroundServiceDidNotStartInTimeException --- .../privacy/android/app/MegaApplication.kt | 5 - .../BackgroundRequestListener.kt | 3 - .../app/presentation/login/LoginViewModel.kt | 4 + .../app/data/worker/ChatUploadsWorkerTest.kt | 6 + .../presentation/login/LoginViewModelTest.kt | 6 +- .../app/transfers/DownloadsWorkerTest.kt | 35 +++++ .../privacy/android/data/di/WorkerModule.kt | 20 +++ .../data/worker/AbstractTransfersWorker.kt | 129 +++++++++++------- .../android/data/worker/ChatUploadsWorker.kt | 6 +- .../android/data/worker/DownloadsWorker.kt | 4 +- 10 files changed, 152 insertions(+), 66 deletions(-) create mode 100644 data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt diff --git a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt index 56c69887c7..167514d927 100644 --- a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt +++ b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt @@ -228,11 +228,6 @@ class MegaApplication : MultiDexApplication(), DefaultLifecycleObserver, setupMegaChatApi() getMiscFlagsIfNeeded() - //Logout check resumed pending transfers - transfersManagement.apply { - checkResumedPendingTransfers() - } - applicationScope.launch { runCatching { updateApiServerUseCase() } dbH.resetExtendedAccountDetailsTimestamp() diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt index a1de505988..4fff3448f5 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt @@ -51,7 +51,6 @@ class BackgroundRequestListener @Inject constructor( private val megaChatApi: MegaChatApiAndroid, private val dbH: DatabaseHandler, @MegaApi private val megaApi: MegaApiAndroid, - private val transfersManagement: TransfersManagement, @ApplicationScope private val applicationScope: CoroutineScope, private val getFullAccountInfoUseCase: GetFullAccountInfoUseCase, private val broadcastFetchNodesFinishUseCase: BroadcastFetchNodesFinishUseCase, @@ -167,8 +166,6 @@ class BackgroundRequestListener @Inject constructor( if (dbH.myChatFilesFolderHandle == INVALID_HANDLE) { megaApi.getMyChatFilesFolder(listener) } - //Login check resumed pending transfers - transfersManagement.checkResumedPendingTransfers() applicationScope.launch { // Init CU sync data after login successfully runCatching { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt index 586a10f757..032c0e4359 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt @@ -22,6 +22,7 @@ import mega.privacy.android.analytics.Analytics import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.R import mega.privacy.android.app.featuretoggle.AppFeatures +import mega.privacy.android.app.globalmanagement.TransfersManagement import mega.privacy.android.app.logging.LegacyLoggingSettings import mega.privacy.android.app.middlelayer.installreferrer.InstallReferrerHandler import mega.privacy.android.app.presentation.extensions.error @@ -129,6 +130,7 @@ class LoginViewModel @Inject constructor( private val clearLastRegisteredEmailUseCase: ClearLastRegisteredEmailUseCase, private val installReferrerHandler: InstallReferrerHandler, @LoginMutex private val loginMutex: Mutex, + private val transfersManagement: TransfersManagement, ) : ViewModel() { private val _state = MutableStateFlow(LoginState()) @@ -748,6 +750,8 @@ class LoginViewModel @Inject constructor( if (getFeatureFlagValueUseCase(AppFeatures.NewChatActivity)) { startChatUploadsWorkerUseCase() } + //Login check resumed pending transfers + transfersManagement.checkResumedPendingTransfers() } else { Timber.d("fetch nodes update") _state.update { it.copy(fetchNodesUpdate = update) } diff --git a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt index d87aa4306c..beef002719 100644 --- a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt @@ -15,6 +15,7 @@ import androidx.work.impl.utils.taskexecutor.WorkManagerTaskExecutor import androidx.work.workDataOf import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -23,6 +24,7 @@ import mega.privacy.android.data.mapper.transfer.ChatUploadNotificationMapper import mega.privacy.android.data.mapper.transfer.OverQuotaNotificationBuilder import mega.privacy.android.data.worker.AreNotificationsEnabledUseCase import mega.privacy.android.data.worker.ChatUploadsWorker +import mega.privacy.android.data.worker.ForegroundSetter import mega.privacy.android.domain.entity.chat.PendingMessage import mega.privacy.android.domain.entity.chat.PendingMessageState import mega.privacy.android.domain.entity.chat.messages.pending.UpdatePendingMessageStateRequest @@ -86,6 +88,7 @@ class ChatUploadsWorkerTest { private val chatMessageRepository = mock() private val updatePendingMessageUseCase = mock() private val checkFinishedChatUploadsUseCase = mock() + private val setForeground = mock() @Before fun init() { @@ -129,6 +132,7 @@ class ChatUploadsWorkerTest { attachNodeWithPendingMessageUseCase, updatePendingMessageUseCase, checkFinishedChatUploadsUseCase, + setForeground, ) } @@ -216,9 +220,11 @@ class ChatUploadsWorkerTest { whenever(monitorOngoingActiveTransfersUseCase(TransferType.CHAT_UPLOAD)) doReturn (flowOf( MonitorOngoingActiveTransfersResult(totals, paused = false, overQuota = false) )) + whenever(monitorTransferEventsUseCase()) doReturn (emptyFlow()) whenever(workProgressUpdater.updateProgress(any(), any(), any())) .thenReturn(SettableFuture.create().also { it.set(null) }) whenever(areNotificationsEnabledUseCase()).thenReturn(false) + whenever(getActiveTransferTotalsUseCase(TransferType.CHAT_UPLOAD)).thenReturn(totals) return finishEvent } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt index b4ee0cb0c7..dd2df30c9c 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt @@ -2,7 +2,6 @@ package test.mega.privacy.android.app.presentation.login import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import de.palm.composestateevents.StateEventWithContent import de.palm.composestateevents.consumed import de.palm.composestateevents.triggered import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -14,6 +13,7 @@ import kotlinx.coroutines.test.TestCoroutineScheduler import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import mega.privacy.android.app.R +import mega.privacy.android.app.globalmanagement.TransfersManagement import mega.privacy.android.app.logging.LegacyLoggingSettings import mega.privacy.android.app.middlelayer.installreferrer.InstallReferrerDetails import mega.privacy.android.app.middlelayer.installreferrer.InstallReferrerHandler @@ -107,6 +107,7 @@ internal class LoginViewModelTest { private val saveLastRegisteredEmailUseCase = mock() private val clearLastRegisteredEmailUseCase = mock() private val installReferrerHandler = mock() + private val transfersManagement = mock() @BeforeEach fun setUp() { @@ -144,7 +145,8 @@ internal class LoginViewModelTest { getLastRegisteredEmailUseCase = getLastRegisteredEmailUseCase, saveLastRegisteredEmailUseCase = saveLastRegisteredEmailUseCase, clearLastRegisteredEmailUseCase = clearLastRegisteredEmailUseCase, - installReferrerHandler = installReferrerHandler + installReferrerHandler = installReferrerHandler, + transfersManagement = transfersManagement, ) } diff --git a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt index 91986cd493..ed951b1f33 100644 --- a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt @@ -29,6 +29,7 @@ import mega.privacy.android.data.mapper.transfer.TransfersFinishedNotificationMa import mega.privacy.android.data.worker.AbstractTransfersWorker import mega.privacy.android.data.worker.AreNotificationsEnabledUseCase import mega.privacy.android.data.worker.DownloadsWorker +import mega.privacy.android.data.worker.ForegroundSetter import mega.privacy.android.domain.entity.Progress import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.MonitorOngoingActiveTransfersResult @@ -85,6 +86,7 @@ class DownloadsWorkerTest { private val transfersFinishedNotificationMapper = mock() private val workProgressUpdater = mock() private val scanMediaFileUseCase = mock() + private val setForeground = mock() @Before fun setup() { @@ -127,6 +129,7 @@ class DownloadsWorkerTest { clearActiveTransfersIfFinishedUseCase = clearActiveTransfersIfFinishedUseCase, transfersFinishedNotificationMapper = transfersFinishedNotificationMapper, scanMediaFileUseCase = scanMediaFileUseCase, + foregroundSetter = setForeground ) } @@ -246,6 +249,37 @@ class DownloadsWorkerTest { verifyNoInteractions(overQuotaNotificationBuilder) } + fun `test that setForeground is not invoked when worker starts with no transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals( + hasCompleted = false, + ) + whenever(initial.totalTransfers).thenReturn(0) + commonStub(initialTransferTotals = initial) + underTest.doWork() + verifyNoInteractions(setForeground) + } + + @Test + fun `test that transfersFinishedNotificationMapper is invoked when worker starts with completed transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals(true) + whenever(initial.totalTransfers).thenReturn(1) + commonStub(initialTransferTotals = initial) + underTest.doWork() + verify(transfersFinishedNotificationMapper).invoke(initial) + } + + @Test + fun `test that setForeground is not invoked when worker starts with completed transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals(true) + commonStub(initialTransferTotals = initial) + whenever(initial.totalTransfers).thenReturn(1) + underTest.doWork() + verifyNoInteractions(setForeground) + } + @Test fun `test that transfersFinishedNotificationMapper is not invoked when transfer finishes with no transfers`() = runTest { @@ -315,6 +349,7 @@ class DownloadsWorkerTest { whenever(areNotificationsEnabledUseCase()).thenReturn(true) whenever(workProgressUpdater.updateProgress(any(), any(), any())) .thenReturn(SettableFuture.create().also { it.set(null) }) + whenever(downloadNotificationMapper(any(), any())).thenReturn(mock()) } private fun mockActiveTransferTotals( diff --git a/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt b/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt new file mode 100644 index 0000000000..33230b3652 --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt @@ -0,0 +1,20 @@ +package mega.privacy.android.data.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import mega.privacy.android.data.worker.ForegroundSetter + +/** + * Module for workers + */ +@Module +@InstallIn(SingletonComponent::class) +object WorkerModule { + /** + * Provides [ForegroundSetter] to its default null value + */ + @Provides + fun provideForegroundSetter(): ForegroundSetter? = null +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt index 91dfd872f0..d6e59ced1b 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt @@ -15,29 +15,28 @@ import androidx.work.workDataOf import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.last import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import kotlinx.coroutines.yield import mega.privacy.android.data.mapper.transfer.OverQuotaNotificationBuilder import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase -import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.active.GetActiveTransferTotalsUseCase +import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.MonitorOngoingActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.paused.AreTransfersPausedUseCase import timber.log.Timber /** * Abstract CoroutineWorker to share common implementation of transfers workers + * @param foregroundSetter to inject the set foreground method, used for testing */ abstract class AbstractTransfersWorker( context: Context, @@ -54,6 +53,7 @@ abstract class AbstractTransfersWorker( private val areNotificationsEnabledUseCase: AreNotificationsEnabledUseCase, private val correctActiveTransfersUseCase: CorrectActiveTransfersUseCase, private val clearActiveTransfersIfFinishedUseCase: ClearActiveTransfersIfFinishedUseCase, + private val foregroundSetter: ForegroundSetter?, ) : CoroutineWorker(context, workerParams) { /** @@ -69,7 +69,7 @@ abstract class AbstractTransfersWorker( /** * Create the update Notification to show worker progress */ - abstract suspend fun createUpdateNotification( + abstract fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ): Notification @@ -90,61 +90,74 @@ abstract class AbstractTransfersWorker( */ open suspend fun onTransferEventReceived(event: TransferEvent) {} - override suspend fun doWork() = coroutineScope { + override suspend fun doWork() = withContext(ioDispatcher) { Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Started") + val monitorJob = monitorTransferEvents(this) + correctActiveTransfersUseCase(type) //to be sure we haven't missed any event before monitoring them + val activeTransferTotals = getActiveTransferTotalsUseCase(type) + if (activeTransferTotals.hasCompleted()) { + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} No transfers to monitor") + stopService(monitorJob) + if (activeTransferTotals.totalTransfers > 0) { + showFinishNotification(activeTransferTotals) + } + return@withContext Result.success() + } // Signal to not kill the worker if the app is killed - setForegroundAsync(getForegroundInfo()) - - withContext(ioDispatcher) { - val monitorJob = monitorTransferEvents(this) - correctActiveTransfersUseCase(type) //to be sure we haven't missed any event before monitoring them - onStart() - monitorOngoingActiveTransfersUseCase(type) - .catch { Timber.e("${this@AbstractTransfersWorker::class.java.simpleName}error: $it") } - .onEach { (transferTotals, paused, _) -> - //set progress percent as worker progress - setProgress(workDataOf(PROGRESS to transferTotals.transferProgress.floatValue)) - //update the notification - notify(createUpdateNotification(transferTotals, paused)) - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}${if (paused) "(paused) " else ""} Notification update (${transferTotals.transferProgress.intValue}):${transferTotals.hasOngoingTransfers()}") - } - .last().let { (lastActiveTransferTotals, _, overQuota) -> - stopService(monitorJob) - clearActiveTransfersIfFinishedUseCase(type) - if (lastActiveTransferTotals.hasCompleted()) { - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Finished Successful: $lastActiveTransferTotals") - if (lastActiveTransferTotals.totalTransfers > 0) { - showFinishNotification(lastActiveTransferTotals) - } - Result.success() + val foregroundInfo = getForegroundInfo(activeTransferTotals, areTransfersPausedUseCase()) + foregroundSetter?.setForeground(foregroundInfo) ?: run { + setForeground(foregroundInfo) + } + + onStart() + monitorOngoingActiveTransfersUseCase(type) + .catch { Timber.e("${this@AbstractTransfersWorker::class.java.simpleName}error: $it") } + .onEach { (transferTotals, paused, _) -> + //set progress percent as worker progress + setProgress(workDataOf(PROGRESS to transferTotals.transferProgress.floatValue)) + //update the notification + notify(createUpdateNotification(transferTotals, paused)) + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}${if (paused) "(paused) " else ""} Notification update (${transferTotals.transferProgress.intValue}):${transferTotals.hasOngoingTransfers()}") + } + .last().let { (lastActiveTransferTotals, _, overQuota) -> + stopService(monitorJob) + if (lastActiveTransferTotals.hasCompleted()) { + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Finished Successful: $lastActiveTransferTotals") + if (lastActiveTransferTotals.totalTransfers > 0) { + showFinishNotification(lastActiveTransferTotals) + } + Result.success() + } else { + if (overQuota + && !ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast( + Lifecycle.State.STARTED + ) + ) { + //the over quota notification is shown if the app is in background (if not a full dialog will be shown in the app) + showFinalNotification( + overQuotaNotificationBuilder(), + NOTIFICATION_STORAGE_OVERQUOTA + ) } else { - if (overQuota - && !ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast( - Lifecycle.State.STARTED - ) - ) { - //the over quota notification is shown if the app is in background (if not a full dialog will be shown in the app) - showFinalNotification( - overQuotaNotificationBuilder(), - NOTIFICATION_STORAGE_OVERQUOTA - ) - } else { - showFinishNotification(lastActiveTransferTotals) - } - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}finished Failure: $lastActiveTransferTotals") - Result.failure()//to retry in the future + showFinishNotification(lastActiveTransferTotals) } + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}finished Failure: $lastActiveTransferTotals") + Result.failure()//to retry in the future } - } + } } - override suspend fun getForegroundInfo() = - createForegroundInfo( - createUpdateNotification( - getActiveTransferTotalsUseCase(type), - areTransfersPausedUseCase() - ) - ) + override suspend fun getForegroundInfo() = getForegroundInfo( + getActiveTransferTotalsUseCase(type), + areTransfersPausedUseCase() + ) + + private fun getForegroundInfo( + activeTransferTotals: ActiveTransferTotals, + paused: Boolean, + ): ForegroundInfo { + return createForegroundInfo(createUpdateNotification(activeTransferTotals, paused)) + } /** * Monitors transfer events and update the related active transfers @@ -161,8 +174,8 @@ abstract class AbstractTransfersWorker( private suspend fun stopService(monitorJob: Job) { monitorJob.cancel() - yield() notificationManager.cancel(updateNotificationId) + clearActiveTransfersIfFinishedUseCase(type) } @SuppressLint("MissingPermission") @@ -217,4 +230,14 @@ abstract class AbstractTransfersWorker( const val PROGRESS = "Progress" private const val NOTIFICATION_STORAGE_OVERQUOTA = 14 } +} + +/** + * Interface to inject the set foreground method, used for testing + */ +interface ForegroundSetter { + /** + * Set foreground + */ + suspend fun setForeground(foregroundInfo: ForegroundInfo) } \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt index 7d41dd96af..4b0c63b8cc 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt @@ -21,10 +21,10 @@ import mega.privacy.android.domain.usecase.chat.message.AttachNodeWithPendingMes import mega.privacy.android.domain.usecase.chat.message.CheckFinishedChatUploadsUseCase import mega.privacy.android.domain.usecase.chat.message.UpdatePendingMessageUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase -import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.active.GetActiveTransferTotalsUseCase +import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.MonitorOngoingActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.paused.AreTransfersPausedUseCase import timber.log.Timber @@ -52,6 +52,7 @@ class ChatUploadsWorker @AssistedInject constructor( private val attachNodeWithPendingMessageUseCase: AttachNodeWithPendingMessageUseCase, private val updatePendingMessageUseCase: UpdatePendingMessageUseCase, private val checkFinishedChatUploadsUseCase: CheckFinishedChatUploadsUseCase, + foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( context, workerParams, @@ -67,10 +68,11 @@ class ChatUploadsWorker @AssistedInject constructor( areNotificationsEnabledUseCase, correctActiveTransfersUseCase, clearActiveTransfersIfFinishedUseCase, + foregroundSetter, ) { override val updateNotificationId = NOTIFICATION_CHAT_UPLOAD - override suspend fun createUpdateNotification( + override fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ) = chatUploadNotificationMapper(activeTransferTotals, null, paused) diff --git a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt index 311d45c084..a8f914d029 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt @@ -46,6 +46,7 @@ class DownloadsWorker @AssistedInject constructor( private val downloadNotificationMapper: DownloadNotificationMapper, private val transfersFinishedNotificationMapper: TransfersFinishedNotificationMapper, private val scanMediaFileUseCase: ScanMediaFileUseCase, + foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( context, workerParams, @@ -61,12 +62,13 @@ class DownloadsWorker @AssistedInject constructor( areNotificationsEnabledUseCase, correctActiveTransfersUseCase, clearActiveTransfersIfFinishedUseCase, + foregroundSetter, ) { override val finalNotificationId = DOWNLOAD_NOTIFICATION_ID override val updateNotificationId = NOTIFICATION_DOWNLOAD_FINAL - override suspend fun createUpdateNotification( + override fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ) = downloadNotificationMapper(activeTransferTotals, paused) From 1f43a66118d122163f8cf27f418c1aab0023a8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Sat, 6 Apr 2024 01:18:28 +1300 Subject: [PATCH 075/261] Pre-release 12.0 --- app/src/main/res/values-ar/strings.xml | 8 +++-- app/src/main/res/values-de/strings.xml | 8 +++-- app/src/main/res/values-es/strings.xml | 16 ++++++---- app/src/main/res/values-fr/strings.xml | 8 +++-- app/src/main/res/values-in/strings.xml | 8 +++-- app/src/main/res/values-it/strings.xml | 8 +++-- app/src/main/res/values-ja/strings.xml | 8 +++-- app/src/main/res/values-ko/strings.xml | 8 +++-- app/src/main/res/values-nl/strings.xml | 12 +++++--- app/src/main/res/values-pl/strings.xml | 16 ++++++---- app/src/main/res/values-pt/strings.xml | 8 +++-- app/src/main/res/values-ro/strings.xml | 8 +++-- app/src/main/res/values-ru/strings.xml | 6 +++- app/src/main/res/values-th/strings.xml | 8 +++-- app/src/main/res/values-vi/strings.xml | 8 +++-- app/src/main/res/values-zh-rCN/strings.xml | 8 +++-- app/src/main/res/values-zh-rTW/strings.xml | 12 +++++--- app/src/main/res/values/strings.xml | 18 +++++++++-- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 6 ++-- .../src/main/res/values-es/strings_shared.xml | 4 +-- .../src/main/res/values-fr/strings_shared.xml | 2 +- .../src/main/res/values-in/strings_shared.xml | 4 +-- .../src/main/res/values-it/strings_shared.xml | 4 +-- .../src/main/res/values-ja/strings_shared.xml | 2 +- .../src/main/res/values-nl/strings_shared.xml | 2 +- .../src/main/res/values-pl/strings_shared.xml | 30 +++++++++---------- .../src/main/res/values-pt/strings_shared.xml | 6 ++-- .../src/main/res/values-ro/strings_shared.xml | 4 +-- .../src/main/res/values-ru/strings_shared.xml | 2 +- .../src/main/res/values-th/strings_shared.xml | 4 +-- .../main/res/values-zh-rCN/strings_shared.xml | 4 +-- .../main/res/values-zh-rTW/strings_shared.xml | 4 +-- 34 files changed, 170 insertions(+), 88 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a28613aaeb..67e7ce8e4c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -5893,9 +5893,9 @@ تمت إزالة %1$d مشارك - تم تحميل التحديث الآن + تم تحديث التطبيق - إعادة تشغيل + Relaunch the app السماح بالوصول إلى الملفات الصوتية @@ -6339,4 +6339,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2992780539..a453649e4b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -4985,9 +4985,9 @@ %1$d Teilnehmer entfernt - Ein Update wurde soeben heruntergeladen + Die App wurde aktualisiert - Neu starten + Relaunch the app Zugriff auf Audiodateien zulassen @@ -5391,4 +5391,8 @@ Probleme beim Einloggen? Problem melden + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index da1f6398dd..f7804f10ad 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5212,9 +5212,9 @@ Se han eliminado %1$d participantes - Se acaba de descargar una actualización + La aplicación se ha actualizado - Reiniciar + Relaunch the app Permitir el acceso a archivos de audio @@ -5592,11 +5592,11 @@ %1$d elementos ocultos - • Priority support + • Soporte prioritario Amplía a Pro para recibir llamadas ilimitadas - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + La llamada ha alcanzado el límite de 60 minutos y ha finalizado. Los usuarios Pro tienen llamadas ilimitadas y hasta 1000 participantes. Ampliar cuenta @@ -5626,7 +5626,11 @@ Anterior - Trouble logging in? + ¿Problemas para iniciar sesión? - Report your issue + Reporta tu problema + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ 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 af7d8855ab..925d9536be 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5212,9 +5212,9 @@ %1$d participants ont été supprimés - Une mise à jour vient d’être téléchargée. + L’appli a été mise à jour - Redémarrer + Relaunch the app Autoriser l’accès aux fichiers son @@ -5629,4 +5629,8 @@ Des difficultés pour vous connecter ? Signalez votre problème + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 54d4d72ada..ebe0a01956 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4758,9 +4758,9 @@ Menghapus %1$d peserta - Pembaruan baru saja diunduh + Aplikasi telah diperbarui - Restart + Relaunch the app Izinkan akses ke file audio @@ -5153,4 +5153,8 @@ Kesulitan masuk? Laporkan masalah anda + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 590205151b..3218b05db0 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5212,9 +5212,9 @@ %1$d partecipanti rimossi - Un aggiornamento è appena stato scaricato + L\’app è stata aggiornata - Riavvia + Relaunch the app Permetti l\’accesso ai file audio @@ -5629,4 +5629,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 5910892834..95161b7fa0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4758,9 +4758,9 @@ %1$d人の参加者を削除しました - アップデートがダウンロードされました + アプリが更新されました - 再起動 + アプリを再起動 音声ファイルへのアクセスを許可する @@ -5153,4 +5153,8 @@ ログインできませんか? 問題を報告 + + 非表示項目を表示する + + 非表示の項目はすべて表示されますが、「非表示」ステータスを示すためにぼかされます \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3dc8047609..1f8a213311 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4758,9 +4758,9 @@ %1$d명의 참여자를 제거하였습니다 - 업데이트가 다운로드 되었습니다 + 앱이 업데이트 되었습니다 - 재시작 + Relaunch the app 오디오 파일에 접근 허용 @@ -5153,4 +5153,8 @@ 로그인에 문제가 있나요? 문제 신고 + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 2067c999a9..5719cdd407 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -4985,9 +4985,9 @@ %1$d deelnemers verwijderd - Er is zojuist een update gedownload + De applicatie is bijgewerkt - Herstarten + Start de applicatie opnieuw Toegang tot audio bestanden toestaan @@ -5388,7 +5388,11 @@ Ouder - Trouble logging in? + Problemen met inloggen? - Report your issue + Meld uw probleem + + Verborgen items weergeven + + Alle verborgen items zijn zichtbaar, maar wazig om hun “verborgen” status aan te geven \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 254fe1786b..3e0c2eb7ff 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5439,9 +5439,9 @@ Usuń %1$d uczestników - Aktualizacja została właśnie pobrana + Aplikacja została zaktualizowana - Zrestartuj + Ponownie uruchom aplikację Zezwalaj na dostęp do plików audio @@ -5830,11 +5830,11 @@ %1$d elementów ukrytych - • Priority support + •   Wsparcie priorytetowe Uaktualnij do Pro, aby otrzymywać nieograniczoną liczbę połączeń - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + Twoje połączenie osiągnęło limit 60 minut i zakończyło się. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000 uczestników. Zmień teraz @@ -5864,7 +5864,11 @@ Starsze - Trouble logging in? + Problemy z zalogowaniem? - Report your issue + Zgłoś swój problem + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 4f37478e28..166bfbe9b6 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5212,9 +5212,9 @@ %1$d participantes foram removidos - Foi feito o download de uma atualização + O aplicativo foi atualizado - Reiniciar + Reiniciar o aplicativo Permitir acesso aos arquivos de áudio @@ -5629,4 +5629,8 @@ Problemas para fazer login? Informar sobre o problema + + Mostrar itens ocultos + + Todos os itens ocultos ficarão visíveis, mas desfocados para indicar o seu status “oculto” \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 6caa3511bf..f71f8056bb 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5212,9 +5212,9 @@ %1$d 150 de participanți au fost eliminați - O actualizare tocmai a fost descărcată + Aplicația a fost actualizată - Repornește + Relaunch the app Permiteți accesul la fișiere audio @@ -5628,4 +5628,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 55948b3bda..467247d64d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5439,7 +5439,7 @@ Удалено %1$d участника - Только что было скачано обновление + Приложение было обновлено Перезапустить @@ -5867,4 +5867,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index aa856b347e..aa628f00be 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4758,9 +4758,9 @@ ลบผู้เข้าร่วม %1$d คนออกแล้ว - เพิ่งดาวน์โหลดการอัปเดตล่าสุดเสร็จเมื่อสักครู่นี้ + แอปได้รับการอัปเดตแล้ว - เริ่มใหม่ตั้งแต่ต้น + Relaunch the app อนุญาตให้เข้าถึงไฟล์เสียง @@ -5153,4 +5153,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 905a60f654..73c4a524b9 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4758,9 +4758,9 @@ Đã loại bỏ %1$d thành viên - Một bản cập nhật vừa được tải xuống + Ứng dụng đã được cập nhật - Khởi động lại + Relaunch the app Cho phép truy cập vào các tệp tin âm thanh @@ -5153,4 +5153,8 @@ Gặp sự cố đăng nhập? Báo cáo vấn đề của bạn + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e8daaaddb7..5c63bf8f0b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4758,9 +4758,9 @@ 已移除%1$d位参与者 - 刚刚下载了更新 + 应用程序已更新 - 重启 + Relaunch the app 允许访问音频文件 @@ -5154,4 +5154,8 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 0df78b35f8..140146cc9e 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4758,9 +4758,9 @@ 已移除%1$d個與會者 - 剛剛下載了更新 + 應用程式已更新 - 重頭播放 + 重新啟動應用程式 允許存取音訊檔案 @@ -5150,7 +5150,11 @@ 較舊的 - Trouble logging in? + 登入時遇到問題? - Report your issue + 報告您的問題 + + 顯示隱藏的項目 + + 可看到所有隱藏的項目,但會模糊顯示以表示其「隱藏」狀態 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f3787e34a9..f35b4c520d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4991,9 +4991,9 @@ Removed %1$d participants - An update has just been downloaded + The app has been updated - Restart + Relaunch the app Allow access to audio files @@ -5397,4 +5397,18 @@ Trouble logging in? Report your issue + + Photo + + Flash mode on + + Flash mode off + + Flash mode auto + + Send to %1$s + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml index 75cc9f7687..34259f215f 100644 --- a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml @@ -71,7 +71,7 @@ Der belegte Speicherplatz hat das Limit erreicht. - Ihr Abonnement ist abgelaufen. + Dieser Ordner kann nicht synchronisiert oder gesichert werden, da Ihr Paket abgelaufen ist. Der Ordner kann nicht synchronisiert werden, da der freigebende Benutzer sein Speicherplatzlimit erreicht hat. diff --git a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml index 22c78927aa..c5d51bf459 100644 --- a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml @@ -101,7 +101,7 @@ Zmiana nazwy nie powiodła się. - Couldn’t create a .megaignore file for this sync + Nie można utworzyć pliku .megaignore dla tej synchronizacji Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 32603843ad..8cba314ee1 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -1,7 +1,7 @@ - لا يوجد خطأ في المزامنة + No sync error لا يمكن لميغا MEGA مزامنة هذا المجلد أو نسخه احتياطيًا لأن نظام الملفات على جهازك غير مدعوم. @@ -69,13 +69,13 @@ حدث خطأ ما. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + لا يمكن مزامنة المجلد أو نسخه احتياطيًا لأن مجلد ميغا MEGA موجود في سلة المحذوفات. Folder in your device can’t be located right now. Try again later. لا يمكن تحديد موقع المجلد في جهازك - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + حدثت مشكلة أثناء مزامنة هذا المجلد أو نسخه احتياطيًا بسبب التغييرات التي تم إجراؤها على مجلد ميغا MEGA. أوقف المزامنة أو النسخ الاحتياطي وحاول إعداده مرة أخرى في تطبيق الحاسوب المكتبي أو تواصل مع قسم الدعم. حدثت مشكلة في مزامنة هذا المجلد أو نسخه احتياطيًا. أوقف المزامنة أو النسخ الاحتياطي وحاول إعداده مرة أخرى في تطبيق الحاسوب المكتبي أو تواصل مع قسم الدعم. diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index cd187344a2..3899d27587 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup porque la carpeta de MEGA está en la Papelera. Folder in your device can’t be located right now. Try again later. Folder in your device can’t be located - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Ha habido un problema al sincronizar o hacer un backup de esta carpeta debido a unos cambios en la carpeta de MEGA. Detén la sincronización o el backup y actívalos de nuevo desde la aplicación de escritorio o contacta con el servicio de soporte. Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Detén la sincronización o el backup e intenta volver a configurarlos en la aplicación de escritorio, o ponte en contacto con el servicio de soporte. diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 9b019a1822..644930759d 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -1,7 +1,7 @@ - Aucune erreur de synchronisation + No sync error MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge. diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index d902103723..4cb9992c52 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + Folder tidak dapat disinkronkan atau dicadangkan karena folder MEGA ada di Tempat sampah. Folder in your device can’t be located right now. Try again later. Folder in your device can’t be located - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Masalah menyinkronkan atau membuat cadangan folder ini karena perubahan pada folder MEGA. Hentikan sinkronisasi atau pencadangan dan coba atur lagi di aplikasi Desktop, atau hubungi Dukungan. Masalah saat menyinkronkan atau membuat cadangan folder ini. Hentikan sinkronisasi atau pencadangan dan coba atur lagi di aplikasi Desktop, atau hubungi Bantuan. diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 8118aec315..8d710ade84 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino. Folder in your device can’t be located right now. Try again later. La cartella nel dispositivo non può essere localizzata - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Problema nella sincronizzazione o nel backup di questa cartella a causa di cambiamenti alla cartella MEGA. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente nell’app per desktop, o contatta il Supporto. Problemi nella sincronizzazione o nel backup di questa cartella. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente dall\’app per desktop, o contatta il Supporto. diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 7df4e2c2b3..29b8963c0a 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -1,7 +1,7 @@ - 同期エラーはありません + No sync error デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません。 diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 193daea2f1..ca649606c9 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -1,7 +1,7 @@ - Geen synchronisatiefout + No sync error MEGA kan geen synchronisatie of back-up van deze map maken omdat het bestandsysteem op uw apparaat niet ondersteund is. diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index c058519480..d6de02774f 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -11,23 +11,23 @@ Wstępne skanowanie nie powiodło się. Konieczne będzie ponowne włączenie synchronizacji lub kopii zapasowej w aplikacji Desktop. - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + Katalog w MEGA nie może być zlokalizowany, ponieważ został przeniesiony lub usunięty, lub możesz nie mieć dostępu Unable to sync or back up this folder as your storage is full - Unable to sync or back up this folder as your plan has expired + Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ plan wygasł - Folder can’t be synced as the user who shared this folder has reached their storage limit + Nie można zsynchronizować katalogu, ponieważ użytkownik, który udostępnił ten katalog, osiągnął pojemność miejsca - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + Katalog w MEGA nie może być zlokalizowany, ponieważ został przeniesiony lub usunięty, lub możesz nie mieć dostępu - Folder can’t be synced as it’s a shared folder that you don’t have full access to + Nie można zsynchronizować katalogu, ponieważ jest to katalog udostępniony, do którego nie masz pełny dostęp - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacja komputerowej. - Folder can’t be synced as it already contains synced folders + Nie można zsynchronizować katalogu, ponieważ zawiera już zsynchronizowane katalogi - MEGA can’t sync or back up VirtualBox folders + MEGA nie może synchronizować ani tworzyć kopii zapasowych katalogu VirtualBox Unable to sync or back up this folder as the account has been blocked @@ -41,11 +41,11 @@ Nie można zlokalizować katalogu na dysku zewnętrznym. - There’s already a synced folder at the same location + W tej samej lokalizacji znajduje się już zsynchronizowany katalog Zmiana nazwy nie powiodła się. - Couldn’t create a .megaignore file for this sync + Nie można utworzyć pliku .megaignore dla tej synchronizacji Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. @@ -61,21 +61,21 @@ Unable to open state cache database - Insufficient storage space on your device + Niewystarczająca ilość miejsca na urządzeniu Nie można odczytać lokalizacji synchronizacji. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu. - An unknown error occurred. Contact Support. + Wystąpił nieznany błąd. Skontaktuj się z pomocą techniczną. Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + Nie można synchronizować ani utworzyć kopii zapasowej katalogu, ponieważ katalog MEGA znajduje się w Koszu. - Folder in your device can’t be located right now. Try again later. + Katalog w urządzeniu nie może być teraz zlokalizowany. Spróbuj ponownie później. Nie można zlokalizować katalogu w urządzeniu - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu z powodu zmian w katalog MEGA. Zatrzymaj synchronizację lub kopię zapasową i spróbuj ponownie skonfigurować ją w aplikacja komputerowej lub kontakt techniczną. Problem z synchronizacją lub kopią zapasową tego katalogu. Zatrzymaj synchronizację lub tworzenie kopii zapasowej i spróbuj skonfigurować je ponownie w aplikacji Desktop lub skontaktuj się z pomocą techniczną. diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 0ebfb51052..f88782cac6 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -1,7 +1,7 @@ - Não há erros de sincronização + No sync error O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado. @@ -13,7 +13,7 @@ Não foi possível localizar a pasta no MEGA porque ela foi movida ou deletada, ou pode ser que você não tenha acesso a ela. - Unable to sync or back up this folder as your storage is full + Não foi possível sincronizar ou fazer backup dessa pasta porque a sua conta está cheia Não foi possível sincronizar ou fazer backup dessa pasta porque o seu plano expirou. @@ -29,7 +29,7 @@ O MEGA não pode sincronizar ou fazer backup das pastas do VirtualBox. - Unable to sync or back up this folder as the account has been blocked + Não foi possível sincronizar ou fazer backup dessa pasta porque a conta foi bloqueada Não foi possível sincronizar ou fazer o backup desta pasta. Tente novamente mais tarde. Se o problema persistir, entre em contato com a nossa equipe de Suporte. diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index c4dfe28d62..5b5b801036 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi. Folder in your device can’t be located right now. Try again later. Folderul din dispozitiv dvs. nu poate fi localizat - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. Problemă la sincronizarea sau backup a acestui folder. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index b617fd5a0e..b269af3fb1 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -75,7 +75,7 @@ Не удалось найти папку на вашем устройстве - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Проблема с синхронизацией или резервным копированием этой папки из-за изменений в папке MEGA. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. Проблема с синхронизацией или резервным копированием этой папки. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index a23a24a636..e4d78e35c7 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์ได้ เนื่องจากโฟลเดอร์ MEGA อยู่ในถังขยะ Folder in your device can’t be located right now. Try again later. ไม่สามารถหาโฟลเดอร์ในอุปกรณ์ของคุณได้ - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้เนื่องจากมีการเปลี่ยนแปลงในโฟลเดอร์ MEGA คุณสามารถหยุดการซิงค์หรือสำรองข้อมูลและลองตั้งค่าใหม่ในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน พบปัญหาในการซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ ให้หยุดการซิงค์หรือสำรองข้อมูล แล้วลองตั้งค่าอีกครั้งในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 328c4a2c16..e53768e4d1 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + 由于MEGA文件夹位于回收站中,文件夹无法同步或备份。 Folder in your device can’t be located right now. Try again later. 无法找到您设备中的文件夹 - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + 由于MEGA文件夹发生更改,因此同步或备份此文件夹时出现问题。请停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 同步或备份此文件夹时出现问题。停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index db6c471ef4..cc25220289 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -69,13 +69,13 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + 由於MEGA資料夾位於垃圾筒中,因此資料夾無法同步或備份。 Folder in your device can’t be located right now. Try again later. 無法找到您裝置中的資料夾 - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + 由於MEGA資料夾發生更動,因此同步或備份此資料夾時出現問題。請停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 同步或備份此資料夾時出現問題。停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 From 37e8adb3129d5355858ce333ae9e7c26f8b29fa0 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Mon, 8 Apr 2024 13:33:08 +1200 Subject: [PATCH 076/261] AND-18552 Fix email subject and body not populating in feedback email --- .../android/app/presentation/settings/FeedBackDialog.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt index 7ed5004135..68a7bab871 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/FeedBackDialog.kt @@ -104,12 +104,10 @@ class FeedBackDialog : DialogFragment() { private fun sendEmail(subject: String, body: String) { val emailIntent = Intent( - Intent.ACTION_SENDTO, Uri.fromParts( - "mailto", Constants.MAIL_ANDROID, null + Intent.ACTION_SENDTO, Uri.parse( + "mailto:${Constants.MAIL_ANDROID}?subject=$subject&body=$body" ) ) - emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) - emailIntent.putExtra(Intent.EXTRA_TEXT, body) if (emailIntent.canBeHandled(requireContext())) { startActivity(emailIntent) From bdf7c7f0cb66cf81c1b22f66f8206a76d9e1a4d7 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Sat, 6 Apr 2024 00:25:52 +1300 Subject: [PATCH 077/261] TRAN-337: Reported not-fatal exception:ForegroundServiceDidNotStartInTimeException --- .../privacy/android/app/MegaApplication.kt | 5 - .../BackgroundRequestListener.kt | 3 - .../app/presentation/login/LoginViewModel.kt | 6 +- .../app/data/worker/ChatUploadsWorkerTest.kt | 6 + .../presentation/login/LoginViewModelTest.kt | 6 +- .../app/transfers/DownloadsWorkerTest.kt | 35 +++++ .../privacy/android/data/di/WorkerModule.kt | 20 +++ .../data/worker/AbstractTransfersWorker.kt | 129 +++++++++++------- .../android/data/worker/ChatUploadsWorker.kt | 6 +- .../android/data/worker/DownloadsWorker.kt | 4 +- 10 files changed, 153 insertions(+), 67 deletions(-) create mode 100644 data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt diff --git a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt index 56c69887c7..167514d927 100644 --- a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt +++ b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt @@ -228,11 +228,6 @@ class MegaApplication : MultiDexApplication(), DefaultLifecycleObserver, setupMegaChatApi() getMiscFlagsIfNeeded() - //Logout check resumed pending transfers - transfersManagement.apply { - checkResumedPendingTransfers() - } - applicationScope.launch { runCatching { updateApiServerUseCase() } dbH.resetExtendedAccountDetailsTimestamp() diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt index a1de505988..4fff3448f5 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt @@ -51,7 +51,6 @@ class BackgroundRequestListener @Inject constructor( private val megaChatApi: MegaChatApiAndroid, private val dbH: DatabaseHandler, @MegaApi private val megaApi: MegaApiAndroid, - private val transfersManagement: TransfersManagement, @ApplicationScope private val applicationScope: CoroutineScope, private val getFullAccountInfoUseCase: GetFullAccountInfoUseCase, private val broadcastFetchNodesFinishUseCase: BroadcastFetchNodesFinishUseCase, @@ -167,8 +166,6 @@ class BackgroundRequestListener @Inject constructor( if (dbH.myChatFilesFolderHandle == INVALID_HANDLE) { megaApi.getMyChatFilesFolder(listener) } - //Login check resumed pending transfers - transfersManagement.checkResumedPendingTransfers() applicationScope.launch { // Init CU sync data after login successfully runCatching { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt index 11e7677663..f02cc4647a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginViewModel.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.sync.Mutex import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.R import mega.privacy.android.app.featuretoggle.AppFeatures +import mega.privacy.android.app.globalmanagement.TransfersManagement import mega.privacy.android.app.logging.LegacyLoggingSettings import mega.privacy.android.app.presentation.extensions.error import mega.privacy.android.app.presentation.extensions.getState @@ -118,7 +119,8 @@ class LoginViewModel @Inject constructor( private val getTimelinePhotosUseCase: GetTimelinePhotosUseCase, private val startDownloadWorkerUseCase: StartDownloadWorkerUseCase, private val startChatUploadsWorkerUseCase: StartChatUploadsWorkerUseCase, - @LoginMutex private val loginMutex: Mutex + @LoginMutex private val loginMutex: Mutex, + private val transfersManagement: TransfersManagement, ) : ViewModel() { private val _state = MutableStateFlow(LoginState()) @@ -728,6 +730,8 @@ class LoginViewModel @Inject constructor( if (getFeatureFlagValueUseCase(AppFeatures.NewChatActivity)) { startChatUploadsWorkerUseCase() } + //Login check resumed pending transfers + transfersManagement.checkResumedPendingTransfers() } else { Timber.d("fetch nodes update") _state.update { it.copy(fetchNodesUpdate = update) } diff --git a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt index 752d8ace28..3317079308 100644 --- a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt @@ -15,6 +15,7 @@ import androidx.work.impl.utils.taskexecutor.WorkManagerTaskExecutor import androidx.work.workDataOf import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -23,6 +24,7 @@ import mega.privacy.android.data.mapper.transfer.ChatUploadNotificationMapper import mega.privacy.android.data.mapper.transfer.OverQuotaNotificationBuilder import mega.privacy.android.data.worker.AreNotificationsEnabledUseCase import mega.privacy.android.data.worker.ChatUploadsWorker +import mega.privacy.android.data.worker.ForegroundSetter import mega.privacy.android.domain.entity.chat.PendingMessage import mega.privacy.android.domain.entity.chat.PendingMessageState import mega.privacy.android.domain.entity.chat.messages.pending.UpdatePendingMessageStateRequest @@ -86,6 +88,7 @@ class ChatUploadsWorkerTest { private val chatMessageRepository = mock() private val updatePendingMessageUseCase = mock() private val checkFinishedChatUploadsUseCase = mock() + private val setForeground = mock() @Before fun init() { @@ -129,6 +132,7 @@ class ChatUploadsWorkerTest { attachNodeWithPendingMessageUseCase, updatePendingMessageUseCase, checkFinishedChatUploadsUseCase, + setForeground, ) } @@ -216,9 +220,11 @@ class ChatUploadsWorkerTest { whenever(monitorOngoingActiveTransfersUseCase(TransferType.CHAT_UPLOAD)) doReturn (flowOf( MonitorOngoingActiveTransfersResult(totals, paused = false, overQuota = false) )) + whenever(monitorTransferEventsUseCase()) doReturn (emptyFlow()) whenever(workProgressUpdater.updateProgress(any(), any(), any())) .thenReturn(SettableFuture.create().also { it.set(null) }) whenever(areNotificationsEnabledUseCase()).thenReturn(false) + whenever(getActiveTransferTotalsUseCase(TransferType.CHAT_UPLOAD)).thenReturn(totals) return finishEvent } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt index f7613349b1..c9f69e4056 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/login/LoginViewModelTest.kt @@ -2,7 +2,6 @@ package test.mega.privacy.android.app.presentation.login import app.cash.turbine.test import com.google.common.truth.Truth.assertThat -import de.palm.composestateevents.StateEventWithContent import de.palm.composestateevents.consumed import de.palm.composestateevents.triggered import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -14,6 +13,7 @@ import kotlinx.coroutines.test.TestCoroutineScheduler import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import mega.privacy.android.app.R +import mega.privacy.android.app.globalmanagement.TransfersManagement import mega.privacy.android.app.logging.LegacyLoggingSettings import mega.privacy.android.app.presentation.login.LoginViewModel import mega.privacy.android.app.presentation.login.model.LoginError @@ -96,6 +96,7 @@ internal class LoginViewModelTest { private val getTimelinePhotosUseCase = mock() private val startDownloadWorkerUseCase = mock() private val startChatUploadsWorkerUseCase = mock() + private val transfersManagement = mock() @BeforeEach fun setUp() { @@ -129,7 +130,8 @@ internal class LoginViewModelTest { getTimelinePhotosUseCase = getTimelinePhotosUseCase, startDownloadWorkerUseCase = startDownloadWorkerUseCase, startChatUploadsWorkerUseCase = startChatUploadsWorkerUseCase, - loginMutex = mock() + loginMutex = mock(), + transfersManagement = transfersManagement, ) } diff --git a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt index 3707708744..25094e2a46 100644 --- a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt @@ -29,6 +29,7 @@ import mega.privacy.android.data.mapper.transfer.TransfersFinishedNotificationMa import mega.privacy.android.data.worker.AbstractTransfersWorker import mega.privacy.android.data.worker.AreNotificationsEnabledUseCase import mega.privacy.android.data.worker.DownloadsWorker +import mega.privacy.android.data.worker.ForegroundSetter import mega.privacy.android.domain.entity.Progress import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.MonitorOngoingActiveTransfersResult @@ -89,6 +90,7 @@ class DownloadsWorkerTest { private val transfersFinishedNotificationMapper = mock() private val workProgressUpdater = mock() private val scanMediaFileUseCase = mock() + private val setForeground = mock() @Before fun setup() { @@ -133,6 +135,7 @@ class DownloadsWorkerTest { handleSDCardEventUseCase = handleSDCardEventUseCase, scanMediaFileUseCase = scanMediaFileUseCase, handleAvailableOfflineEventUseCase = handleAvailableOfflineEventUseCase, + foregroundSetter = setForeground ) } @@ -252,6 +255,37 @@ class DownloadsWorkerTest { verifyNoInteractions(overQuotaNotificationBuilder) } + fun `test that setForeground is not invoked when worker starts with no transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals( + hasCompleted = false, + ) + whenever(initial.totalTransfers).thenReturn(0) + commonStub(initialTransferTotals = initial) + underTest.doWork() + verifyNoInteractions(setForeground) + } + + @Test + fun `test that transfersFinishedNotificationMapper is invoked when worker starts with completed transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals(true) + whenever(initial.totalTransfers).thenReturn(1) + commonStub(initialTransferTotals = initial) + underTest.doWork() + verify(transfersFinishedNotificationMapper).invoke(initial) + } + + @Test + fun `test that setForeground is not invoked when worker starts with completed transfers`() = + runTest { + val initial: ActiveTransferTotals = mockActiveTransferTotals(true) + commonStub(initialTransferTotals = initial) + whenever(initial.totalTransfers).thenReturn(1) + underTest.doWork() + verifyNoInteractions(setForeground) + } + @Test fun `test that transfersFinishedNotificationMapper is not invoked when transfer finishes with no transfers`() = runTest { @@ -342,6 +376,7 @@ class DownloadsWorkerTest { whenever(areNotificationsEnabledUseCase()).thenReturn(true) whenever(workProgressUpdater.updateProgress(any(), any(), any())) .thenReturn(SettableFuture.create().also { it.set(null) }) + whenever(downloadNotificationMapper(any(), any())).thenReturn(mock()) } private fun mockActiveTransferTotals( diff --git a/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt b/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt new file mode 100644 index 0000000000..33230b3652 --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/di/WorkerModule.kt @@ -0,0 +1,20 @@ +package mega.privacy.android.data.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import mega.privacy.android.data.worker.ForegroundSetter + +/** + * Module for workers + */ +@Module +@InstallIn(SingletonComponent::class) +object WorkerModule { + /** + * Provides [ForegroundSetter] to its default null value + */ + @Provides + fun provideForegroundSetter(): ForegroundSetter? = null +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt index aaf2ce804d..3c578caf2f 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt @@ -15,14 +15,12 @@ import androidx.work.workDataOf import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.last import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import kotlinx.coroutines.yield import mega.privacy.android.data.mapper.transfer.OverQuotaNotificationBuilder import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferEvent @@ -38,6 +36,7 @@ import timber.log.Timber /** * Abstract CoroutineWorker to share common implementation of transfers workers + * @param foregroundSetter to inject the set foreground method, used for testing */ abstract class AbstractTransfersWorker( context: Context, @@ -54,6 +53,7 @@ abstract class AbstractTransfersWorker( private val areNotificationsEnabledUseCase: AreNotificationsEnabledUseCase, private val correctActiveTransfersUseCase: CorrectActiveTransfersUseCase, private val clearActiveTransfersIfFinishedUseCase: ClearActiveTransfersIfFinishedUseCase, + private val foregroundSetter: ForegroundSetter?, ) : CoroutineWorker(context, workerParams) { /** @@ -69,7 +69,7 @@ abstract class AbstractTransfersWorker( /** * Create the update Notification to show worker progress */ - abstract suspend fun createUpdateNotification( + abstract fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ): Notification @@ -90,61 +90,74 @@ abstract class AbstractTransfersWorker( */ open suspend fun onTransferEventReceived(event: TransferEvent) {} - override suspend fun doWork() = coroutineScope { + override suspend fun doWork() = withContext(ioDispatcher) { Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Started") + val monitorJob = monitorTransferEvents(this) + correctActiveTransfersUseCase(type) //to be sure we haven't missed any event before monitoring them + val activeTransferTotals = getActiveTransferTotalsUseCase(type) + if (activeTransferTotals.hasCompleted()) { + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} No transfers to monitor") + stopService(monitorJob) + if (activeTransferTotals.totalTransfers > 0) { + showFinishNotification(activeTransferTotals) + } + return@withContext Result.success() + } // Signal to not kill the worker if the app is killed - setForegroundAsync(getForegroundInfo()) - - withContext(ioDispatcher) { - val monitorJob = monitorTransferEvents(this) - correctActiveTransfersUseCase(type) //to be sure we haven't missed any event before monitoring them - onStart() - monitorOngoingActiveTransfersUseCase(type) - .catch { Timber.e("${this@AbstractTransfersWorker::class.java.simpleName}error: $it") } - .onEach { (transferTotals, paused, _) -> - //set progress percent as worker progress - setProgress(workDataOf(PROGRESS to transferTotals.transferProgress.floatValue)) - //update the notification - notify(createUpdateNotification(transferTotals, paused)) - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}${if (paused) "(paused) " else ""} Notification update (${transferTotals.transferProgress.intValue}):${transferTotals.hasOngoingTransfers()}") - } - .last().let { (lastActiveTransferTotals, _, overQuota) -> - stopService(monitorJob) - clearActiveTransfersIfFinishedUseCase(type) - if (lastActiveTransferTotals.hasCompleted()) { - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Finished Successful: $lastActiveTransferTotals") - if (lastActiveTransferTotals.totalTransfers > 0) { - showFinishNotification(lastActiveTransferTotals) - } - Result.success() + val foregroundInfo = getForegroundInfo(activeTransferTotals, areTransfersPausedUseCase()) + foregroundSetter?.setForeground(foregroundInfo) ?: run { + setForeground(foregroundInfo) + } + + onStart() + monitorOngoingActiveTransfersUseCase(type) + .catch { Timber.e("${this@AbstractTransfersWorker::class.java.simpleName}error: $it") } + .onEach { (transferTotals, paused, _) -> + //set progress percent as worker progress + setProgress(workDataOf(PROGRESS to transferTotals.transferProgress.floatValue)) + //update the notification + notify(createUpdateNotification(transferTotals, paused)) + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}${if (paused) "(paused) " else ""} Notification update (${transferTotals.transferProgress.intValue}):${transferTotals.hasOngoingTransfers()}") + } + .last().let { (lastActiveTransferTotals, _, overQuota) -> + stopService(monitorJob) + if (lastActiveTransferTotals.hasCompleted()) { + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Finished Successful: $lastActiveTransferTotals") + if (lastActiveTransferTotals.totalTransfers > 0) { + showFinishNotification(lastActiveTransferTotals) + } + Result.success() + } else { + if (overQuota + && !ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast( + Lifecycle.State.STARTED + ) + ) { + //the over quota notification is shown if the app is in background (if not a full dialog will be shown in the app) + showFinalNotification( + overQuotaNotificationBuilder(), + NOTIFICATION_STORAGE_OVERQUOTA + ) } else { - if (overQuota - && !ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast( - Lifecycle.State.STARTED - ) - ) { - //the over quota notification is shown if the app is in background (if not a full dialog will be shown in the app) - showFinalNotification( - overQuotaNotificationBuilder(), - NOTIFICATION_STORAGE_OVERQUOTA - ) - } else { - showFinishNotification(lastActiveTransferTotals) - } - Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}finished Failure: $lastActiveTransferTotals") - Result.failure()//to retry in the future + showFinishNotification(lastActiveTransferTotals) } + Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}finished Failure: $lastActiveTransferTotals") + Result.failure()//to retry in the future } - } + } } - override suspend fun getForegroundInfo() = - createForegroundInfo( - createUpdateNotification( - getActiveTransferTotalsUseCase(type), - areTransfersPausedUseCase() - ) - ) + override suspend fun getForegroundInfo() = getForegroundInfo( + getActiveTransferTotalsUseCase(type), + areTransfersPausedUseCase() + ) + + private fun getForegroundInfo( + activeTransferTotals: ActiveTransferTotals, + paused: Boolean, + ): ForegroundInfo { + return createForegroundInfo(createUpdateNotification(activeTransferTotals, paused)) + } /** * Monitors transfer events and update the related active transfers @@ -161,8 +174,8 @@ abstract class AbstractTransfersWorker( private suspend fun stopService(monitorJob: Job) { monitorJob.cancel() - yield() notificationManager.cancel(updateNotificationId) + clearActiveTransfersIfFinishedUseCase(type) } @SuppressLint("MissingPermission") @@ -217,4 +230,14 @@ abstract class AbstractTransfersWorker( const val PROGRESS = "Progress" private const val NOTIFICATION_STORAGE_OVERQUOTA = 14 } -} \ No newline at end of file +} + +/** + * Interface to inject the set foreground method, used for testing + */ +interface ForegroundSetter { + /** + * Set foreground + */ + suspend fun setForeground(foregroundInfo: ForegroundInfo) +} diff --git a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt index cc67ef4413..e7e9b47b27 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt @@ -52,6 +52,7 @@ class ChatUploadsWorker @AssistedInject constructor( private val attachNodeWithPendingMessageUseCase: AttachNodeWithPendingMessageUseCase, private val updatePendingMessageUseCase: UpdatePendingMessageUseCase, private val checkFinishedChatUploadsUseCase: CheckFinishedChatUploadsUseCase, + foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( context, workerParams, @@ -67,10 +68,11 @@ class ChatUploadsWorker @AssistedInject constructor( areNotificationsEnabledUseCase, correctActiveTransfersUseCase, clearActiveTransfersIfFinishedUseCase, + foregroundSetter, ) { override val updateNotificationId = NOTIFICATION_CHAT_UPLOAD - override suspend fun createUpdateNotification( + override fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ) = chatUploadNotificationMapper(activeTransferTotals, null, paused) @@ -115,4 +117,4 @@ class ChatUploadsWorker @AssistedInject constructor( const val SINGLE_CHAT_UPLOAD_TAG = "MEGA_CHAT_UPLOAD_TAG" private const val NOTIFICATION_CHAT_UPLOAD = 15 } -} \ No newline at end of file +} diff --git a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt index 9f1a5c8b2f..4147e5b8f2 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt @@ -50,6 +50,7 @@ class DownloadsWorker @AssistedInject constructor( private val handleSDCardEventUseCase: HandleSDCardEventUseCase, private val scanMediaFileUseCase: ScanMediaFileUseCase, private val handleAvailableOfflineEventUseCase: HandleAvailableOfflineEventUseCase, + foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( context, workerParams, @@ -65,12 +66,13 @@ class DownloadsWorker @AssistedInject constructor( areNotificationsEnabledUseCase, correctActiveTransfersUseCase, clearActiveTransfersIfFinishedUseCase, + foregroundSetter, ) { override val finalNotificationId = DOWNLOAD_NOTIFICATION_ID override val updateNotificationId = NOTIFICATION_DOWNLOAD_FINAL - override suspend fun createUpdateNotification( + override fun createUpdateNotification( activeTransferTotals: ActiveTransferTotals, paused: Boolean, ) = downloadNotificationMapper(activeTransferTotals, paused) From c7e8ff1ec6122b4821e103196da733610cef4745 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Mon, 8 Apr 2024 11:20:00 +0800 Subject: [PATCH 078/261] Update version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9ae60eba1c..c642971e97 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -73,7 +73,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "11.9" +extra["appVersion"] = "11.9.1" // Sdk and tools extra["compileSdkVersion"] = 34 From 860901a430e19b124b4c9c6a8062d25525fd019c Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Mon, 8 Apr 2024 16:36:18 +1200 Subject: [PATCH 079/261] AND-18581: VideoLauncher Crash issue --- .../imagepreview/ImagePreviewVideoLauncher.kt | 49 +++++++------------ 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt index e21d43bf8c..56f18830a8 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt @@ -19,6 +19,7 @@ import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerIsRunnin import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerStartUseCase import mega.privacy.android.domain.usecase.node.AddImageTypeUseCase import nz.mega.sdk.MegaNode +import timber.log.Timber import java.io.File import javax.inject.Inject @@ -117,43 +118,27 @@ class ImagePreviewVideoLauncher @Inject constructor( intent: Intent, source: ImagePreviewFetcherSource, ): Intent { - if (megaApiHttpServerIsRunningUseCase() == 0) { - megaApiHttpServerStartUseCase() - intent.putExtra(Constants.INTENT_EXTRA_KEY_NEED_STOP_HTTP_SERVER, true) - } - - when (source) { - ImagePreviewFetcherSource.CHAT -> { - getFileUrlByImageNodeUseCase(imageNode as ChatImageFile).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + runCatching { + if (megaApiHttpServerIsRunningUseCase() == 0) { + megaApiHttpServerStartUseCase() + intent.putExtra(Constants.INTENT_EXTRA_KEY_NEED_STOP_HTTP_SERVER, true) } - ImagePreviewFetcherSource.FOLDER_LINK, - ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY, - -> { - getFileUrlByImageNodeUseCase( - PublicLinkFile( - node = addImageTypeUseCase(imageNode), - parent = null - ) - ).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + val url = when (source) { + ImagePreviewFetcherSource.CHAT -> getFileUrlByImageNodeUseCase(imageNode as ChatImageFile) + ImagePreviewFetcherSource.FOLDER_LINK, ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY -> getFileUrlByImageNodeUseCase( + PublicLinkFile(node = addImageTypeUseCase(imageNode), parent = null) + ) + + else -> getFileUrlByImageNodeUseCase(addImageTypeUseCase(imageNode)) } - else -> { - getFileUrlByImageNodeUseCase(addImageTypeUseCase(imageNode)).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + url?.takeIf { it.isNotEmpty() }?.let { urlString -> + Uri.parse(urlString)?.let { uri -> + intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) + } ?: throw IllegalArgumentException("Invalid URL: $urlString") } - } + }.onFailure { e -> Timber.e("updateIntent", "Error updating intent: ${e.message}", e) } return intent } From 127dbe258b12f7afa1da479446356db78fdb3cc6 Mon Sep 17 00:00:00 2001 From: JoeJi Date: Mon, 8 Apr 2024 16:54:16 +1200 Subject: [PATCH 080/261] fix crash issue release/11.9.1 --- .../imagepreview/ImagePreviewVideoLauncher.kt | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt index a5b9e13ae4..27c2102142 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt @@ -19,6 +19,7 @@ import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerIsRunnin import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerStartUseCase import mega.privacy.android.domain.usecase.node.AddImageTypeUseCase import nz.mega.sdk.MegaNode +import timber.log.Timber import java.io.File import javax.inject.Inject @@ -117,43 +118,30 @@ class ImagePreviewVideoLauncher @Inject constructor( intent: Intent, source: ImagePreviewFetcherSource, ): Intent { - if (megaApiHttpServerIsRunningUseCase() == 0) { - megaApiHttpServerStartUseCase() - intent.putExtra(Constants.INTENT_EXTRA_KEY_NEED_STOP_HTTP_SERVER, true) - } - - when (source) { - ImagePreviewFetcherSource.SHARED_FILES_HISTORY -> { - getFileUrlByImageNodeUseCase(imageNode as ChatImageFile).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + runCatching { + if (megaApiHttpServerIsRunningUseCase() == 0) { + megaApiHttpServerStartUseCase() + intent.putExtra(Constants.INTENT_EXTRA_KEY_NEED_STOP_HTTP_SERVER, true) } - ImagePreviewFetcherSource.FOLDER_LINK, - ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY, - -> { - getFileUrlByImageNodeUseCase( - PublicLinkFile( - node = addImageTypeUseCase(imageNode), - parent = null - ) - ).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + val url = when (source) { + ImagePreviewFetcherSource.SHARED_FILES_HISTORY -> getFileUrlByImageNodeUseCase( + imageNode as ChatImageFile + ) + + ImagePreviewFetcherSource.FOLDER_LINK, ImagePreviewFetcherSource.FOLDER_LINK_MEDIA_DISCOVERY -> getFileUrlByImageNodeUseCase( + PublicLinkFile(node = addImageTypeUseCase(imageNode), parent = null) + ) + + else -> getFileUrlByImageNodeUseCase(addImageTypeUseCase(imageNode)) } - else -> { - getFileUrlByImageNodeUseCase(addImageTypeUseCase(imageNode)).let { url -> - Uri.parse(url)?.let { uri -> - intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) - } - } + url?.takeIf { it.isNotEmpty() }?.let { urlString -> + Uri.parse(urlString)?.let { uri -> + intent.setDataAndType(uri, MimeTypeList.typeForName(imageNode.name).type) + } ?: throw IllegalArgumentException("Invalid URL: $urlString") } - } + }.onFailure { e -> Timber.e("updateIntent", "Error updating intent: ${e.message}", e) } return intent } From 89f00bedee965fde9bd8a5f1c73b1d4ce1ac70ee Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Mon, 8 Apr 2024 08:12:46 +0530 Subject: [PATCH 081/261] AND-18517: (T15744661)optimise cloud drive search- folder title not updated correctly --- .../app/presentation/clouddrive/FileBrowserComposeFragment.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt index 5c590b66c0..1ad6edafb2 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt @@ -227,9 +227,7 @@ class FileBrowserComposeFragment : Fragment() { fileCount = uiState.selectedFileNodes, folderCount = uiState.selectedFolderNodes ) - LaunchedEffect(uiState.currentFileNode) { - onItemClick(uiState.currentFileNode) - } + onItemClick(uiState.currentFileNode) HandleMediaDiscoveryVisibility( isMediaDiscoveryOpen = uiState.isMediaDiscoveryOpen, isMediaDiscoveryOpenedByIconClick = uiState.isMediaDiscoveryOpenedByIconClick, From a7e79e9eec8a244e92d8511d92b8b3fb55cd5000 Mon Sep 17 00:00:00 2001 From: Rohit Soni Date: Mon, 8 Apr 2024 18:52:00 +1200 Subject: [PATCH 082/261] SAO-53 hotfix/ (t15672083) update device file and folder icons " --- .../clouddrive/FileBrowserComposeFragment.kt | 8 +++ .../clouddrive/ui/FileBrowserComposeView.kt | 5 +- .../folderlink/FolderLinkComposeActivity.kt | 13 ++++- .../folderlink/view/FolderLinkView.kt | 5 +- .../rubbishbin/RubbishBinComposeFragment.kt | 10 +++- .../rubbishbin/view/RubbishBinComposeView.kt | 8 +-- .../app/presentation/search/SearchActivity.kt | 8 +++ .../app/presentation/search/SearchNavGraph.kt | 3 ++ .../search/SearchNavHostController.kt | 5 +- .../app/presentation/search/SearchScreen.kt | 3 ++ .../search/view/SearchComposeView.kt | 6 ++- .../incoming/IncomingSharesComposeFragment.kt | 8 +++ .../shares/incoming/ui/IncomingSharesView.kt | 3 ++ .../shares/links/LinksComposeFragment.kt | 8 +++ .../shares/links/view/LinksView.kt | 5 +- .../outgoing/OutgoingSharesComposeFragment.kt | 8 +++ .../shares/outgoing/ui/OutgoingSharesView.kt | 5 +- .../videosection/VideoSelectedActivity.kt | 10 +++- .../view/videoselected/VideoSelectedScreen.kt | 10 +++- .../view/videoselected/VideoSelectedView.kt | 11 ++-- .../app/presentation/view/NodeGridView.kt | 3 ++ .../app/presentation/view/NodeGridViewItem.kt | 5 +- .../app/presentation/view/NodeListView.kt | 23 ++++++--- .../app/presentation/view/NodesView.kt | 6 ++- .../incoming/ui/IncomingSharesViewTest.kt | 9 +++- .../outgoing/ui/OutgoingSharesViewTest.kt | 9 +++- .../folderlink/FolderLinkViewTest.kt | 4 +- .../RubbishBinComposeFragmentTest.kt | 6 ++- .../videosection/VideoSelectedViewTest.kt | 5 +- .../app/presentation/view/NodesViewTest.kt | 17 +++++-- .../devicecenter/ui/DeviceCenterInfoScreen.kt | 5 +- .../bottomsheet/tiles/InfoBottomSheetTile.kt | 3 +- .../tiles/RenameDeviceBottomSheetTile.kt | 3 +- .../ui/model/DeviceCenterInfoUiState.kt | 4 +- .../ui/model/icon/DeviceIconType.kt | 16 +++--- .../ui/model/icon/FolderIconType.kt | 10 ++-- .../res/drawable/ic_bottom_sheet_info.xml | 11 ---- .../res/drawable/ic_bottom_sheet_rename.xml | 11 ---- .../main/res/drawable/ic_device_android.xml | 22 -------- .../main/res/drawable/ic_device_folder.xml | 22 -------- .../res/drawable/ic_device_folder_backup.xml | 22 -------- .../ic_device_folder_camera_uploads.xml | 22 -------- .../res/drawable/ic_device_folder_sync.xml | 22 -------- .../src/main/res/drawable/ic_device_ios.xml | 22 -------- .../src/main/res/drawable/ic_device_pc.xml | 22 -------- .../main/res/drawable/ic_device_pc_linux.xml | 22 -------- .../main/res/drawable/ic_device_pc_mac.xml | 22 -------- .../res/drawable/ic_device_pc_windows.xml | 22 -------- .../res/drawable/ic_android_medium_solid.xml | 50 +++++++++++++++++++ .../main/res/drawable/ic_ios_medium_solid.xml | 22 ++++++++ .../res/drawable/ic_mobile_medium_solid.xml | 2 +- 51 files changed, 287 insertions(+), 299 deletions(-) delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_info.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_rename.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_android.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_folder.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_folder_backup.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_folder_camera_uploads.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_folder_sync.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_ios.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_pc.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_pc_linux.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_pc_mac.xml delete mode 100644 feature/devicecenter/src/main/res/drawable/ic_device_pc_windows.xml create mode 100644 icon-pack/src/main/res/drawable/ic_android_medium_solid.xml create mode 100644 icon-pack/src/main/res/drawable/ic_ios_medium_solid.xml rename feature/devicecenter/src/main/res/drawable/ic_device_mobile.xml => icon-pack/src/main/res/drawable/ic_mobile_medium_solid.xml (63%) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt index 1ad6edafb2..49a7fd7a5e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserComposeFragment.kt @@ -72,6 +72,7 @@ import mega.privacy.android.domain.entity.node.MoveRequestResult import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.mobile.analytics.event.CloudDriveScreenEvent import timber.log.Timber @@ -118,6 +119,12 @@ class FileBrowserComposeFragment : Fragment() { @Inject lateinit var getOptionsForToolbarMapper: GetOptionsForToolbarMapper + /** + * Mapper to get icon for file type + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private val fileBrowserViewModel: FileBrowserViewModel by activityViewModels() private val sortByHeaderViewModel: SortByHeaderViewModel by activityViewModels() @@ -205,6 +212,7 @@ class FileBrowserComposeFragment : Fragment() { isMediaDiscoveryOpenedByIconClick = true, ) }, + fileTypeIconMapper = fileTypeIconMapper, ) // Snackbar host state should be attached to snackbar host in the scaffold, but we don't have a scaffold yet diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/ui/FileBrowserComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/ui/FileBrowserComposeView.kt index 1f0af99fdd..995eca90e4 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/ui/FileBrowserComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/ui/FileBrowserComposeView.kt @@ -30,6 +30,7 @@ import mega.privacy.android.core.ui.utils.getState import mega.privacy.android.core.ui.utils.sync import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** @@ -61,6 +62,7 @@ fun FileBrowserComposeView( onUpgradeClicked: () -> Unit, onDismissClicked: () -> Unit, onEnterMediaDiscoveryClick: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper, ) { var listStateMap by rememberSaveable(saver = ListGridStateMap.Saver) { @@ -109,7 +111,8 @@ fun FileBrowserComposeView( onDisputeTakeDownClicked = onDisputeTakeDownClicked, showMediaDiscoveryButton = uiState.showMediaDiscoveryIcon, onEnterMediaDiscoveryClick = onEnterMediaDiscoveryClick, - listContentPadding = PaddingValues(top = 18.dp) + listContentPadding = PaddingValues(top = 18.dp), + fileTypeIconMapper = fileTypeIconMapper ) } } else { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/FolderLinkComposeActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/FolderLinkComposeActivity.kt index fb562bda44..1e958f6f44 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/FolderLinkComposeActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/FolderLinkComposeActivity.kt @@ -70,6 +70,7 @@ import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import nz.mega.sdk.MegaNode import timber.log.Timber @@ -82,9 +83,18 @@ import javax.inject.Inject class FolderLinkComposeActivity : TransfersManagementActivity(), DecryptAlertDialog.DecryptDialogListener { + /** + * Use case to get the value of a feature flag + */ @Inject lateinit var getFeatureFlagValueUseCase: GetFeatureFlagValueUseCase + /** + * Mapper to get the icon of a file type + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private lateinit var binding: ActivityFolderLinkComposeBinding private val viewModel: FolderLinkViewModel by viewModels() @@ -253,7 +263,8 @@ class FolderLinkComposeActivity : TransfersManagementActivity(), } adsViewModel.fetchNewAd(AdsSlotIDs.SHARED_LINK_SLOT_ID) }, - onAdDismissed = adsViewModel::onAdConsumed + onAdDismissed = adsViewModel::onAdConsumed, + fileTypeIconMapper = fileTypeIconMapper ) StartDownloadComponent( event = uiState.downloadEvent, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt index de5a87b616..328eba7420 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt @@ -76,6 +76,7 @@ import mega.privacy.android.core.ui.theme.extensions.teal_300_teal_200 import mega.privacy.android.core.ui.theme.white import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import nz.mega.sdk.MegaNode @@ -152,6 +153,7 @@ internal fun FolderLinkView( adsUiState: AdsUIState, onAdClicked: (uri: Uri?) -> Unit, onAdDismissed: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper, ) { val listState = rememberLazyListState() val gridState = rememberLazyGridState() @@ -273,7 +275,8 @@ internal fun FolderLinkView( onDisputeTakeDownClicked = onDisputeTakeDownClicked, showMediaDiscoveryButton = state.hasMediaItem, onEnterMediaDiscoveryClick = onEnterMediaDiscoveryClick, - isPublicNode = true + isPublicNode = true, + fileTypeIconMapper = fileTypeIconMapper ) ImportDownloadView( Modifier diff --git a/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragment.kt index b3a06db9a9..bee014b2d2 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragment.kt @@ -46,6 +46,7 @@ import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import nz.mega.sdk.MegaChatApiJava import nz.mega.sdk.MegaNode import timber.log.Timber @@ -70,6 +71,12 @@ class RubbishBinComposeFragment : Fragment() { @Inject lateinit var getThemeMode: GetThemeMode + /** + * FileTypeIconMapper + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private val viewModel: RubbishBinViewModel by activityViewModels() private val managerViewModel: ManagerViewModel by activityViewModels() private val sortByHeaderViewModel: SortByHeaderViewModel by activityViewModels() @@ -111,7 +118,8 @@ class RubbishBinComposeFragment : Fragment() { ), emptyState = getEmptyFolderDrawable(uiState.isRubbishBinEmpty), onLinkClicked = ::navigateToLink, - onDisputeTakeDownClicked = ::navigateToLink + onDisputeTakeDownClicked = ::navigateToLink, + fileTypeIconMapper = fileTypeIconMapper ) } updateActionModeTitle( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/view/RubbishBinComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/view/RubbishBinComposeView.kt index 878b5248bf..b6d9167ecb 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/view/RubbishBinComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/rubbishbin/view/RubbishBinComposeView.kt @@ -11,9 +11,10 @@ import mega.privacy.android.app.presentation.data.NodeUIItem import mega.privacy.android.app.presentation.rubbishbin.model.RubbishBinState import mega.privacy.android.app.presentation.view.NODES_EMPTY_VIEW_VISIBLE import mega.privacy.android.app.presentation.view.NodesView -import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper +import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** * View for RubbishBinComposeFragment @@ -25,7 +26,6 @@ import mega.privacy.android.domain.entity.preference.ViewType * @param onChangeViewTypeClick * @param sortOrder * @param emptyState - * @param thumbnailViewModel */ @Composable fun RubbishBinComposeView( @@ -39,6 +39,7 @@ fun RubbishBinComposeView( emptyState: Pair, onLinkClicked: (String) -> Unit, onDisputeTakeDownClicked: (String) -> Unit, + fileTypeIconMapper: FileTypeIconMapper, ) { val listState = rememberLazyListState() val gridState = rememberLazyGridState() @@ -55,7 +56,8 @@ fun RubbishBinComposeView( listState = listState, gridState = gridState, onLinkClicked = onLinkClicked, - onDisputeTakeDownClicked = onDisputeTakeDownClicked + onDisputeTakeDownClicked = onDisputeTakeDownClicked, + fileTypeIconMapper = fileTypeIconMapper ) } else { LegacyMegaEmptyView( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt index 90fbe6ecea..29b10a4a1d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt @@ -100,6 +100,7 @@ import mega.privacy.android.domain.entity.node.TypedFolderNode import mega.privacy.android.domain.entity.search.SearchCategory import mega.privacy.android.domain.usecase.GetThemeMode import mega.privacy.android.feature.sync.data.mapper.ListToStringWithDelimitersMapper +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.mobile.analytics.event.SearchAudioFilterPressedEvent import mega.privacy.mobile.analytics.event.SearchDocsFilterPressedEvent @@ -160,6 +161,12 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { @Inject lateinit var moveRequestMessageMapper: MoveRequestMessageMapper + /** + * File type icon mapper + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private val snackbarHostState = SnackbarHostState() companion object { @@ -301,6 +308,7 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { } } }, + fileTypeIconMapper = fileTypeIconMapper, onBackPressed = { if (viewModel.state.value.selectedNodes.isNotEmpty()) { viewModel.clearSelection() diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavGraph.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavGraph.kt index 40a144d97e..86d61c2928 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavGraph.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavGraph.kt @@ -23,6 +23,7 @@ import mega.privacy.android.app.presentation.search.navigation.shareFolderAccess import mega.privacy.android.app.presentation.search.navigation.shareFolderDialogNavigation import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.feature.sync.data.mapper.ListToStringWithDelimitersMapper +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper /** @@ -49,6 +50,7 @@ internal fun NavGraphBuilder.searchNavGraph( onBackPressed: () -> Unit, nodeActionsViewModel: NodeActionsViewModel, handleClick: (TypedNode?) -> Unit, + fileTypeIconMapper: FileTypeIconMapper, listToStringWithDelimitersMapper: ListToStringWithDelimitersMapper, ) { composable(searchRoute) { @@ -60,6 +62,7 @@ internal fun NavGraphBuilder.searchNavGraph( searchActivityViewModel = searchActivityViewModel, onBackPressed = onBackPressed, nodeActionHandler = nodeActionHandler, + fileTypeIconMapper = fileTypeIconMapper, handleClick = handleClick ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavHostController.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavHostController.kt index 8524033257..641ba77005 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavHostController.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchNavHostController.kt @@ -13,6 +13,7 @@ import mega.privacy.android.app.presentation.search.model.SearchFilter import mega.privacy.android.core.ui.controls.sheets.MegaBottomSheetLayout import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.feature.sync.data.mapper.ListToStringWithDelimitersMapper +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper /** * Search nav host controller @@ -43,6 +44,7 @@ internal fun SearchNavHostController( bottomSheetNavigator: BottomSheetNavigator, nodeActionsViewModel: NodeActionsViewModel, listToStringWithDelimitersMapper: ListToStringWithDelimitersMapper, + fileTypeIconMapper: FileTypeIconMapper, handleClick: (TypedNode?) -> Unit, modifier: Modifier = Modifier, ) { @@ -65,7 +67,8 @@ internal fun SearchNavHostController( onBackPressed = onBackPressed, nodeActionsViewModel = nodeActionsViewModel, handleClick = handleClick, - listToStringWithDelimitersMapper = listToStringWithDelimitersMapper + listToStringWithDelimitersMapper = listToStringWithDelimitersMapper, + fileTypeIconMapper = fileTypeIconMapper ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt index 173ac0103d..b55bbf72d7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchScreen.kt @@ -28,6 +28,7 @@ import mega.privacy.android.app.presentation.search.navigation.nodeBottomSheetRo import mega.privacy.android.app.presentation.search.navigation.searchFilterBottomSheetRoute import mega.privacy.android.app.presentation.search.view.SearchComposeView import mega.privacy.android.domain.entity.node.TypedNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper /** * Search activity to search Nodes and display @@ -43,6 +44,7 @@ fun SearchScreen( searchActivityViewModel: SearchActivityViewModel, nodeActionHandler: NodeActionHandler, handleClick: (TypedNode?) -> Unit, + fileTypeIconMapper: FileTypeIconMapper, modifier: Modifier = Modifier, ) { val uiState by searchActivityViewModel.state.collectAsStateWithLifecycle() @@ -101,5 +103,6 @@ fun SearchScreen( onBackPressed = onBackPressed, navHostController = navHostController, nodeActionHandler = nodeActionHandler, + fileTypeIconMapper = fileTypeIconMapper, ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index 3e87881409..03db41a810 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -46,6 +46,7 @@ import mega.privacy.android.domain.entity.SortOrder import mega.privacy.android.domain.entity.node.NodeSourceType import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyViewForSearch /** @@ -82,6 +83,7 @@ fun SearchComposeView( navHostController: NavHostController, nodeActionHandler: NodeActionHandler, clearSelection: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper, modifier: Modifier = Modifier, ) { var resetScroll by rememberSaveable { @@ -180,7 +182,8 @@ fun SearchComposeView( onDisputeTakeDownClicked = onDisputeTakeDownClicked, listState = listState, gridState = gridState, - modifier = Modifier.padding(padding) + modifier = Modifier.padding(padding), + fileTypeIconMapper = fileTypeIconMapper ) } else { LegacyMegaEmptyViewForSearch( @@ -242,6 +245,7 @@ private fun PreviewSearchComposeView() { hiltViewModel() ), clearSelection = {}, + fileTypeIconMapper = FileTypeIconMapper() ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/IncomingSharesComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/IncomingSharesComposeFragment.kt index f38aed813f..5febba5bda 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/IncomingSharesComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/IncomingSharesComposeFragment.kt @@ -70,6 +70,7 @@ import mega.privacy.android.domain.entity.node.MoveRequestResult import mega.privacy.android.domain.entity.node.shares.ShareNode import mega.privacy.android.domain.entity.shares.AccessPermission import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import timber.log.Timber import javax.inject.Inject @@ -115,6 +116,12 @@ class IncomingSharesComposeFragment : Fragment() { @Inject lateinit var getOptionsForToolbarMapper: GetOptionsForToolbarMapper + /** + * Mapper to get file type icon + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private val viewModel: IncomingSharesComposeViewModel by activityViewModels() private val sortByHeaderViewModel: SortByHeaderViewModel by viewModels() @@ -196,6 +203,7 @@ class IncomingSharesComposeFragment : Fragment() { onChangeViewTypeClick = viewModel::onChangeViewTypeClicked, onLinkClicked = ::navigateToLink, onToggleAppBarElevation = ::toggleAppBarElevation, + fileTypeIconMapper = fileTypeIconMapper, ) // Snackbar host state should be attached to snackbar host in the scaffold, but we don't have a scaffold yet diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesView.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesView.kt index f4749fe5d9..3927baf5bf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesView.kt @@ -33,6 +33,7 @@ import mega.privacy.android.core.ui.utils.getState import mega.privacy.android.core.ui.utils.sync import mega.privacy.android.domain.entity.node.shares.ShareNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** @@ -60,6 +61,7 @@ fun IncomingSharesView( onSortOrderClick: () -> Unit, onChangeViewTypeClick: () -> Unit, onLinkClicked: (String) -> Unit, + fileTypeIconMapper: FileTypeIconMapper ) { var listStateMap by rememberSaveable(saver = ListGridStateMap.Saver) { @@ -130,6 +132,7 @@ fun IncomingSharesView( showMediaDiscoveryButton = false, onEnterMediaDiscoveryClick = { }, listContentPadding = PaddingValues(top = 18.dp), + fileTypeIconMapper = fileTypeIconMapper ) } else { LegacyMegaEmptyView( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/links/LinksComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/links/LinksComposeFragment.kt index 40114db0fb..bb14eba03b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/links/LinksComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/links/LinksComposeFragment.kt @@ -69,6 +69,7 @@ import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.MoveRequestResult import mega.privacy.android.domain.entity.node.publiclink.PublicLinkNode import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import timber.log.Timber import javax.inject.Inject @@ -100,6 +101,12 @@ class LinksComposeFragment : Fragment() { @Inject lateinit var getThemeMode: GetThemeMode + /** + * Mapper to get file type icon + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + /** * Interface that notifies the attached Activity to execute specific functions */ @@ -159,6 +166,7 @@ class LinksComposeFragment : Fragment() { ), onSortOrderClick = ::showSortByPanel, onToggleAppBarElevation = ::toggleAppBarElevation, + fileTypeIconMapper = fileTypeIconMapper, ) LaunchedEffect(snackbarHostState.currentSnackbarData) { snackbarHostState.currentSnackbarData?.message?.let { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/links/view/LinksView.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/links/view/LinksView.kt index ff37961d1f..93eca51107 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/links/view/LinksView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/links/view/LinksView.kt @@ -24,6 +24,7 @@ import mega.privacy.android.core.ui.utils.ListStateMap import mega.privacy.android.core.ui.utils.getState import mega.privacy.android.core.ui.utils.sync import mega.privacy.android.domain.entity.node.publiclink.PublicLinkNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** @@ -47,6 +48,7 @@ fun LinksView( onMenuClick: (NodeUIItem) -> Unit, sortOrder: String, onSortOrderClick: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper, ) { var listStateMap by rememberSaveable(saver = ListStateMap.Saver) { mutableStateOf(emptyMap()) @@ -99,7 +101,8 @@ fun LinksView( onDisputeTakeDownClicked = { }, showMediaDiscoveryButton = false, onEnterMediaDiscoveryClick = { }, - showPublicLinkCreationTime = uiState.isInRootLevel + showPublicLinkCreationTime = uiState.isInRootLevel, + fileTypeIconMapper = fileTypeIconMapper ) } else { LegacyMegaEmptyView( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/OutgoingSharesComposeFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/OutgoingSharesComposeFragment.kt index 5c9e84cc07..b8cdc410f9 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/OutgoingSharesComposeFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/OutgoingSharesComposeFragment.kt @@ -70,6 +70,7 @@ import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.MoveRequestResult import mega.privacy.android.domain.entity.node.shares.ShareNode import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import timber.log.Timber import javax.inject.Inject @@ -115,6 +116,12 @@ class OutgoingSharesComposeFragment : Fragment() { @Inject lateinit var getOptionsForToolbarMapper: GetOptionsForToolbarMapper + /** + * Mapper to get file type icon + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + private val viewModel: OutgoingSharesComposeViewModel by activityViewModels() private val sortByHeaderViewModel: SortByHeaderViewModel by viewModels() @@ -197,6 +204,7 @@ class OutgoingSharesComposeFragment : Fragment() { onLinkClicked = ::navigateToLink, onVerifyContactDialogDismissed = viewModel::dismissVerifyContactDialog, onToggleAppBarElevation = ::toggleAppBarElevation, + fileTypeIconMapper = fileTypeIconMapper, ) // Snackbar host state should be attached to snackbar host in the scaffold, but we don't have a scaffold yet diff --git a/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesView.kt b/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesView.kt index 862bc1853a..e350aa1996 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesView.kt @@ -26,6 +26,7 @@ import mega.privacy.android.core.ui.utils.getState import mega.privacy.android.core.ui.utils.sync import mega.privacy.android.domain.entity.node.shares.ShareNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView /** @@ -54,6 +55,7 @@ fun OutgoingSharesView( onChangeViewTypeClick: () -> Unit, onLinkClicked: (String) -> Unit, onVerifyContactDialogDismissed: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper ) { var listStateMap by rememberSaveable(saver = ListGridStateMap.Saver) { @@ -103,7 +105,8 @@ fun OutgoingSharesView( onDisputeTakeDownClicked = { }, showMediaDiscoveryButton = false, onEnterMediaDiscoveryClick = { }, - listContentPadding = PaddingValues(top = 18.dp) + listContentPadding = PaddingValues(top = 18.dp), + fileTypeIconMapper = fileTypeIconMapper ) } else { LegacyMegaEmptyView( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSelectedActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSelectedActivity.kt index 6f0f03cc8e..bffaf9d316 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSelectedActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSelectedActivity.kt @@ -19,6 +19,7 @@ import mega.privacy.android.app.presentation.videosection.view.videoselected.Vid import mega.privacy.android.app.utils.Constants.ORDER_CLOUD import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.model.SearchWidgetState import mega.privacy.android.shared.theme.MegaAppTheme import javax.inject.Inject @@ -34,6 +35,12 @@ class VideoSelectedActivity : PasscodeActivity() { @Inject lateinit var getThemeMode: GetThemeMode + /** + * [FileTypeIconMapper] injection + */ + @Inject + lateinit var fileTypeIconMapper: FileTypeIconMapper + internal val viewModel by viewModels() private val sortByHeaderViewModel by viewModels() @@ -84,7 +91,8 @@ class VideoSelectedActivity : PasscodeActivity() { Intent().putStringArrayListExtra(INTENT_KEY_VIDEO_SELECTED, items) ) this.finish() - } + }, + fileTypeIconMapper = fileTypeIconMapper ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedScreen.kt index 7757d82b6a..0feb3205d7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedScreen.kt @@ -9,6 +9,7 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import mega.privacy.android.app.presentation.fileinfo.model.FileInfoMenuAction import mega.privacy.android.app.presentation.videosection.VideoSelectedViewModel +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper @Composable internal fun VideoSelectedScreen( @@ -16,6 +17,7 @@ internal fun VideoSelectedScreen( onVideoSelected: (List) -> Unit, onBackPressed: () -> Unit, onSortOrderClick: () -> Unit, + fileTypeIconMapper: FileTypeIconMapper, ) { val navHostController = rememberNavController() @@ -25,7 +27,8 @@ internal fun VideoSelectedScreen( modifier = Modifier, onBackPressed = onBackPressed, onSortOrderClick = onSortOrderClick, - onVideoSelected = onVideoSelected + onVideoSelected = onVideoSelected, + fileTypeIconMapper = fileTypeIconMapper, ) } @@ -38,9 +41,11 @@ internal fun VideoSelectedNavHost( onSortOrderClick: () -> Unit, onVideoSelected: (List) -> Unit, startDestination: String = videoSelectedRoute, + fileTypeIconMapper: FileTypeIconMapper, ) { val state = viewModel.state.collectAsStateWithLifecycle().value NavHost( + modifier = modifier, navController = navHostController, startDestination = startDestination ) { @@ -67,7 +72,8 @@ internal fun VideoSelectedNavHost( else -> {} } - } + }, + fileTypeIconMapper = fileTypeIconMapper, ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedView.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedView.kt index d3f36bb21c..0f2e54fd22 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/videoselected/VideoSelectedView.kt @@ -48,6 +48,7 @@ import mega.privacy.android.core.ui.utils.sync import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.LegacyMegaEmptyView import mega.privacy.android.shared.theme.MegaAppTheme @@ -64,6 +65,7 @@ internal fun VideoSelectedView( onVideoSelected: (List) -> Unit, onBackPressed: () -> Unit, onMenuActionClick: (FileInfoMenuAction) -> Unit, + fileTypeIconMapper: FileTypeIconMapper, modifier: Modifier = Modifier, ) { var listStateMap by rememberSaveable(saver = ListGridStateMap.Saver) { @@ -191,7 +193,8 @@ internal fun VideoSelectedView( showChangeViewType = showChangeViewType, gridState = currentListState.lazyGridState, showMediaDiscoveryButton = showMediaDiscoveryButton, - isPublicNode = false + isPublicNode = false, + fileTypeIconMapper = fileTypeIconMapper, ) } } @@ -246,7 +249,8 @@ private fun VideoSelectedViewWithProgressBarPreview() { onChangeViewTypeClick = {}, onSortOrderClick = {}, onItemClicked = {}, - onMenuActionClick = {} + onMenuActionClick = {}, + fileTypeIconMapper = FileTypeIconMapper() ) } } @@ -269,7 +273,8 @@ private fun VideoSelectedViewWithEmptyViewPreview() { onChangeViewTypeClick = {}, onSortOrderClick = {}, onItemClicked = {}, - onMenuActionClick = {} + onMenuActionClick = {}, + fileTypeIconMapper = FileTypeIconMapper() ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridView.kt index e4c53c4431..7fba302743 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridView.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.unit.dp import mega.privacy.android.app.presentation.data.NodeUIItem import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.node.thumbnail.ThumbnailRequest +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.lists.HeaderViewItem /** @@ -55,6 +56,7 @@ fun NodeGridView( showChangeViewType: Boolean = true, isPublicNode: Boolean = false, listContentPadding: PaddingValues = PaddingValues(0.dp), + fileTypeIconMapper: FileTypeIconMapper, ) { LazyVerticalGrid( state = gridState, @@ -99,6 +101,7 @@ fun NodeGridView( onItemClicked = onItemClicked, onLongClick = onLongClick, thumbnailData = ThumbnailRequest(nodeUIItems[it].node.id, isPublicNode), + fileTypeIconMapper = fileTypeIconMapper, ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridViewItem.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridViewItem.kt index 7222e5ec86..d3127cee4a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridViewItem.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeGridViewItem.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import androidx.constraintlayout.compose.Visibility -import mega.privacy.android.app.MimeTypeList import mega.privacy.android.app.R import mega.privacy.android.app.presentation.data.NodeUIItem import mega.privacy.android.app.presentation.view.extension.getPainter @@ -50,6 +49,7 @@ import mega.privacy.android.core.ui.theme.transparent import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.TypedNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper /** * Grid view item for file/folder info @@ -69,6 +69,7 @@ internal fun NodeGridViewItem( onItemClicked: (NodeUIItem) -> Unit, onLongClick: (NodeUIItem) -> Unit, thumbnailData: Any?, + fileTypeIconMapper: FileTypeIconMapper, ) { if (nodeUIItem.node is FolderNode) { ConstraintLayout( @@ -171,7 +172,7 @@ internal fun NodeGridViewItem( .testTag(THUMBNAIL_FILE_TEST_TAG), contentDescription = "File", data = thumbnailData, - defaultImage = MimeTypeList.typeForName(nodeUIItem.name).iconResourceId, + defaultImage = fileTypeIconMapper(nodeUIItem.node.type.extension), contentScale = ContentScale.Crop, ) nodeUIItem.fileDuration?.let { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt index e1d65255ac..a2e936066b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt @@ -20,8 +20,8 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import mega.privacy.android.app.MimeTypeList import mega.privacy.android.app.R +import mega.privacy.android.icon.pack.R as IconPackR import mega.privacy.android.app.presentation.data.NodeUIItem import mega.privacy.android.app.presentation.view.extension.folderInfo import mega.privacy.android.app.presentation.view.extension.getIcon @@ -33,11 +33,13 @@ import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.theme.extensions.grey_alpha_012_white_alpha_012 import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.FolderNode +import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.entity.node.TypedFolderNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.node.shares.ShareFolderNode import mega.privacy.android.domain.entity.node.thumbnail.ThumbnailRequest import mega.privacy.android.domain.entity.shares.AccessPermission +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.lists.HeaderViewItem import mega.privacy.android.legacy.core.ui.controls.lists.NodeListViewItem import mega.privacy.android.shared.theme.MegaAppTheme @@ -82,6 +84,7 @@ fun NodeListView( isPublicNode: Boolean = false, showPublicLinkCreationTime: Boolean = false, listContentPadding: PaddingValues = PaddingValues(0.dp), + fileTypeIconMapper: FileTypeIconMapper, ) { LazyColumn( state = listState, @@ -159,10 +162,17 @@ fun NodeListView( folderInfo = nodeEntity .let { node -> node as? FolderNode } ?.folderInfo(), - icon = nodeEntity - .let { node -> node as? TypedFolderNode } - ?.getIcon() - ?: MimeTypeList.typeForName(nodeUIItemList[it].node.name).iconResourceId, + icon = when (nodeEntity) { + is TypedFolderNode -> { + nodeEntity.getIcon() + } + + is TypedFileNode -> { + fileTypeIconMapper(nodeEntity.type.extension) + } + + else -> IconPackR.drawable.ic_generic_medium_solid + }, fileSize = nodeEntity .let { node -> node as? FileNode } ?.let { file -> formatFileSize(file.size, LocalContext.current) }, @@ -232,7 +242,8 @@ private fun NodeListViewPreview( listState = LazyListState(), showMediaDiscoveryButton = false, modifier = Modifier, - showChangeViewType = true + showChangeViewType = true, + fileTypeIconMapper = FileTypeIconMapper() ) } } \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt index f071fd3549..6d15ccaf2e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt @@ -14,6 +14,7 @@ import mega.privacy.android.app.presentation.data.NodeUIItem import mega.privacy.android.app.utils.Constants import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.TypedNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper /** @@ -64,6 +65,7 @@ fun NodesView( isPublicNode: Boolean = false, onEnterMediaDiscoveryClick: () -> Unit = {}, listContentPadding: PaddingValues = PaddingValues(0.dp), + fileTypeIconMapper: FileTypeIconMapper, ) { val takenDownDialog = remember { mutableStateOf(Pair(false, false)) } val orientation = LocalConfiguration.current.orientation @@ -93,6 +95,7 @@ fun NodesView( showMediaDiscoveryButton = showMediaDiscoveryButton, isPublicNode = isPublicNode, showPublicLinkCreationTime = showPublicLinkCreationTime, + fileTypeIconMapper = fileTypeIconMapper ) } else { val newList = rememberNodeListForGrid(nodeUIItems = nodeUIItems, spanCount = span) @@ -118,7 +121,8 @@ fun NodesView( showChangeViewType = showChangeViewType, gridState = gridState, showMediaDiscoveryButton = showMediaDiscoveryButton, - isPublicNode = isPublicNode + isPublicNode = isPublicNode, + fileTypeIconMapper = fileTypeIconMapper ) } if (takenDownDialog.value.first) { diff --git a/app/src/test/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesViewTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesViewTest.kt index 854f89082a..765874fd94 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesViewTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/shares/incoming/ui/IncomingSharesViewTest.kt @@ -1,16 +1,19 @@ package mega.privacy.android.app.presentation.shares.incoming.ui import android.os.Build -import androidx.compose.ui.test.* +import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithTag import androidx.test.ext.junit.runners.AndroidJUnit4 import mega.privacy.android.app.R import mega.privacy.android.app.presentation.shares.incoming.model.IncomingSharesState import mega.privacy.android.app.presentation.view.NODES_EMPTY_VIEW_VISIBLE import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.mock import org.robolectric.annotation.Config @Config(sdk = [Build.VERSION_CODES.Q]) @@ -20,6 +23,8 @@ class IncomingSharesViewTest { @get:Rule val composeTestRule = createComposeRule() + private val fileTypeIconMapper: FileTypeIconMapper = mock() + @Test fun `test that empty state is shown when there are no incoming shares`() { val uiState = IncomingSharesState( @@ -43,6 +48,7 @@ class IncomingSharesViewTest { onSortOrderClick = {}, onChangeViewTypeClick = {}, onLinkClicked = {}, + fileTypeIconMapper = fileTypeIconMapper ) } @@ -77,6 +83,7 @@ class IncomingSharesViewTest { onSortOrderClick = {}, onChangeViewTypeClick = {}, onLinkClicked = {}, + fileTypeIconMapper = fileTypeIconMapper ) } diff --git a/app/src/test/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesViewTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesViewTest.kt index b4c9558173..d5694e2796 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesViewTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/shares/outgoing/ui/OutgoingSharesViewTest.kt @@ -8,9 +8,11 @@ import mega.privacy.android.app.R import mega.privacy.android.app.presentation.shares.outgoing.model.OutgoingSharesState import mega.privacy.android.app.presentation.view.NODES_EMPTY_VIEW_VISIBLE import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.mock import org.robolectric.annotation.Config import test.mega.privacy.android.app.onNodeWithText @@ -20,6 +22,7 @@ class OutgoingSharesViewTest { @get:Rule val composeTestRule = createComposeRule() + private val fileTypeIconMapper: FileTypeIconMapper = mock() @Test fun outgoingSharesViewRendersEmptyView() { @@ -44,7 +47,8 @@ class OutgoingSharesViewTest { onSortOrderClick = {}, onChangeViewTypeClick = {}, onLinkClicked = {}, - onVerifyContactDialogDismissed = {} + onVerifyContactDialogDismissed = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } @@ -76,7 +80,8 @@ class OutgoingSharesViewTest { onSortOrderClick = {}, onChangeViewTypeClick = {}, onLinkClicked = {}, - onVerifyContactDialogDismissed = {} + onVerifyContactDialogDismissed = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.onNodeWithText(R.string.shared_items_contact_not_in_contact_list_dialog_title) diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/folderlink/FolderLinkViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/folderlink/FolderLinkViewTest.kt index fe559f59d2..5b5a4cb365 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/folderlink/FolderLinkViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/folderlink/FolderLinkViewTest.kt @@ -23,6 +23,7 @@ import mega.privacy.android.app.presentation.folderlink.view.Constants.SAVE_BUTT import mega.privacy.android.app.presentation.folderlink.view.Constants.SNACKBAR_TAG import mega.privacy.android.app.presentation.folderlink.view.FolderLinkView import mega.privacy.android.domain.entity.node.TypedFolderNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.lists.MEDIA_DISCOVERY_TAG import org.junit.Rule import org.junit.Test @@ -74,7 +75,8 @@ class FolderLinkViewTest { onEnterMediaDiscoveryClick = { }, adsUiState = adsUiState, onAdClicked = { }, - onAdDismissed = { } + onAdDismissed = { }, + fileTypeIconMapper = FileTypeIconMapper() ) } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragmentTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragmentTest.kt index 2de0db7974..df4be73535 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragmentTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/rubbishbin/RubbishBinComposeFragmentTest.kt @@ -8,14 +8,17 @@ import mega.privacy.android.app.R import mega.privacy.android.app.presentation.rubbishbin.model.RubbishBinState import mega.privacy.android.app.presentation.rubbishbin.view.RubbishBinComposeView import mega.privacy.android.app.presentation.view.NODES_EMPTY_VIEW_VISIBLE +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Mockito.mock @RunWith(AndroidJUnit4::class) class RubbishBinComposeFragmentTest { @get:Rule var composeRule = createComposeRule() + private val fileTypeIconMapper: FileTypeIconMapper = mock() @Test fun `test that NodesView not displayed when list is empty`() { @@ -30,7 +33,8 @@ class RubbishBinComposeFragmentTest { sortOrder = "Name", emptyState = Pair(R.drawable.rubbish_bin_empty, R.string.context_empty_rubbish_bin), onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper ) } composeRule.onNodeWithTag(NODES_EMPTY_VIEW_VISIBLE).assertIsDisplayed() diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoSelectedViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoSelectedViewTest.kt index 82b5ce677a..e7a6c1c4a7 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoSelectedViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoSelectedViewTest.kt @@ -23,6 +23,7 @@ import mega.privacy.android.app.presentation.videosection.view.videoselected.VID import mega.privacy.android.app.presentation.videosection.view.videoselected.VideoSelectedView import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.entity.preference.ViewType +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import org.junit.Before import org.junit.Rule import org.junit.Test @@ -36,6 +37,7 @@ import org.mockito.kotlin.verify class VideoSelectedViewTest { @get:Rule val composeTestRule = createAndroidComposeRule() + private val fileTypeIconMapper: FileTypeIconMapper = mock() @Before fun setUp() { @@ -69,7 +71,8 @@ class VideoSelectedViewTest { onChangeViewTypeClick = onChangeViewTypeClick, onVideoSelected = onVideoSelected, onBackPressed = onBackPressed, - onMenuActionClick = onMenuActionClick + onMenuActionClick = onMenuActionClick, + fileTypeIconMapper = fileTypeIconMapper ) } } diff --git a/app/src/testDebug/java/test/mega/privacy/android/app/presentation/view/NodesViewTest.kt b/app/src/testDebug/java/test/mega/privacy/android/app/presentation/view/NodesViewTest.kt index 242e662092..6adcae2103 100644 --- a/app/src/testDebug/java/test/mega/privacy/android/app/presentation/view/NodesViewTest.kt +++ b/app/src/testDebug/java/test/mega/privacy/android/app/presentation/view/NodesViewTest.kt @@ -11,6 +11,7 @@ import mega.privacy.android.app.presentation.view.NodesView import mega.privacy.android.domain.entity.node.ExportedData import mega.privacy.android.domain.entity.node.TypedFolderNode import mega.privacy.android.domain.entity.node.TypedNode +import mega.privacy.android.feature.sync.ui.mapper.FileTypeIconMapper import mega.privacy.android.legacy.core.ui.controls.lists.EXPORTED_TEST_TAG import mega.privacy.android.legacy.core.ui.controls.lists.FAVORITE_TEST_TAG import mega.privacy.android.legacy.core.ui.controls.lists.INFO_TEXT_TEST_TAG @@ -27,6 +28,7 @@ import org.mockito.kotlin.whenever class NodesViewTest { @get:Rule val composeTestRule = createComposeRule() + private val fileTypeIconMapper: FileTypeIconMapper = mock() private val exportedData = ExportedData("link", 123L) @@ -55,7 +57,8 @@ class NodesViewTest { isListView = false, sortOrder = "Any Name", onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.run { @@ -90,7 +93,8 @@ class NodesViewTest { isListView = false, sortOrder = "Any Name", onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.run { @@ -126,7 +130,8 @@ class NodesViewTest { isListView = false, sortOrder = "Any Name", onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.run { @@ -165,7 +170,8 @@ class NodesViewTest { isListView = false, sortOrder = "Any Name", onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.run { @@ -200,7 +206,8 @@ class NodesViewTest { isListView = true, sortOrder = "Any Name", onLinkClicked = {}, - onDisputeTakeDownClicked = {} + onDisputeTakeDownClicked = {}, + fileTypeIconMapper = fileTypeIconMapper, ) } composeTestRule.run { diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt index a7b3386e40..c69a400e2a 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/DeviceCenterInfoScreen.kt @@ -35,6 +35,7 @@ import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.core.ui.theme.extensions.textColorSecondary import mega.privacy.android.core.ui.theme.tokens.TextColor import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R as IconPackR import mega.privacy.android.feature.devicecenter.ui.model.DeviceCenterInfoUiState import mega.privacy.android.shared.theme.MegaAppTheme @@ -206,7 +207,7 @@ private fun DeviceCenterInfoScreenDevicePreview() { MegaAppTheme(isDark = isSystemInDarkTheme()) { DeviceCenterInfoScreen( uiState = DeviceCenterInfoUiState( - icon = R.drawable.ic_device_pc, + icon = IconPackR.drawable.ic_pc_medium_solid, applySecondaryColorIconTint = true, name = "Device name", numberOfFiles = 6, @@ -224,7 +225,7 @@ private fun DeviceCenterInfoScreenFolderPreview() { MegaAppTheme(isDark = isSystemInDarkTheme()) { DeviceCenterInfoScreen( uiState = DeviceCenterInfoUiState( - icon = R.drawable.ic_device_folder, + icon = IconPackR.drawable.ic_folder_medium_solid, name = "Folder name", numberOfFiles = 6, numberOfFolders = 5, diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/InfoBottomSheetTile.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/InfoBottomSheetTile.kt index 42ee1a9357..c206aec0b2 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/InfoBottomSheetTile.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/InfoBottomSheetTile.kt @@ -10,6 +10,7 @@ import mega.privacy.android.core.ui.controls.dividers.DividerType import mega.privacy.android.core.ui.controls.lists.MenuActionListTile import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R as IconPackR import mega.privacy.android.shared.theme.MegaAppTheme /** @@ -32,7 +33,7 @@ internal fun InfoBottomSheetTile( MenuActionListTile( modifier = Modifier.testTag(BOTTOM_SHEET_TILE_INFO), text = stringResource(R.string.device_center_bottom_sheet_item_info), - icon = painterResource(id = R.drawable.ic_bottom_sheet_info), + icon = painterResource(id = IconPackR.drawable.ic_info_medium_regular_outline), dividerType = dividerType, onActionClicked = onActionClicked, ) diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/RenameDeviceBottomSheetTile.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/RenameDeviceBottomSheetTile.kt index 73e63143dd..0cf526a859 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/RenameDeviceBottomSheetTile.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/bottomsheet/tiles/RenameDeviceBottomSheetTile.kt @@ -9,6 +9,7 @@ import androidx.compose.ui.res.stringResource import mega.privacy.android.core.ui.controls.lists.MenuActionListTile import mega.privacy.android.core.ui.preview.CombinedThemePreviews import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R as IconPackR import mega.privacy.android.shared.theme.MegaAppTheme /** @@ -30,7 +31,7 @@ internal fun RenameDeviceBottomSheetTile( modifier = Modifier.testTag(BOTTOM_SHEET_TILE_RENAME_DEVICE), dividerType = null, text = stringResource(R.string.device_center_bottom_sheet_item_rename), - icon = painterResource(id = R.drawable.ic_bottom_sheet_rename), + icon = painterResource(id = IconPackR.drawable.ic_edit_medium_regular_outline), onActionClicked = onActionClicked, ) } diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt index 007a28a448..c0a2e071e4 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/DeviceCenterInfoUiState.kt @@ -1,7 +1,7 @@ package mega.privacy.android.feature.devicecenter.ui.model import androidx.annotation.DrawableRes -import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R /** * Data class representing the state of the Device Center Info View @@ -15,7 +15,7 @@ import mega.privacy.android.feature.devicecenter.R * @property creationTime The creation time */ data class DeviceCenterInfoUiState( - @DrawableRes val icon: Int = R.drawable.ic_device_folder, + @DrawableRes val icon: Int = R.drawable.ic_folder_medium_solid, @Deprecated( "Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon." ) val applySecondaryColorIconTint: Boolean = false, diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceIconType.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceIconType.kt index 8891a42230..bec895915b 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceIconType.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/DeviceIconType.kt @@ -1,6 +1,6 @@ package mega.privacy.android.feature.devicecenter.ui.model.icon -import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R /** * A sealed UI interface that represents different Device Icons @@ -11,7 +11,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents an Android Device Icon */ data object Android : DeviceIconType { - override val iconRes = R.drawable.ic_device_android + override val iconRes = R.drawable.ic_android_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -21,7 +21,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents an iOS Device Icon */ data object IOS : DeviceIconType { - override val iconRes = R.drawable.ic_device_ios + override val iconRes = R.drawable.ic_ios_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -31,7 +31,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents a Linux Device Icon */ data object Linux : DeviceIconType { - override val iconRes = R.drawable.ic_device_pc_linux + override val iconRes = R.drawable.ic_pc_linux_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -41,7 +41,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents a Mac Device Icon */ data object Mac : DeviceIconType { - override val iconRes = R.drawable.ic_device_pc_mac + override val iconRes = R.drawable.ic_pc_mac_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -51,7 +51,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents a Mobile Device Icon */ data object Mobile : DeviceIconType { - override val iconRes = R.drawable.ic_device_mobile + override val iconRes = R.drawable.ic_mobile_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -61,7 +61,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents a PC Device Icon */ data object PC : DeviceIconType { - override val iconRes = R.drawable.ic_device_pc + override val iconRes = R.drawable.ic_pc_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true @@ -71,7 +71,7 @@ sealed interface DeviceIconType : DeviceCenterUINodeIcon { * Represents a Windows Device Icon */ data object Windows : DeviceIconType { - override val iconRes = R.drawable.ic_device_pc_windows + override val iconRes = R.drawable.ic_pc_windows_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = true diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/FolderIconType.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/FolderIconType.kt index 948a5306bd..1c29073ea9 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/FolderIconType.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/icon/FolderIconType.kt @@ -1,6 +1,6 @@ package mega.privacy.android.feature.devicecenter.ui.model.icon -import mega.privacy.android.feature.devicecenter.R +import mega.privacy.android.icon.pack.R /** * A sealed UI interface that represents different Folder Icons @@ -11,7 +11,7 @@ sealed interface FolderIconType : DeviceCenterUINodeIcon { * Represents a Backup Folder Icon */ data object Backup : FolderIconType { - override val iconRes = R.drawable.ic_device_folder_backup + override val iconRes = R.drawable.ic_folder_backup_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = false @@ -21,7 +21,7 @@ sealed interface FolderIconType : DeviceCenterUINodeIcon { * Represents a Camera Uploads Folder Icon */ data object CameraUploads : FolderIconType { - override val iconRes = R.drawable.ic_device_folder_camera_uploads + override val iconRes = R.drawable.ic_folder_camera_uploads_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = false @@ -31,7 +31,7 @@ sealed interface FolderIconType : DeviceCenterUINodeIcon { * Represents a plain Folder Icon */ data object Folder : FolderIconType { - override val iconRes = R.drawable.ic_device_folder + override val iconRes = R.drawable.ic_folder_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = false @@ -41,7 +41,7 @@ sealed interface FolderIconType : DeviceCenterUINodeIcon { * Represents a Sync Folder Icon */ data object Sync : FolderIconType { - override val iconRes = R.drawable.ic_device_folder_sync + override val iconRes = R.drawable.ic_folder_sync_medium_solid @Deprecated("Temporary used in order to fix icon color until we change to the new icon set. Will be removed soon.") override val applySecondaryColorTint = false diff --git a/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_info.xml b/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_info.xml deleted file mode 100644 index d8d1a6e6c9..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_info.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_rename.xml b/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_rename.xml deleted file mode 100644 index fe372eaf62..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_bottom_sheet_rename.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_android.xml b/feature/devicecenter/src/main/res/drawable/ic_device_android.xml deleted file mode 100644 index e3c7627125..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_android.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_folder.xml b/feature/devicecenter/src/main/res/drawable/ic_device_folder.xml deleted file mode 100644 index 2c32df5319..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_folder.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_folder_backup.xml b/feature/devicecenter/src/main/res/drawable/ic_device_folder_backup.xml deleted file mode 100644 index dd25650e5f..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_folder_backup.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_folder_camera_uploads.xml b/feature/devicecenter/src/main/res/drawable/ic_device_folder_camera_uploads.xml deleted file mode 100644 index 558794a039..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_folder_camera_uploads.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_folder_sync.xml b/feature/devicecenter/src/main/res/drawable/ic_device_folder_sync.xml deleted file mode 100644 index 17cdd8a532..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_folder_sync.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_ios.xml b/feature/devicecenter/src/main/res/drawable/ic_device_ios.xml deleted file mode 100644 index 2e096c30fd..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_ios.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_pc.xml b/feature/devicecenter/src/main/res/drawable/ic_device_pc.xml deleted file mode 100644 index a2c14bf6a1..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_pc.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_pc_linux.xml b/feature/devicecenter/src/main/res/drawable/ic_device_pc_linux.xml deleted file mode 100644 index 34211b9812..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_pc_linux.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_pc_mac.xml b/feature/devicecenter/src/main/res/drawable/ic_device_pc_mac.xml deleted file mode 100644 index c35222dcc7..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_pc_mac.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_pc_windows.xml b/feature/devicecenter/src/main/res/drawable/ic_device_pc_windows.xml deleted file mode 100644 index 346ea35562..0000000000 --- a/feature/devicecenter/src/main/res/drawable/ic_device_pc_windows.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - diff --git a/icon-pack/src/main/res/drawable/ic_android_medium_solid.xml b/icon-pack/src/main/res/drawable/ic_android_medium_solid.xml new file mode 100644 index 0000000000..4dff345425 --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_android_medium_solid.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icon-pack/src/main/res/drawable/ic_ios_medium_solid.xml b/icon-pack/src/main/res/drawable/ic_ios_medium_solid.xml new file mode 100644 index 0000000000..1ffe8829e7 --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_ios_medium_solid.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/feature/devicecenter/src/main/res/drawable/ic_device_mobile.xml b/icon-pack/src/main/res/drawable/ic_mobile_medium_solid.xml similarity index 63% rename from feature/devicecenter/src/main/res/drawable/ic_device_mobile.xml rename to icon-pack/src/main/res/drawable/ic_mobile_medium_solid.xml index bfa8020ce5..80983aef3f 100644 --- a/feature/devicecenter/src/main/res/drawable/ic_device_mobile.xml +++ b/icon-pack/src/main/res/drawable/ic_mobile_medium_solid.xml @@ -5,7 +5,7 @@ android:viewportWidth="48" android:viewportHeight="48"> Date: Mon, 8 Apr 2024 12:52:00 +0200 Subject: [PATCH 083/261] Hotfix: T15745377 Open a chat link - Edited indicator --- .../domain/usecase/chat/message/CreateMetaMessageUseCase.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/CreateMetaMessageUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/CreateMetaMessageUseCase.kt index b000a22460..6d79a1c477 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/CreateMetaMessageUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/chat/message/CreateMetaMessageUseCase.kt @@ -27,7 +27,10 @@ class CreateMetaMessageUseCase @Inject constructor() : CreateTypedMessageUseCase shouldShowAvatar = shouldShowAvatar, reactions = reactions, content = content.orEmpty(), - isEdited = isEdited, + // Rich preview messages are always edited because are sent as normal messages, + // but then edited after getting the preview info from API. + // So we cannot manage any real edited status. + isEdited = false, status = status, rowId = rowId, ) From 0465ba3f337c1a91dcc1c66192823d9845e088e0 Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Mon, 8 Apr 2024 23:10:55 +1200 Subject: [PATCH 084/261] SAO-53 (t15745336) update device file and folder icons Fix notification issue --- .../android/app/listeners/GlobalListener.kt | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/listeners/GlobalListener.kt b/app/src/main/java/mega/privacy/android/app/listeners/GlobalListener.kt index dd13eaadf7..274f24134b 100644 --- a/app/src/main/java/mega/privacy/android/app/listeners/GlobalListener.kt +++ b/app/src/main/java/mega/privacy/android/app/listeners/GlobalListener.kt @@ -6,9 +6,10 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent -import android.graphics.drawable.BitmapDrawable -import android.graphics.drawable.Drawable +import android.graphics.Bitmap +import android.graphics.Canvas import android.media.RingtoneManager +import androidx.annotation.DrawableRes import androidx.core.app.NotificationCompat import androidx.core.content.ContextCompat import androidx.core.text.HtmlCompat @@ -394,8 +395,9 @@ class GlobalListener @Inject constructor( ) channel.setShowBadge(true) notificationManager.createNotificationChannel(channel) - val d: Drawable = appContext.resources - .getDrawable(IconPackR.drawable.ic_folder_incoming_medium_solid, appContext.theme) + val icon: Bitmap? = getBitmapFromVectorDrawable( + IconPackR.drawable.ic_folder_incoming_medium_solid + ) val notificationBuilder: NotificationCompat.Builder = NotificationCompat.Builder(appContext, notificationChannelId) .setSmallIcon(IconPackR.drawable.ic_stat_notify) @@ -406,7 +408,7 @@ class GlobalListener @Inject constructor( .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) .setContentIntent(pendingIntent) .setColor(ContextCompat.getColor(appContext, R.color.red_600_red_300)) - .setLargeIcon((d as BitmapDrawable).bitmap) + .setLargeIcon(icon) .setPriority(NotificationManager.IMPORTANCE_HIGH) notificationManager.notify( Constants.NOTIFICATION_PUSH_CLOUD_DRIVE, @@ -417,6 +419,20 @@ class GlobalListener @Inject constructor( } } + private fun getBitmapFromVectorDrawable( + @DrawableRes drawableId: Int, + ): Bitmap? { + val drawable = ContextCompat.getDrawable(appContext, drawableId) ?: return null + val bitmap = Bitmap.createBitmap( + drawable.intrinsicWidth, + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + return bitmap + } + /** * A force reload account has been received. A fetch nodes is in progress and the * Login screen should be shown. From 421903504a83d514f4fd920cc716d3f4af04064e Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 8 Apr 2024 21:00:02 +0700 Subject: [PATCH 085/261] Pre-release 12.0 (cherry picked from commit 0ad8999b51b56db6b40df4e4ef430d9463ce3348) --- app/src/main/res/values-ar/strings.xml | 12 +++-- app/src/main/res/values-de/strings.xml | 12 +++-- app/src/main/res/values-es/strings.xml | 18 +++++--- app/src/main/res/values-fr/strings.xml | 22 ++++++---- app/src/main/res/values-in/strings.xml | 12 +++-- app/src/main/res/values-it/strings.xml | 12 +++-- app/src/main/res/values-ja/strings.xml | 12 +++-- app/src/main/res/values-ko/strings.xml | 14 ++++-- app/src/main/res/values-nl/strings.xml | 12 +++-- app/src/main/res/values-pl/strings.xml | 12 +++-- app/src/main/res/values-pt/strings.xml | 12 +++-- app/src/main/res/values-ro/strings.xml | 12 +++-- app/src/main/res/values-ru/strings.xml | 20 ++++++--- app/src/main/res/values-th/strings.xml | 12 +++-- app/src/main/res/values-vi/strings.xml | 16 ++++--- app/src/main/res/values-zh-rCN/strings.xml | 12 +++-- app/src/main/res/values-zh-rTW/strings.xml | 12 +++-- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../res/values-ar/strings_sync_feature.xml | 2 +- .../res/values-de/strings_sync_feature.xml | 2 +- .../res/values-es/strings_sync_feature.xml | 2 +- .../res/values-fr/strings_sync_feature.xml | 2 +- .../res/values-in/strings_sync_feature.xml | 2 +- .../res/values-it/strings_sync_feature.xml | 2 +- .../res/values-ja/strings_sync_feature.xml | 2 +- .../res/values-ko/strings_sync_feature.xml | 2 +- .../res/values-nl/strings_sync_feature.xml | 2 +- .../res/values-pl/strings_sync_feature.xml | 2 +- .../res/values-pt/strings_sync_feature.xml | 2 +- .../res/values-ro/strings_sync_feature.xml | 2 +- .../res/values-ru/strings_sync_feature.xml | 2 +- .../res/values-th/strings_sync_feature.xml | 2 +- .../res/values-vi/strings_sync_feature.xml | 2 +- .../values-zh-rCN/strings_sync_feature.xml | 2 +- .../values-zh-rTW/strings_sync_feature.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 14 +++--- .../src/main/res/values-de/strings_shared.xml | 14 +++--- .../src/main/res/values-es/strings_shared.xml | 18 ++++---- .../src/main/res/values-fr/strings_shared.xml | 22 +++++----- .../src/main/res/values-in/strings_shared.xml | 20 +++++---- .../src/main/res/values-it/strings_shared.xml | 16 ++++--- .../src/main/res/values-ja/strings_shared.xml | 14 +++--- .../src/main/res/values-ko/strings_shared.xml | 14 +++--- .../src/main/res/values-nl/strings_shared.xml | 16 ++++--- .../src/main/res/values-pl/strings_shared.xml | 16 ++++--- .../src/main/res/values-pt/strings_shared.xml | 8 ++-- .../src/main/res/values-ro/strings_shared.xml | 16 ++++--- .../src/main/res/values-ru/strings_shared.xml | 28 ++++++------ .../src/main/res/values-th/strings_shared.xml | 16 ++++--- .../src/main/res/values-vi/strings_shared.xml | 22 +++++----- .../main/res/values-zh-rCN/strings_shared.xml | 16 ++++--- .../main/res/values-zh-rTW/strings_shared.xml | 44 ++++++++++--------- 55 files changed, 363 insertions(+), 227 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 67e7ce8e4c..dc3efce6e7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6157,9 +6157,9 @@ تفاصيل الاشتراك يتم تجديد الاشتراكات تلقائيًا لفترات اشتراك متتالية من نفس المدة وبنفس سعر الفترة الأولية المختارة. يمكنك إيقاف التجديد التلقائي لاشتراك ميغا برو MEGA Pro الخاص بك في موعد لا يتجاوز 24 ساعة قبل استحقاق دفعة الاشتراك التالية عبر الاشتراكات في [A]غوغل بلاي Google Play[/A]. - + السماح بالوصول إلى معرض الصور الخاص بك - + منح اذن الوصول التحديث مطلوب @@ -6306,7 +6306,7 @@ Upgrade to Pro to get unlimited calls - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + وصلت مكالمتك إلى حد 60 دقيقة وانتهت. يتمتع مستخدمو برو Pro بمدة مكالمات غير محدودة ويمكنهم دعوة ما يصل إلى 1000 مشارك. رق حسابك الآن @@ -6343,4 +6343,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a453649e4b..f22f32daff 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5221,9 +5221,9 @@ Abonnementdetails Abonnements werden automatisch für den ursprünglich gewählten Abonnementzeitraum und zum gleichen Preis verlängert. Sie können die automatische Verlängerung Ihres MEGA-Pro-Abonnements bis spätestens 24 Stunden vor Fälligkeit Ihrer nächsten Abonnementzahlung in [A]Google Play[/A] unter Abonnements deaktivieren. - + Gewähren Sie Zugriff auf Ihre Galerie - + Zugriff gewähren Update erforderlich @@ -5358,7 +5358,7 @@ Auf Pro upgraden, um unbegrenzte Anrufe zu führen - Ihr Anruf hat das Limit von 60 Minuten erreicht und wurde beendet. Pro-Benutzer können unbegrenzt Anrufe führen und bis zu 1000 Teilnehmer einladen. + Ihr Anruf hat das Limit von 60 Minuten erreicht und wurde beendet. Pro-Benutzer können beliebig lange Anrufe führen und bis zu 1000 Teilnehmer einladen. Jetzt upgraden @@ -5395,4 +5395,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Foto + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index f7804f10ad..8ecbf68461 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5214,7 +5214,7 @@ La aplicación se ha actualizado - Relaunch the app + Reiniciar app Permitir el acceso a archivos de audio @@ -5455,9 +5455,9 @@ Información sobre la suscripción La suscripción se renueva automáticamente con la misma duración y precio elegidos inicialmente. Puedes desactivar la renovación automática de la suscripción a MEGA Pro en la página de suscripciones de [A]Google Play[/A] hasta 24 horas antes de la renovación programada. - + Permitir acceso a la galería - + Conceder acceso Actualización requerida @@ -5596,7 +5596,7 @@ Amplía a Pro para recibir llamadas ilimitadas - La llamada ha alcanzado el límite de 60 minutos y ha finalizado. Los usuarios Pro tienen llamadas ilimitadas y hasta 1000 participantes. + La llamada ha alcanzado el límite de 60 minutos y ha finalizado. Los usuarios Pro tienen llamadas de duración ilimitada y pueden invitar hasta 1000 participantes. Ampliar cuenta @@ -5630,7 +5630,13 @@ Reporta tu problema - Show hidden items + Mostrar elementos ocultos - All hidden items will be visible, but blurred to indicate their “hidden” status + Todos los elementos ocultos estarán visibles, pero desenfocados para indicar su estado “oculto” + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$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 925d9536be..d448c0ae00 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5214,7 +5214,7 @@ L’appli a été mise à jour - Relaunch the app + Relancer l’appli Autoriser l’accès aux fichiers son @@ -5455,9 +5455,9 @@ Détails de l’abonnement Les abonnements sont renouvelés automatiquement pour des périodes d’abonnement successives de même durée et au même prix que la période initiale choisie. Vous pouvez désactiver le renouvellement automatique de votre abonnement MEGA Pro au plus tard 24 heures avant la date de paiement de votre prochain abonnement dans Abonnements de [A]Google Play[/A]. - + Autoriser l’accès à votre galerie - + Accorder l’accès Une mise à jour est nécessaire @@ -5552,7 +5552,7 @@ Expire le %1$s à %2$s - Seuls 100 participants peuvent participer à l’appel. Tout participant supplémentaire ne pourra qu’envoyer et recevoir des messages. La personne organise l’appel peut souscrire un abonnement Pro pour lever ces restrictions. + Seuls 100 participants peuvent participer à l’appel. Tout participant supplémentaire ne pourra qu’envoyer et recevoir des messages. La personne qui organise l’appel peut souscrire un abonnement Pro pour lever ces restrictions. Seuls 100 participants peuvent participer à l’appel. Tout participant supplémentaire ne pourra qu’envoyer et lire les conversations. Demandez à la personne qui l’organise de lever cette restriction. @@ -5564,7 +5564,7 @@ Originale - Si vous souhaitez enregistrer un message vocal, autorisez MEGA à accéder à votre microphone. + Vous avez refuser à MEGA l’accès à votre microphone. Si vous souhaitez enregistrer un message vocal, accordez à MEGA l’accès à votre microphone. Impossible de vous joindre @@ -5596,7 +5596,7 @@ Passer à la version Pro pour bénéficier d’appels illimités - Votre appel a atteint la limite de 60 minutes et s’est terminé. Les utilisateurs Pro bénéficient d’une durée d’appel illimitée, jusqu’à 1 000 participants. + Votre appel a atteint la limite de 60 minutes et s’est terminé. Les utilisateurs Pro bénéficient d’une durée d’appel illimitée et peuvent inviter jusqu’à 1 000 participants. Surclasser le compte maintenant @@ -5630,7 +5630,13 @@ Signalez votre problème - Show hidden items + Afficher les éléments cachés - All hidden items will be visible, but blurred to indicate their “hidden” status + Tous les éléments cachés seront visibles, mais flous pour indiquer leur état « caché » + + Photo + Flash mode on + Flash mode off + Flash mode auto + Envoyer vers %1$s \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index ebe0a01956..9ea93d6788 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4987,9 +4987,9 @@ Detail langganan Langganan diperpanjang secara otomatis untuk periode berlangganan berturut-turut dengan durasi yang sama dan dengan harga yang sama dengan periode awal yang dipilih. Anda dapat mematikan perpanjangan otomatis langganan MEGA   Pro anda selambat-lambatnya 24 jam sebelum pembayaran langganan berikutnya jatuh tempo melalui Langganan di [A]Google Play[/A]. - + Izinkan akses ke galeri anda - + Berikan akses Diperlukan pembaruan @@ -5120,7 +5120,7 @@ Tingkatkan ke Pro untuk mendapatkan panggilan tak terbatas - Panggilan anda mencapai batas 60 menit dan telah berakhir. Pengguna pro memiliki panggilan tak terbatas dan hingga 1000 peserta. + Panggilan anda mencapai batas 60 menit dan telah berakhir. Pengguna Pro memiliki durasi panggilan tak terbatas dan dapat mengundang hingga 1000 peserta. Tingkatkan sekarang @@ -5157,4 +5157,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3218b05db0..af8cfb8ede 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5455,9 +5455,9 @@ Dettagli dell\’abbonamento Gli abbonamenti vengono rinnovati automaticamente per periodi di abbonamento successivi della stessa durata e allo stesso prezzo del periodo iniziale scelto. Puoi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro entro 24 ore prima della scadenza del prossimo pagamento dell\’abbonamento tramite Abbonamenti nel [A]Google Play[/A]. - + Permetti l\’accesso alla tua galleria - + Garantisci l\’accesso Aggiornamento necessario @@ -5596,7 +5596,7 @@ Effettua l\’upgrade a Pro per avere chiamate illimitate - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + La tua chiamata ha raggiunto il limite di 60 minuti ed è terminata. Gli utenti Pro hanno una durata illimitata delle chiamate e possono invitare fino a 1000 partecipanti. Effettua l\’upgrade ora @@ -5633,4 +5633,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 95161b7fa0..76b5ff1280 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4987,9 +4987,9 @@ サブスクリプションの詳細 サブスクリプションは、最初に選択した期間と同じ期間および同じ価格で、連続するサブスクリプション期間に対して自動的に更新されます。次のサブスクリプションのお支払い期日の24時間前までに、MEGA Proサブスクリプションの自動更新をオフに切り替えることができます。これは、[A]Google Play[/A]の「サブスクリプション」から実行できます。 - + ギャラリーへのアクセスを許可する - + アクセスを許可 アップデートが必要です @@ -5120,7 +5120,7 @@ Proにアップグレードしていただくと無制限に通話できるようになります - 通話は60分の制限に達したため終了しました。Proユーザー様は、無制限の通話と最大1000人の参加者が利用できます。 + 通話時間が60分の制限に達したため終了しました。Proユーザー様は通話時間が無制限で、最大1000人の参加者を招待できます。 今すぐアップグレード @@ -5157,4 +5157,10 @@ 非表示項目を表示する 非表示の項目はすべて表示されますが、「非表示」ステータスを示すためにぼかされます + + 写真 + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 1f8a213311..69356008e1 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4987,9 +4987,9 @@ 구독 세부정보 구독은 처음 선택한 기간과 같은 기간 그리고 같은 가격으로 연속적으로 자동 갱신 됩니다. MEGA Pro 구독 자동 갱신을 [A]Google Play[/A]의 구독을 통해 다음 구독의 결제 24시간 전에 취소할 수 있습니다. - + 갤러리에 접근 허용 - + 접근 허가 업데이트가 필요합니다 @@ -5120,7 +5120,7 @@ 무제한 통화를 하려면 Pro로 업그레이드 하세요 - 당신의 통화가 60분 제한에 도달하여 종료되었습니다. Pro 이용자들은 무제한 통화와 최대 1,000명까지 참여할 수 있습니다. + 당신의 통화가 60분 제한에 도달하여 종료되었습니다. Pro 이용자들은 무제한 통화 시간과 최대 1000명의 참여자를 초대할 수 있습니다. 지금 업그레이드 @@ -5154,7 +5154,13 @@ 문제 신고 - Show hidden items + 숨겨진 항목 보기 All hidden items will be visible, but blurred to indicate their “hidden” status + + 사진 + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5719cdd407..85373f451d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5221,9 +5221,9 @@ Abonnement details Abonnementen worden automatisch verlengd voor opeenvolgende abonnementsperioden van dezelfde duur en tegen dezelfde prijs als de gekozen initiële periode. U kunt de automatische verlenging van uw MEGA   Pro-abonnement uiterlijk 24 uur voordat uw volgende abonnementsbetaling verschuldigd is, uitschakelen via Abonnementen in [A]Google Play[/A]. - + Geef toegang tot uw gallerij - + Toegang verlenen Update vereist @@ -5358,7 +5358,7 @@ Upgrade naar Pro om ongelimiteerd te kunnen bellen - Uw gesprek heeft de limiet van 60 minuten bereikt en is beëindigd. Pro-gebruikers kunnen ongelimiteerd bellen en tot 1000 deelnemers. + Uw gesprek heeft de limiet van 60 minuten bereikt en is beëindigd. Pro-gebruikers hebben een onbeperkte gespreksduur en kunnen tot 1000 deelnemers uitnodigen. Nu upgraden @@ -5395,4 +5395,10 @@ Verborgen items weergeven Alle verborgen items zijn zichtbaar, maar wazig om hun “verborgen” status aan te geven + + Foto + Flash mode on + Flash mode off + Flash mode auto + Verzenden naar %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 3e0c2eb7ff..c8f5047da3 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5689,9 +5689,9 @@ Szczegóły subskrypcji Subskrypcje są odnawiane automatycznie na kolejne okresy subskrypcji o tym samym czasie trwania i w tej samej cenie, co wybrany okres początkowy. Użytkownik może wyłączyć automatyczne odnawianie subskrypcji MEGA Pro nie później niż 24 godziny przed terminem płatności kolejnej subskrypcji za pośrednictwem Subskrypcji w [A]Google Play[/A]. - + Zezwalaj na dostęp do swojej galerii - + Przyznaj dostęp Wymagana aktualizacja @@ -5834,7 +5834,7 @@ Uaktualnij do Pro, aby otrzymywać nieograniczoną liczbę połączeń - Twoje połączenie osiągnęło limit 60 minut i zakończyło się. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000 uczestników. + Twoje połączenie osiągnęło limit 60 minut i zakończyło się. Użytkownicy Pro mają nieograniczony czas trwania połączeń i mogą zaprosić do 1000 uczestników. Zmień teraz @@ -5871,4 +5871,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Zdjęcie + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 166bfbe9b6..448e1dcb6d 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5455,9 +5455,9 @@ Informações da assinatura As assinaturas serão renovadas automaticamente por períodos sucessivos com a mesma duração e pelo mesmo preço do período inicial. Você pode desativar a renovação automática da sua assinatura Pro do MEGA até 24 horas antes do vencimento do próximo pagamento nas Assinaturas da [A]Google Play[/A]. - + Permitir o acesso à sua galeria - + Permitir acesso Atualização necessária @@ -5596,7 +5596,7 @@ Faça o upgrade a um plano Pro para ter chamadas ilimitadas - A sua chamada atingiu o limite de 60 minutos e foi finalizada. Os usuários Pro podem fazer chamadas com qualquer duração e convidar até 1000 participantes. + A sua chamada atingiu o limite de 60 minutos e foi finalizada. Os usuários Pro podem fazer chamadas com qualquer duração e convidar até 1000 participantes. Upgrade @@ -5633,4 +5633,10 @@ Mostrar itens ocultos Todos os itens ocultos ficarão visíveis, mas desfocados para indicar o seu status “oculto” + + Foto + Flash mode on + Flash mode off + Flash mode auto + Enviar a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index f71f8056bb..a193878902 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5455,9 +5455,9 @@ Detaliile abonamentului Abonamentele sunt reînnoite automat pentru perioade succesive de abonament cu aceeași durată și la același preț ca perioada inițială aleasă. Puteți dezactiva reînnoirea automată a abonamentului MEGA Pro cu cel mult 24 de ore înainte de scadența următoarei plăți a abonamentului prin Abonamente în [A]Google Play[/A]. - + Permiteți accesul la galeria dvs. - + Acordă acces Actualizarea necesară @@ -5595,7 +5595,7 @@ Upgradați la Pro pentru a primi apeluri nelimitate - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + Apelul dvs. a atins limita de 60 de minute și s-a încheiat. Utilizatorii Pro au o durată nelimitată a apelului și pot invita până la 1000 de participanți. Upgradați acum @@ -5632,4 +5632,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 467247d64d..be909d59e6 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5689,9 +5689,9 @@ Подробная информация о подписке Подписки продлеваются автоматически на последующие периоды той же продолжительности и по той же цене, что и первоначально выбранный период. Вы можете отключить автоматическое продление подписки MEGA Pro не позднее чем за 24 часа до следующего платежа за подписку на странице «Подписки» в [A]Google Play[/A]. - + Разрешите доступ к галерее - + Открыть доступ Требуется обновление @@ -5834,7 +5834,7 @@ Перейдите на Pro для безлимитных звонков - Ваш звонок продлился 60 минут и был завершён. У пользователей Pro звонки неограничены по времени и могут включать до 1000 участников. + Ваш звонок продлился 60 минут и был завершён. Пользователи Pro могут организовывать звонки без ограничений по времени и приглашать до 1000 участников. Улучшить @@ -5864,11 +5864,17 @@ Старше - Trouble logging in? + Не удаётся войти в систему? - Report your issue + Сообщите о проблеме - Show hidden items + Показывать скрытые элементы - All hidden items will be visible, but blurred to indicate their “hidden” status + Все скрытые элементы будут видны, но размыты, чтобы указать на их «скрытый» статус + + Фото + Flash mode on + Flash mode off + Flash mode auto + Отправить в «%1$s» \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index aa628f00be..1451faf735 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4987,9 +4987,9 @@ รายละเอียดการสมัครใช้งาน เมื่อสมัครใช้งานแล้ว ระบบจะต่ออายุสมาชิกให้อัตโนมัติตามระยะเวลาและราคาเดิมที่เลือกไว้ คุณสามารถยกเลิกการต่ออายุสมาชิก MEGA Pro อัตโนมัติได้ไม่เกิน 24 ชั่วโมงก่อนวันครบกำหนดชำระค่าสมาชิกครั้งต่อไปผ่านระบบสมาชิกใน [A]Google Play[/A] - + อนุญาตให้เข้าถึงแกลเลอรี่ของคุณ - + ให้สิทธิ์เข้าถึง จำเป็นต้องได้รับการอัปเดต @@ -5120,7 +5120,7 @@ อัปเกรดเป็นแผน Pro เพื่อโทรได้ไม่อั้น - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + การโทรของคุณใช้เวลาครบ 60 นาทีตามข้อจำกัดของระบบแล้ว ผู้ใช้บัญชี Pro นั้นสามารถโทรได้นานไม่จำกัด และสามารถเชิญผู้เข้าร่วมได้มากถึง 1000 คน อัปเกรดตอนนี้ @@ -5157,4 +5157,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 73c4a524b9..528ec41fc1 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4760,7 +4760,7 @@ Ứng dụng đã được cập nhật - Relaunch the app + Khởi chạy lại ứng dụng Cho phép truy cập vào các tệp tin âm thanh @@ -4987,9 +4987,9 @@ Chi tiết gói đăng ký Các gói đăng ký được tự động gia hạn cho khoảng thời gian đăng ký kế tiếp có cùng thời lượng và ở cùng mức giá như khoảng thời gian ban đầu đã chọn. Bạn có thể tắt tự động gia hạn gói đăng ký MEGA Pro của mình không được ít hơn 24 giờ trước khi đến kỳ hạn thanh toán cho gói đăng ký tiếp theo thông qua trang Gói thuê bao trong [A]Google Play[/A]. - + Cho phép truy cập vào thư viện hình ảnh của bạn - + Cấp quyền Cần phải cập nhật @@ -5154,7 +5154,13 @@ Báo cáo vấn đề của bạn - Show hidden items + Hiện các mục đã ẩn - All hidden items will be visible, but blurred to indicate their “hidden” status + Tất cả các mục ẩn sẽ hiển thị, nhưng bị làm mờ để cho biết trạng thái là bị “ẩn” + + Ảnh + Flash mode on + Flash mode off + Flash mode auto + Gửi đến %1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5c63bf8f0b..53ab5473fb 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4987,9 +4987,9 @@ 订阅详情 订阅将自动续订,续订周期与初始选择的周期相同,并且以相同的价格进行续订。您可以在下一次订阅付款到期前24小时以内,通过[A]Google Play[/A]订阅界面关闭MEGA Pro订阅的自动续订功能。 - + 允许访问您的图库 - + 授予权限 需要更新 @@ -5121,7 +5121,7 @@ Upgrade to Pro to get unlimited calls - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + 您的通话已达到60分钟限制并已结束。Pro会员用户具有无限通话时长,并且可以邀请多达1000名参与者。 立即升级 @@ -5158,4 +5158,10 @@ Show hidden items All hidden items will be visible, but blurred to indicate their “hidden” status + + Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 140146cc9e..06de33448c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4987,9 +4987,9 @@ 訂閱詳情 訂閱會自動續訂,續訂的訂閱期間與初始選擇的周期相同,價格也相同。您可以在下次訂閱付款到期前24小時內,透過[A]Google Play[/A]中的訂閱關閉MEGA Pro訂閱的自動續訂功能。 - + 允許存取您的相簿 - + 授予權限 需要更新 @@ -5120,7 +5120,7 @@ 升級到Pro方案可獲得無限的通話 - 您的通話已達到60分鐘限制並已結束。Pro使用者有無限的通話,而且最多可容納1000位與會者。 + 您的通話時間已達60分鐘的限制並已結束。Pro使用者的通話時間不受限制,最多可邀請1000位與會者。 立即升級 @@ -5157,4 +5157,10 @@ 顯示隱藏的項目 可看到所有隱藏的項目,但會模糊顯示以表示其「隱藏」狀態 + + 拍照 + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml index 81fab5f48f..e18b039953 100644 --- a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml @@ -111,7 +111,7 @@ No se ha podido comunicar con la ubicación de la carpeta. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Unable to add a filesystem watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. diff --git a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml index de6063c410..a78f2ebfd2 100644 --- a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml @@ -111,7 +111,7 @@ Tidak dapat berkomunikasi dengan lokasi folder. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Unable to add a filesystem watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. diff --git a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml index 5414dbd4f9..54756acff0 100644 --- a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml @@ -101,7 +101,7 @@ Не удалось переименовать. - Couldn’t create a .megaignore file for this sync + Не удалось создать файл .megaignore для этой синхронизации Не удалось прочитать конфигурацию синхронизации. Повторите попытку позже или проверьте права доступа к папке. diff --git a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml index 3db9a5d97e..8dbb044555 100644 --- a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml @@ -101,7 +101,7 @@ 重新命名失敗。 - Couldn’t create a .megaignore file for this sync + 無法為此同步建立.megaignore檔案 無法讀取同步設定。稍後再試或檢查資料夾權限。 diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 05c7d652ed..8f2c8048cd 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -199,7 +199,7 @@ هناك العديد من العناصر التي تحمل الاسم نفسه على جانب واحد من المزامنة الخاصة بك والتي ستصبح جميعها نفس العنصر الفردي على الجانب الآخر من المزامنة الخاصة بك - تم اكتشاف نقل أو إعادة تسمية في ميغا MEGA ولكن لا يمكن إجراءها محليًا. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. تم اكتشاف نقل أو إعادة تسمية حيث يحدث محليًا ولكن تعذر إجراؤها في ميغا MEGA. diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index 5241d3fdb0..e69e81504f 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -183,7 +183,7 @@ Mehrere Elemente mit demselben Namen auf der einen Seite Ihrer Synchronisierung würden einem einzigen Element auf der anderen Seite der Synchronisierung entsprechen - Ein Verschieben oder Umbenennen wurde auf MEGA erkannt, konnte jedoch lokal nicht repliziert werden. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Ein lokal erkannter Verschiebe- oder Umbenennungsvorgang konnte auf MEGA nicht repliziert werden. diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index 8f3b5b4776..0a50c16400 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -187,7 +187,7 @@ There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync - A move or rename was detected in MEGA, but couldn’t be replicated locally. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index 0ef03e8a4b..66a54f6609 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -187,7 +187,7 @@ Plusieurs éléments du même nom d’un côté de votre synchronisation deviendraient le même élément de l’autre côté de votre synchronisation - Un déplacement ou un renommage a été détecté sur MEGA, mais n’a pas pu être reproduit localement. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Un déplacement ou un renommage a été détecté localement, mais n’a pas pu être reproduit sur MEGA. diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index ca6fbf2064..3e2a0c829a 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -179,7 +179,7 @@ There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync - A move or rename was detected in MEGA, but couldn’t be replicated locally. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index d8f1977de0..30289122f8 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -187,7 +187,7 @@ Ci sono più oggetti con lo stesso nome da un lato della sincronizzazione che diverrebbero tutti lo stesso oggetto dall\’altro lato della sincronizzazione - MEGA ha riscontrato uno spostamento o una rinominazione, ma non riesce a ripeterla localmente. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Localmente è stato riscontrato uno spostamento o una rinominazione, ma è impossibile da replicare su MEGA. diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index a4179077f1..0f48020365 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -179,7 +179,7 @@ 同期の一方の側に同じ名前の複数の項目がありますが、同期のもう一方の側ではすべて同じ1つの項目になります。 - MEGAで移動または名前変更が検出されましたが、ローカルで複製できませんでした。 + MEGAで移動または名前変更アクションが検出されましたが、ローカルで複製できませんでした。 移動または名前変更がローカルで行われたものとして検出されましたが、MEGAでは複製できませんでした。 diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index dc041c8a8d..bbe1df7663 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -179,7 +179,7 @@ 동기화의 한쪽에서 같은 이름을 다신 여러 항목이 있지만 동기화의 다른 쪽에서 같은 하나의 항목이 될 것입니다 - MEGA에서 이동 또는 이름 변경을 감지하였지만, 로컬에 반영할 수 없었습니다 + A move or rename action was detected in MEGA, but couldn’t be replicated locally. 로컬에서 이동 또는 이름 변경을 감지하였지만, MEGA에 반영할 수 없었습니다. diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index 3323cfb6c0..a8720e91ee 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -183,7 +183,7 @@ Er zijn meerdere items met dezelfde naam aan één kant van uw synchronisatie die allemaal één dezelfde bestand worden aan de andere kant van uw synchronisatie - Er is een verplaatsing of hernoeming gedetecteerd in MEGA, maar deze kon niet lokaal worden gerepliceerd. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Verplaatsen of hernoemen werd lokaal gedetecteerd, maar kon niet worden gerepliceerd in MEGA. diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index b2018175ce..da1340a8b2 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -191,7 +191,7 @@ Istnieje wiele elementów o tej samej nazwie po jednej stronie synchronizacji, które stały się tym samym pojedynczym elementem po drugiej stronie synchronizacji - Przeniesienie lub zmiana nazwy zostały wykryte w MEGA, ale nie mogły zostać odtworzone lokalnie. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Przeniesienie lub zmiana nazwy zostały wykryte lokalnie, ale nie mogły zostać odtworzone w MEGA. diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index c683926a92..6fa7c528a7 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -187,7 +187,7 @@ Há vários itens com o mesmo nome em um lado da sincronização que se tornariam todos o mesmo item no outro lado da sincronização. - Uma movimentação ou renomeação foi detectada no MEGA, mas não foi possível replicá-la no dispositivo local. + Foi detectada no MEGA uma ação para mover ou renomear, mas não foi possível replicá-la no dispositivo local. Foi detectado que uma mudança ou renomeação foi feita localmente, mas não foi possível replicá-la no MEGA. diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index faede03108..847eb3063f 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -187,7 +187,7 @@ Există mai multe elemente cu același nume pe o parte a sincronizării dvs. care ar deveni toate același element unic pe cealaltă parte a sincronizării - O mutare sau redenumire a fost detectată în MEGA, dar nu a putut fi replicată local. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. O mutare sau redenumire a fost detectată la nivel local, dar nu a putut fi reprodusă în MEGA. diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index db2b8f1456..56ef4d5fff 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -191,7 +191,7 @@ На одной стороне синхронизации есть несколько элементов с одинаковым названием, которые на другой стороне синхронизации станут одним и тем же элементом - В MEGA обнаружено перемещение или переименование, но его не удалось воспроизвести локально. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Обнаружено локальное перемещение или переименование, но его не удалось воспроизвести в MEGA. diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index c6b305948a..1bb95dcf0a 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -179,7 +179,7 @@ พบหลายรายการที่มีชื่อซ้ำกันหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว - มีการย้ายหรือเปลี่ยนชื่อไฟล์ใน MEGA แต่ไม่สามารถซิงค์กับอุปกรณ์ของคุณได้ + A move or rename action was detected in MEGA, but couldn’t be replicated locally. ระบบตรวจพบว่ามีการย้ายหรือเปลี่ยนชื่อไฟล์ในเครื่องของคุณ แต่ไม่สามารถจำลองการเปลี่ยนแปลงนี้บน MEGA ได้ diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 1ae959f709..371c9ee82c 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -179,7 +179,7 @@ Có nhiều mục có cùng tên tại một bên của quá trình đồng bộ hóa của bạn và tất cả sẽ trở thành cùng một mục duy nhất ở phía bên kia của quá trình đồng bộ hóa của bạn - Một việc di chuyển hoặc đổi tên đã được phát hiện trên MEGA, nhưng không thể phỏng y theo trong cục bộ. + A move or rename action was detected in MEGA, but couldn’t be replicated locally. Một việc di chuyển hoặc đổi tên đã được phát hiện trong cục bộ, nhưng không thể phỏng y theo trên MEGA. diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index e8916f9f90..6a21302cd1 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -179,7 +179,7 @@ 同步的一侧具有多个相同名称的项目,这些项目在同步的另一侧都将成为相同的单一项目 - 在MEGA中检测到移动或重命名,但无法在本地复制。 + A move or rename action was detected in MEGA, but couldn’t be replicated locally. 检测到本地发生的移动或重命名,但无法在MEGA中复制。 diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 55173b0845..579948df23 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -179,7 +179,7 @@ 同步的一側有多個具有相同名稱的項目,這些項目在同步的另一側都將成為相同的單一項目 - 在MEGA中偵測到移動或重新命名的變動,但無法在本地複製。 + A move or rename action was detected in MEGA, but couldn’t be replicated locally. 偵測到本地發生的移動或重新命名,但無法在MEGA中複製。 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 8cba314ee1..786f0d8018 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - لا يمكن لميغا MEGA مزامنة هذا المجلد أو نسخه احتياطيًا لأن نظام الملفات على جهازك غير مدعوم. + MEGA can’t sync or backup this folder because the file system on your device is not supported لا يمكن مزامنة المجلد الذي اخترته @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ تمت إعادة تحميل الحساب. لم يتم تطبيق أي تحديثات فائتة على النسخ الاحتياطية أو المزامنات الخاصة بك. - تم إيقاف المزامنة أو النسخ الاحتياطي حيث يبدو أنك قمت بتسجيل الخروج من تطبيق الحاسوب المكتبي. قم بتسجيل الدخول مرة أخرى عبر تطبيق الحاسوب المكتبي واستأنف المزامنة أو النسخ الاحتياطي. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. غير متوفر @@ -69,7 +69,7 @@ حدث خطأ ما. - لا يمكن مزامنة المجلد أو نسخه احتياطيًا لأن مجلد ميغا MEGA موجود في سلة المحذوفات. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. @@ -79,7 +79,9 @@ حدثت مشكلة في مزامنة هذا المجلد أو نسخه احتياطيًا. أوقف المزامنة أو النسخ الاحتياطي وحاول إعداده مرة أخرى في تطبيق الحاسوب المكتبي أو تواصل مع قسم الدعم. - لا يمكن مزامنة المجلد لأنه داخل مجلد متزامن. + Folder can’t be synced as it’s already inside a synced folder - لا يمكن مزامنة الملفات الموجودة في هذا المجلد أو نسخها احتياطيًا. ستحتاج إلى إعادة تمكين المزامنة أو النسخ الاحتياطي من تطبيق الحاسوب المكتبي. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index df1e21ee88..de1ec3e906 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA kann diesen Ordner nicht synchronisieren oder sichern, da das Dateisystem Ihres Geräts nicht unterstützt wird. + MEGA can’t sync or backup this folder because the file system on your device is not supported Der gewählte Ordner kann nicht synchronisiert werden @@ -23,7 +23,7 @@ Der Ordner kann nicht synchronisiert werden, da es sich um einen freigegebenen Ordner handelt, auf den Sie keinen Vollzugriff haben - Die Dateien in diesem Ordner können nicht synchronisiert oder gesichert werden. Sie müssen die Synchronisierung bzw. das Backup in der Desktop-App wieder aktivieren. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Der Ordner kann nicht synchronisiert werden, da er bereits synchronisierte Ordner enthält @@ -35,7 +35,7 @@ Account neu geladen. Verpasste Updates Ihrer Backups oder Synchronisierungen wurden nicht übernommen. - Die Synchronisierung oder das Backup wurde angehalten, da Sie sich anscheinend in der Desktop-App ausgeloggt haben. Loggen Sie sich in der Desktop-App wieder ein und aktivieren Sie die Synchronisierung bzw. das Backup erneut. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,7 +69,7 @@ Something went wrong. - Der Ordner kann nicht synchronisiert oder gesichert werden, da sich der MEGA-Ordner im Papierkorb befindet. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Der Ordner auf Ihrem Gerät kann derzeit nicht gefunden werden. Versuchen Sie es später erneut. @@ -79,7 +79,9 @@ Problem bei der Synchronisierung oder Sicherung dieses Ordners. Beenden Sie die Synchronisierung bzw. das Backup und richten Sie sie in der Desktop-App erneut ein oder wenden Sie sich an den Support. - Der Ordner kann nicht synchronisiert werden, da er sich bereits innerhalb eines synchronisierten Ordners befindet. + Folder can’t be synced as it’s already inside a synced folder - Die Dateien in diesem Ordner können nicht synchronisiert oder gesichert werden. Sie müssen die Synchronisierung bzw. das Backup in der Desktop-App wieder aktivieren. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 3899d27587..df38fa9646 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - No se puede sincronizar ni hacer un backup de esta carpeta ya que el sistema de archivos de tu dispositivo no es compatible. + MEGA can’t sync or backup this folder because the file system on your device is not supported The folder you chose can’t be synced @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ Cuenta recargada. No se han realizado actualizaciones pendientes de tus backups o sincronizaciones. - La sincronización o el backup se han detenido porque parece que has cerrado sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -55,7 +55,7 @@ No se ha podido comunicar con la ubicación de la carpeta. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Unable to add a filesystem watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. @@ -69,17 +69,19 @@ Something went wrong. - Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup porque la carpeta de MEGA está en la Papelera. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. Folder in your device can’t be located - Ha habido un problema al sincronizar o hacer un backup de esta carpeta debido a unos cambios en la carpeta de MEGA. Detén la sincronización o el backup y actívalos de nuevo desde la aplicación de escritorio o contacta con el servicio de soporte. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Detén la sincronización o el backup e intenta volver a configurarlos en la aplicación de escritorio, o ponte en contacto con el servicio de soporte. - La carpeta no se puede sincronizar porque ya está dentro de una carpeta sincronizada. + Folder can’t be synced as it’s already inside a synced folder - Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup. Reactiva la sincronización o el backup desde la aplicación de escritorio. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 644930759d..d46cd915b4 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -3,25 +3,25 @@ No sync error - MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge. + MEGA can’t sync or backup this folder because the file system on your device is not supported Le dossier que vous avez choisi ne peut pas être synchronisé Un fichier ne peut pas être synchronisé individuellement. Vous devez définir la synchronisation du dossier. - Échec de l’analyse initiale. Vous devez réactiver votre synchronisation ou sauvegarde dans l’appli pour ordinateur. + Échec d’analyse initiale. Vous devez réactiver votre synchronisation ou sauvegarde dans l’appli pour ordinateur. - Impossible de trouver le dossier dans MEGA. Soit il a été déplacé, soit il a été supprimé, soit vous n’y avez pas accès. + Impossible de trouver le dossier dans MEGA. Soit il a été déplacé, soit il a été supprimé, soit vous n’y avez pas accès - Unable to sync or back up this folder as your storage is full + Impossible de synchroniser ou sauvegarder ce dossier, car votre espace de stockage est saturé Impossible de synchroniser ou sauvegarder ce dossier, car votre abonnement est expiré - Le dossier ne peut pas être synchronisé, car l’utilisateur qui l’a partagé a dépassé sa limite d’espace de stockage + Le dossier ne peut pas être synchronisé, car la personne qui l’a partagé a dépassé sa limite d’espace de stockage - Impossible de trouver le dossier dans MEGA. Soit il a été déplacé, soit il a été supprimé, soit vous n’y avez pas accès. + Impossible de trouver le dossier dans MEGA. Soit il a été déplacé, soit il a été supprimé, soit vous n’y avez pas accès - Impossible de synchroniser le dossier, car c’est un dossier partagé auquel vous n’avez pas l’accès total. + Impossible de synchroniser le dossier, car c’est un dossier partagé auquel vous n’avez pas l’accès total Les fichiers de ce dossier ne peuvent être ni synchronisés ni sauvegardés. Vous devez réactiver la synchronisation ou la sauvegarde dans l’appli pour ordinateur. @@ -29,7 +29,7 @@ MEGA ne peut ni synchroniser ni sauvegarder les dossiers VirtualBox - Unable to sync or back up this folder as the account has been blocked + Impossible de synchroniser ou sauvegarder ce dossier, car le compte a été bloqué Problème de synchronisation ou de sauvegarde de ce dossier. Réessayez ultérieurement. Si la situation persiste, contactez l’assistance. @@ -69,7 +69,7 @@ Un problème est survenu - Le dossier ne peut ni être synchronisé ni sauvegardé, car le dossier MEGA est dans la Corbeille. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Impossible de trouver le dossier sur votre appareil. Réessayez plus tard. @@ -79,7 +79,9 @@ Problème de synchronisation ou de sauvegarde de ce dossier. Arrêtez la synchronisation ou la sauvegarde, puis tentez de la définir de nouveau dans l’appli pour ordinateur ou contactez l’assistance. - Le dossier ne peut pas être synchronisé, car il fait déjà partie d’un dossier synchronisé. + Folder can’t be synced as it’s already inside a synced folder Les fichiers de ce dossier ne peuvent être ni synchronisés ni sauvegardés. Vous devez réactiver la synchronisation ou la sauvegarde dans l’appli pour ordinateur. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 4cb9992c52..50ba41ccf9 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -3,13 +3,13 @@ No sync error - MEGA tidak dapat menyinkronkan atau mencadangkan folder ini karena sistem file pada perangkat anda tidak didukung. + MEGA can’t sync or backup this folder because the file system on your device is not supported The folder you chose can’t be synced File tidak dapat disinkronkan satu per satu. Anda perlu mengatur sinkronisasi dari folder. - Pemindaian awal gagal. Anda harus mengaktifkan kembali sinkronisasi atau cadangan dari aplikasi Desktop. + Initial scan failed. You will need to re-enable your sync or backup from the desktop app. Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ Akun dimuat ulang. Pembaruan apa pun yang terlewat untuk cadangan atau sinkronisasi anda belum diterapkan. - Sinkronisasi atau pencadangan telah dihentikan karena anda tampaknya keluar dari aplikasi Desktop. Masuk kembali melalui aplikasi Desktop, dan lanjutkan sinkronisasi atau pencadangan. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -55,7 +55,7 @@ Tidak dapat berkomunikasi dengan lokasi folder. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Unable to add a filesystem watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. @@ -69,17 +69,19 @@ Something went wrong. - Folder tidak dapat disinkronkan atau dicadangkan karena folder MEGA ada di Tempat sampah. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. Folder in your device can’t be located - Masalah menyinkronkan atau membuat cadangan folder ini karena perubahan pada folder MEGA. Hentikan sinkronisasi atau pencadangan dan coba atur lagi di aplikasi Desktop, atau hubungi Dukungan. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. Masalah saat menyinkronkan atau membuat cadangan folder ini. Hentikan sinkronisasi atau pencadangan dan coba atur lagi di aplikasi Desktop, atau hubungi Bantuan. - Folder tidak dapat disinkronkan karena sudah berada di dalam folder yang disinkronkan. + Folder can’t be synced as it’s already inside a synced folder - File dalam folder ini tidak dapat disinkronkan atau dicadangkan. Anda harus mengaktifkan kembali sinkronisasi atau cadangan dari aplikasi Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 8d710ade84..6c74752e18 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato. + MEGA can’t sync or backup this folder because the file system on your device is not supported La cartella che hai scelto non può essere sincronizzata @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ Account ricaricato. Qualsiasi aggiornamento mancato ai tuoi backup o alle tue sincronizzazioni non è stato applicato. - La sincronizzazione o il backup è stato fermato perché sembra che tu abbia effettuato il logout dall\’app per desktop. Effettua nuovamente l\’accesso tramite l\’app per desktop, e riprendi la sincronizzazione o il backup. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. La cartella nel dispositivo non può essere localizzata - Problema nella sincronizzazione o nel backup di questa cartella a causa di cambiamenti alla cartella MEGA. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente nell’app per desktop, o contatta il Supporto. + Problemi durante la sincronizzazione o il backup di questa cartella a causa di modifiche alla cartella MEGA. Interrompi la sincronizzazione o il backup e prova a configurarli nuovamente nell\’app desktop oppure contatta il Supporto. Problemi nella sincronizzazione o nel backup di questa cartella. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente dall\’app per desktop, o contatta il Supporto. - La cartella non può essere sincronizzata in quanto è già dentro una cartella sincronizzata. + Folder can’t be synced as it’s already inside a synced folder - I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 29b8963c0a..5296bffd0c 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません。 + デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません 選択したフォルダは同期できません @@ -13,7 +13,7 @@ MEGA内のフォルダは、移動または削除されたため見つからないか、アクセス権がない可能性があります - Unable to sync or back up this folder as your storage is full + ストレージがいっぱいのため、このフォルダを同期またはバックアップできません お客様のプランの有効期限が切れているため、このフォルダを同期またはバックアップできません @@ -29,7 +29,7 @@ MEGAはVirtualBoxフォルダを同期またはバックアップできません - Unable to sync or back up this folder as the account has been blocked + アカウントがブロックされているため、このフォルダを同期またはバックアップできません。 このフォルダの同期またはバックアップ中に問題が発生しました。あとでもう一度お試しください。問題が解決しない場合は、サポートにお問い合わせください。 @@ -69,17 +69,19 @@ 何か問題が発生しました。 - MEGAフォルダはごみ箱にあるため、フォルダを同期またはバックアップできません。 + MEGAフォルダはごみ箱にあるため、フォルダを同期またはバックアップできません 現在、デバイス内のフォルダが見つかりません。あとでもう一度お試しください。 デバイス内のフォルダが見つかりません - MEGAフォルダへの変更により、このフォルダの同期またはバックアップ中に問題が発生しました。バックアップを停止し、デスクトップアプリでもう一度セットアップしてみるか、サポートにお問い合わせください。 + MEGAフォルダへの変更により、このフォルダの同期またはバックアップ中に問題が発生しました。バックアップを停止し、デスクトップアプリでもう一度セットアップしてみるか、サポートにご連絡ください。 このフォルダの同期またはバックアップ中に問題が発生しました。同期またはバックアップを停止し、デスクトップアプリでもう一度設定してみるか、サポートにお問い合わせください。 - パスの上にアクティブな同期。 + パスの上にアクティブな同期 このフォルダ内のファイルは同期またはバックアップできません。デスクトップアプリから同期またはバックアップを再度有効にする必要があります。 + + 同期が一時停止されました。バッテリー残量が少なすぎます。同期を再開するにはバッテリーを充電してください。 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 331f1ed52d..4f6334b616 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - 이 폴더는 당신의 기기의 파일 시스템이 지원하지 않기 때문에 MEGA에서 동기화 하거나 백업할 수 없습니다. + MEGA can’t sync or backup this folder because the file system on your device is not supported 선택한 폴더는 동기화할 수 없습니다 @@ -23,7 +23,7 @@ 당신에게 전체 권한 없이 공유된 폴더이기 때문에 폴더를 동기화할 수 없습니다. - 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. 동기화된 폴더가 포함되어 있는 폴더이기 때문에 동기화할 수 없습니다 @@ -35,7 +35,7 @@ 계정을 다시 불러왔습니다. 백업 또는 동기화에 누락된 변경사항이 적용되지 않습니다. - 데스크톱 앱에서 로그아웃한 것으로 나타나서 동기화 또는 백업이 멈추었습니다. 데스크톱 앱에서 다시 로그인하고, 동기화 또는 백업을 재개하세요. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,7 +69,7 @@ Something went wrong. - MEGA 폴더가 휴지통에 있어서 폴더를 동기화 또는 백업할 수 없습니다. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin 장치의 폴더를 찾을 수 없습니다. 나중에 다시 시도하세요. @@ -79,7 +79,9 @@ 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. - 동기화된 폴더 안에 위치한 폴더이기 때문에 동기화할 수 없습니다. + Folder can’t be synced as it’s already inside a synced folder - 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index ca649606c9..f7e051244e 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA kan geen synchronisatie of back-up van deze map maken omdat het bestandsysteem op uw apparaat niet ondersteund is. + MEGA can’t sync or backup this folder because the file system on your device is not supported De map die u heeft gekozen, kan niet worden gesynchroniseerd @@ -23,7 +23,7 @@ De map kan niet worden gesynchroniseerd omdat het een gedeelde map is waar u geen volledige toegang tot heeft - Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet het synchroniseren of backuppen opnieuw inschakelen via de Desktop-applicatie. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. De map kan niet worden gesynchroniseerd omdat deze al gesynchroniseerde mappen bevat @@ -35,7 +35,7 @@ Account opnieuw geladen. Eventuele gemiste updates voor uw back-ups of synchronisaties zijn niet toegepast. - Synchronisatie of back-up is gestopt omdat het lijkt alsof u bent afgemeld bij de Desktop-applicatie. Meld u opnieuw aan via de Desktop-applicatie en hervat de synchronisatie of back-up. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Er is iets misgegaan. - De map kan niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt omdat de MEGA-map zich in de Prullenbak bevindt. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin De map op uw apparaat kan op dit moment niet worden gevonden. Probeer het later nog eens. De map op uw apparaat kan niet worden gevonden - Probleem bij het synchroniseren of maken van een reservekopie van deze map vanwege wijzigingen in de MEGA-map. Stop het synchroniseren of de backup en probeer het opnieuw in te stellen in de Desktop-applicatie, of neem contact op met de klantenservice. + Probleem bij het synchroniseren of maken van een reservekopie van deze map vanwege wijzigingen in de MEGA-map. Stop het synchroniseren of de backup en probeer het opnieuw in te stellen in de desktop applicatie, of neem contact op met de Ondersteuning. Probleem bij het synchroniseren of back-uppen van deze map. Stop de synchronisatie of back-up en probeer deze opnieuw in te stellen in de Desktop-applicatie, of neem contact op met de ondersteuning. - Map kan niet gesynchroniseert worden omdat het al binnen een gesynchroniseerde map is. + Folder can’t be synced as it’s already inside a synced folder - Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet de synchronisatie of back-up opnieuw inschakelen via de desktop-applicatie. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index d6de02774f..73935b3381 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA nie może zsynchronizować ani wykonać kopii zapasowej tego katalogu, ponieważ system plików na urządzeniu nie jest obsługiwany. + MEGA can’t sync or backup this folder because the file system on your device is not supported Nie można zsynchronizować wybranego katalogu @@ -23,7 +23,7 @@ Nie można zsynchronizować katalogu, ponieważ jest to katalog udostępniony, do którego nie masz pełny dostęp - Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacja komputerowej. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Nie można zsynchronizować katalogu, ponieważ zawiera już zsynchronizowane katalogi @@ -35,7 +35,7 @@ Konto zostało przeładowane. Wszelkie pominięte aktualizacje kopii zapasowych lub synchronizacji nie zostały zastosowane. - Synchronizacja lub tworzenie kopii zapasowej zostały zatrzymane, ponieważ wygląda na to, że użytkownik wylogował się z aplikacji Desktop. Zaloguj się ponownie za pomocą aplikacji Desktop i wznów synchronizację lub tworzenie kopii zapasowej. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - Nie można synchronizować ani utworzyć kopii zapasowej katalogu, ponieważ katalog MEGA znajduje się w Koszu. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Katalog w urządzeniu nie może być teraz zlokalizowany. Spróbuj ponownie później. Nie można zlokalizować katalogu w urządzeniu - Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu z powodu zmian w katalog MEGA. Zatrzymaj synchronizację lub kopię zapasową i spróbuj ponownie skonfigurować ją w aplikacja komputerowej lub kontakt techniczną. + Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu z powodu zmian w katalogu MEGA. Zatrzymaj synchronizację lub kopię zapasową i spróbuj ponownie skonfigurować ją w aplikacja desktopowa komputerowej lub kontakt techniczną. Problem z synchronizacją lub kopią zapasową tego katalogu. Zatrzymaj synchronizację lub tworzenie kopii zapasowej i spróbuj skonfigurować je ponownie w aplikacji Desktop lub skontaktuj się z pomocą techniczną. - Katalog nie może być zsynchronizowany, ponieważ znajduje się już w zsynchronizowanym katalogu. + Folder can’t be synced as it’s already inside a synced folder - Plików w tym katalogu nie można synchronizować ani tworzyć ich kopii zapasowych. Konieczne będzie ponowne włączenie synchronizacji lub tworzenia kopii zapasowych w aplikacji Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index f88782cac6..cd9e0b0c55 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado. + O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado Não é possível sincronizar a pasta selecionada @@ -69,7 +69,7 @@ Algo deu errado. - Não é possível sincronizar ou fazer backup porque a pasta no MEGA está na Lixeira. + Não é possível sincronizar ou fazer backup porque a pasta no MEGA está na Lixeira Não foi possível localizar a pasta no seu dispositivo - tente novamente mais tarde. @@ -79,7 +79,9 @@ Não foi possível sincronizar ou fazer o backup desta pasta. Cancele a sincronização ou o backup e tente configurá-lo novamente no aplicativo para desktop, ou entre em contato com a nossa equipe de Suporte. - Não é possível sincronizar esta pasta porque está dentro de uma pasta sincronizada. + Não é possível sincronizar esta pasta porque está dentro de uma pasta sincronizada Não foi possível sincronizar ou fazer backup dos arquivos nesta pasta. Você precisa reativar a sua sincronização ou o seu backup no aplicativo para desktop. + + A sincronização foi pausada porque o nível da bateria está muito baixo. Carregue a bateria para retomar a sincronização. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 5b5b801036..d264079b35 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat. + MEGA can’t sync or backup this folder because the file system on your device is not supported Folderul ales nu poate fi sincronizat @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ Contul a fost reîncărcat. Toate actualizările ratate ale backupurilor sau ale sincronizărilor nu au fost aplicate. - Sincronizarea sau backupul au fost oprite pe măsură ce parcă v-ați deconectat de la aplicația Desktop. Conectați-vă din nou prin aplicația Desktop și reluați sincronizarea sau backup-ul. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. Folderul din dispozitiv dvs. nu poate fi localizat - Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. + Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați Asistența. Problemă la sincronizarea sau backup a acestui folder. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. - Folderul nu poate fi sincronizat, deoarece se află deja într-un folder sincronizat. + Folder can’t be synced as it’s already inside a synced folder - Fișierele din acest folder nu pot fi sincronizate sau backup-uite. Va trebui să reactivați sincronizarea sau backupul din aplicația desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index b269af3fb1..d1c97c70be 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA не может синхронизировать эту папку или сделать резервную копию, потому что файловая система на вашем устройстве не поддерживается. + MEGA can’t sync or backup this folder because the file system on your device is not supported Выбранную папку невозможно синхронизировать @@ -13,7 +13,7 @@ Не удалось найти папку в MEGA, так как она была перемещена или удалена, либо у вас нет доступа - Unable to sync or back up this folder as your storage is full + Невозможно синхронизировать или создать резервную копию этой папки, так как ваше хранилище заполнено Невозможно синхронизировать или создать резервную копию этой папки, так как срок действия вашего плана истёк @@ -23,29 +23,29 @@ Невозможно синхронизировать папку, так как это общая папка, к которой у вас нет полного доступа - Файлы в этой папке невозможно синхронизировать или создать их резервные копии. Вам нужно снова включить синхронизацию или резервное копирование из настольного приложения. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Папку нельзя синхронизировать, так как она уже содержит синхронизируемые папки MEGA не может синхронизировать или создавать резервные копии папок VirtualBox - Unable to sync or back up this folder as the account has been blocked + Невозможно синхронизировать или создать резервную копию этой папки, так как аккаунт заблокирован Проблема с синхронизацией или резервным копированием этой папки. Повторите попытку позже. Если проблема не исчезнет, обратитесь в поддержку. Аккаунт перезагружен. Любые пропущенные обновления ваших резервных копий или синхронизаций не были применены. - Синхронизация или резервное копирование остановлены, поскольку вы, похоже, вышли из настольного приложения. Снова войдите в систему в настольном приложении и возобновите синхронизацию или резервное копирование. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Не удаётся найти папку на внешнем диске. - There’s already a synced folder at the same location + В том же расположении уже есть синхронизируемая папка Не удалось переименовать. - Couldn’t create a .megaignore file for this sync + Не удалось создать файл .megaignore для этой синхронизации Не удалось прочитать конфигурацию синхронизации. Повторите попытку позже или проверьте права доступа к папке. @@ -61,17 +61,17 @@ Unable to open state cache database - Insufficient storage space on your device + Недостаточно места для хранения на вашем устройстве Не удалось прочитать расположение синхронизации. Убедитесь, что расположение папки доступно и предоставлены права доступа к нему. - An unknown error occurred. Contact Support. + Произошла неизвестная ошибка. Обратитесь в поддержку. Something went wrong. - Папку невозможно синхронизировать или создать её резервную копию, так как папка MEGA находится в Корзине. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin - Folder in your device can’t be located right now. Try again later. + Не удалось найти папку на вашем устройстве в данный момент. Повторите попытку позже. Не удалось найти папку на вашем устройстве @@ -79,7 +79,9 @@ Проблема с синхронизацией или резервным копированием этой папки. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. - Папку нельзя синхронизировать, так как она уже находится внутри синхронизируемой папки. + Folder can’t be synced as it’s already inside a synced folder - Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index e4d78e35c7..2e746e7857 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ได้ เนื่องจากไม่สนับสนุนระบบไฟล์ในอุปกรณ์ของคุณ + MEGA can’t sync or backup this folder because the file system on your device is not supported โฟลเดอร์ที่คุณเลือกไม่สามารถซิงค์ได้ @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ บัญชีของคุณถูกโหลดซ้ำ การเปลี่ยนแปลงที่หายไปจะไม่มีผลกับการสำรองข้อมูลหรือการซิงค์ของคุณ - การซิงค์หรือการสำรองข้อมูลถูกหยุดลง ซึ่งดูเหมือนว่าคุณได้ออกจากระบบแอปเดสก์ท็อปแล้ว กรุณาเข้าสู่ระบบผ่านแอปเดสก์ท็อปแล้วเริ่มต้นการซิงค์หรือการสำรองข้อมูลใหม่อีกครั้ง + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์ได้ เนื่องจากโฟลเดอร์ MEGA อยู่ในถังขยะ + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. ไม่สามารถหาโฟลเดอร์ในอุปกรณ์ของคุณได้ - มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้เนื่องจากมีการเปลี่ยนแปลงในโฟลเดอร์ MEGA คุณสามารถหยุดการซิงค์หรือสำรองข้อมูลและลองตั้งค่าใหม่ในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน + มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ เนื่องจากมีการเปลี่ยนแปลงในโฟลเดอร์ MEGA คุณสามารถหยุดการซิงค์หรือสำรองข้อมูลและลองตั้งค่าใหม่ในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน พบปัญหาในการซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ ให้หยุดการซิงค์หรือสำรองข้อมูล แล้วลองตั้งค่าอีกครั้งในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน - ไม่สามารถซิงค์โฟลเดอร์นี้ได้เนื่องจากอยู่ในโฟลเดอร์ที่มีการซิงค์อยู่แล้ว + Folder can’t be synced as it’s already inside a synced folder - ไฟล์ในโฟลเดอร์นี้ไม่สามารถซิงค์หรือสำรองข้อมูลได้ คุณต้องเปิดใช้งานการซิงค์หรือการสำรองข้อมูลใหม่จากแอปบนเดสก์ท็อปก่อน + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index b589bb7686..ad4239e36d 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -3,17 +3,17 @@ No sync error - MEGA không thể đồng bộ hoặc sao lưu thư mục này bởi vì hệ thống tệp trên thiết bị của bạn không được hỗ trợ. + MEGA can’t sync or backup this folder because the file system on your device is not supported Thư mục bạn đã chọn không thể đồng bộ được Đồng bộ không thể thực hiện với tệp tin riêng lẻ. Bạn cần phải thiết lập đồng bộ từ một thư mục. - Quét khởi đầu đã không thành công. Bạn sẽ cần kích hoạt lại đồng bộ hóa hoặc sao lưu của mình từ Ứng dụng cho máy tính. + Quét khởi đầu đã không thành công. Bạn sẽ cần kích hoạt lại đồng bộ hóa hoặc sao lưu của mình từ ứng dụng cho máy tính. Không tìm thấy vị trí của thư mục trên MEGA, có thể do đã bị di chuyển hoặc bị xóa, cũng có thể là bạn không có quyền truy cập - Unable to sync or back up this folder as your storage is full + Không thể đồng bộ hóa hoặc sao lưu thư mục này vì không gian lưu trữ của bạn đã đầy Không thể đồng bộ hóa hoặc sao lưu thư mục này vì gói đăng ký của bạn đã hết hạn @@ -23,19 +23,19 @@ Thư mục không thể đồng bộ được vì thư mục này đã chia sẻ mà không có cấp quyền truy cập toàn quyền cho bạn - Các tệp tin trong thư mục này không thể đồng bộ hóa hoặc sao lưu được. Bạn sẽ cần phải kích hoạt lại đồng bộ hoặc sao lưu từ App cho Máy tính. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Thư mục không thể đồng bộ được bởi vì nó đang nằm ở trong một thư mục được đồng bộ MEGA không thể đồng bộ hóa hoặc sao lưu các thư mục VirtualBox - Unable to sync or back up this folder as the account has been blocked + Không thể đồng bộ hóa hoặc sao lưu thư mục này vì tài khoản của bạn đã bị chặn Có sự cố khi đồng bộ hóa hoặc sao lưu thư mục này. Thử lại sau. Nếu sự cố vẫn tiếp diễn, hãy liên hệ với bộ phận Hỗ trợ. Đã tải lại tài khoản. Mọi cập nhật bị bỏ lỡ đối với các bản sao lưu hoặc đồng bộ hóa của bạn chưa có được áp dụng. - Đồng bộ hóa hoặc sao lưu đã bị dừng do có vẻ như bạn đã đăng xuất khỏi Ứng dụng cho máy tính. Đăng nhập vào lại Ứng dụng cho máy tính để tiếp tục đồng bộ hóa hoặc sao lưu. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - Thư mục không thể đồng bộ hoặc sao lưu được bởi vì thư mục tương ứng trên MEGA đang nằm trong Thùng Rác. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Hiện không thể xác định vị trí thư mục trong thiết bị của bạn. Hãy thử lại sau. Không tìm thấy vị trí của thư mục trong thiết bị của bạn - Có sự cố đồng bộ hóa hoặc sao lưu thư mục này do các thay đổi của thư mục MEGA. Dừng đồng bộ hóa hoặc sao lưu và thử thiết lập lại trong App cho Máy tính hoặc liên hệ với bộ phận Hỗ trợ. + Có sự cố đồng bộ hóa hoặc sao lưu thư mục này do các thay đổi của thư mục MEGA. Dừng đồng bộ hóa hoặc sao lưu và thử thiết lập lại trong app đành cho máy tính hoặc liên hệ với bộ phận Hỗ trợ. Có sự cố khi đồng bộ hóa hoặc sao lưu thư mục này. Hãy thử dừng đồng bộ hóa hoặc sao lưu và thử thiết lập lại trong Ứng dụng cho máy tính hoặc liên hệ với bộ phận Hỗ Trợ. - Thư mục không thể đồng bộ được bởi vì nó đang nằm ở trong một thư mục được đồng bộ. + Folder can’t be synced as it’s already inside a synced folder - Các tệp tin trong thư mục này không thể đồng bộ hóa hoặc sao lưu được. Bạn sẽ cần phải kích hoạt lại đồng bộ hoặc sao lưu từ ứng dụng cho máy tính. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index e53768e4d1..037b32f649 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA无法同步或备份此文件夹,因为尚不支持您设备上的文件系统。 + MEGA can’t sync or backup this folder because the file system on your device is not supported 您选择的文件夹无法同步 @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ 帐户已重新加载。对备份或同步的任何更新尚未应用。 - 由于您似乎已登出桌面应用程序,因此同步或备份已停止。通过桌面应用程序重新登录,然后恢复同步或备份。 + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -69,17 +69,19 @@ Something went wrong. - 由于MEGA文件夹位于回收站中,文件夹无法同步或备份。 + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. 无法找到您设备中的文件夹 - 由于MEGA文件夹发生更改,因此同步或备份此文件夹时出现问题。请停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 + 由于MEGA文件夹发生变动,同步或备份此文件夹时出现问题。请停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 同步或备份此文件夹时出现问题。停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 - 无法同步文件夹,因为它已经在同步的文件夹中。 + Folder can’t be synced as it’s already inside a synced folder - 无法同步或备份此文件夹中的文件。您需要从桌面应用程序重新启用同步或备份。 + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index cc25220289..966cec2af1 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - 因為不支援您裝置上的檔案系統,MEGA無法同步或備份此資料夾。 + MEGA can’t sync or backup this folder because the file system on your device is not supported 您選擇的資料夾無法同步 @@ -11,41 +11,41 @@ 初始掃描失敗。您需要從桌面應用程式重新啟用同步或備份。 - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + MEGA無法找到MEGA中的資料夾,因為它已被移動或刪除,或者您可能沒有存取權限。 - Unable to sync or back up this folder as your storage is full + 由於您的儲存空間已滿,因此無法同步或備份此資料夾。 - Unable to sync or back up this folder as your plan has expired + 由於您的方案已過期,因此無法同步或備份此資料夾。 - Folder can’t be synced as the user who shared this folder has reached their storage limit + 無法同步資料夾,因為共享此資料夾的使用者已達到其儲存限制。 - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + MEGA無法找到MEGA中的資料夾,因為它已被移動或刪除,或者您可能沒有存取權限。 - Folder can’t be synced as it’s a shared folder that you don’t have full access to + 資料夾無法同步,因為它是一個您沒有完全存取權限的共用資料夾 - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. - Folder can’t be synced as it already contains synced folders + 資料夾無法同步,因為它已經包含同步的資料夾 - MEGA can’t sync or back up VirtualBox folders + MEGA無法同步或備份VirtualBox資料夾 - Unable to sync or back up this folder as the account has been blocked + 由於帳戶已被封鎖,因此無法同步或備份此資料夾 同步或備份此資料夾時出現問題。稍後再試。如果問題仍然存在,請聯繫客服。 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 - 由於您似乎已登出桌面應用程式,因此同步或備份已停止。使用桌面應用程式重新登入,然後恢復同步或備份。 + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A 無法找到外部磁碟的資料夾。 - There’s already a synced folder at the same location + 在同一位置已有一個同步的資料夾 重新命名失敗。 - Couldn’t create a .megaignore file for this sync + 無法為此同步建立.megaignore檔案 無法讀取同步設定。稍後再試或檢查資料夾權限。 @@ -61,25 +61,27 @@ Unable to open state cache database - Insufficient storage space on your device + 您裝置上的儲存空間不足 無法讀取同步位置。檢查該位置是否可用,而且是否已授予該資料夾位置的權限。 - An unknown error occurred. Contact Support. + 發生未知錯誤。聯繫客服。 Something went wrong. - 由於MEGA資料夾位於垃圾筒中,因此資料夾無法同步或備份。 + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin - Folder in your device can’t be located right now. Try again later. + 目前無法找到您裝置中的資料夾。稍後再試。 無法找到您裝置中的資料夾 - 由於MEGA資料夾發生更動,因此同步或備份此資料夾時出現問題。請停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 + 由於MEGA資料夾發生變動,因此同步或備份此資料夾時出現問題。請停止同步或備份,然後嘗試在桌面應用程式中再次設定,或聯繫客服。 同步或備份此資料夾時出現問題。停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 - 由於資料夾已位於同步的資料夾中,因此無進行同步。 + Folder can’t be synced as it’s already inside a synced folder - 無法同步或備份此資料夾中的檔案。您需要從桌面應用程式重新啟用同步或備份。 + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. \ No newline at end of file From 27adf4a77797e91c2683fa31896e8d14b1c03b0c Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Wed, 10 Apr 2024 17:03:53 +0530 Subject: [PATCH 086/261] SAO-53: Enable feature flag for new search activity - Fix typing issue --- .../ui/controls/appbar/LegacySearchAppBar.kt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt index 31283bf825..c57abeed35 100644 --- a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt +++ b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/appbar/LegacySearchAppBar.kt @@ -191,6 +191,11 @@ fun ExpandedSearchAppBar( modifier: Modifier = Modifier, isHideAfterSearch: Boolean = false, ) { + var textFieldValue by remember { + mutableStateOf( + TextFieldValue(text, TextRange(text.length)) + ) + } Surface( modifier = modifier .fillMaxWidth() @@ -200,7 +205,6 @@ fun ExpandedSearchAppBar( ) { val initialLaunch = rememberSaveable { mutableStateOf(true) } val keyboardVisibleInPreviousConfiguration by keyboardAsState() - val focusRequester = remember { FocusRequester() } val iconColor = if (MaterialTheme.colors.isLight) Color.Black else Color.White val keyboardController = LocalSoftwareKeyboardController.current @@ -210,8 +214,11 @@ fun ExpandedSearchAppBar( .padding(start = 5.dp, end = 5.dp) .focusRequester(focusRequester) .testTag(SEARCH_TOOLBAR_TEXT_VIEW_TEST_TAG), - value = TextFieldValue(text, TextRange(text.length)), - onValueChange = { onSearchTextChange(it.text) }, + value = textFieldValue, + onValueChange = { + textFieldValue = it + onSearchTextChange(it.text) + }, placeholder = { Text( modifier = Modifier.alpha(ContentAlpha.medium), @@ -237,7 +244,11 @@ fun ExpandedSearchAppBar( if (text.isNotEmpty()) { IconButton( modifier = Modifier.testTag(SEARCH_TOOLBAR_CLOSE_BUTTON_TEST_TAG), - onClick = { onSearchTextChange("") }) { + onClick = { + textFieldValue = TextFieldValue() + onSearchTextChange("") + } + ) { Icon( imageVector = Icons.Default.Close, contentDescription = "Close Icon", From fb42413e357fce50d6073bd132327defd5a968f7 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 11 Apr 2024 20:23:30 +1200 Subject: [PATCH 087/261] CU-752: Add log to trace processing worker (cherry picked from commit 386052186a66a9a853785e50e7aa1e4740c542af) --- .../camerauploads/CameraUploadsWorkerTest.kt | 11 +++++++ .../app/data/worker/ChatUploadsWorkerTest.kt | 14 +++++++- .../app/transfers/DownloadsWorkerTest.kt | 12 +++++++ .../data/facade/WorkManagerGatewayImpl.kt | 18 ++-------- .../data/worker/AbstractTransfersWorker.kt | 6 ++++ .../data/worker/CameraUploadsWorker.kt | 14 +++++--- .../android/data/worker/ChatUploadsWorker.kt | 33 ++++++++++--------- .../android/data/worker/DownloadsWorker.kt | 33 ++++++++++--------- 8 files changed, 90 insertions(+), 51 deletions(-) diff --git a/app/src/test/java/test/mega/privacy/android/app/camerauploads/CameraUploadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/camerauploads/CameraUploadsWorkerTest.kt index e6b31aee84..f8542996ef 100644 --- a/app/src/test/java/test/mega/privacy/android/app/camerauploads/CameraUploadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/camerauploads/CameraUploadsWorkerTest.kt @@ -67,6 +67,7 @@ import mega.privacy.android.domain.entity.transfer.Transfer import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.exception.NotEnoughStorageException import mega.privacy.android.domain.exception.QuotaExceededMegaException +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.repository.FileSystemRepository import mega.privacy.android.domain.repository.TimeSystemRepository import mega.privacy.android.domain.usecase.CreateCameraUploadTemporaryRootDirectoryUseCase @@ -124,6 +125,7 @@ import org.mockito.kotlin.eq import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock import org.mockito.kotlin.never +import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import java.io.File @@ -209,6 +211,7 @@ class CameraUploadsWorkerTest { private val disableCameraUploadsUseCase: DisableCameraUploadsUseCase = mock() private val getFileByPathUseCase: GetFileByPathUseCase = mock() private val loginMutex: Mutex = mock() + private val crashReporter: CrashReporter = mock() private val foregroundInfo = ForegroundInfo(1, mock()) private val primaryNodeHandle = 1111L @@ -298,6 +301,7 @@ class CameraUploadsWorkerTest { getUploadVideoQualityUseCase = getUploadVideoQualityUseCase, disableCameraUploadsUseCase = disableCameraUploadsUseCase, getFileByPathUseCase = getFileByPathUseCase, + crashReporter = crashReporter, ) ) setupDefaultCheckConditionMocks() @@ -366,6 +370,13 @@ class CameraUploadsWorkerTest { whenever(extractGpsCoordinatesUseCase(list)).thenReturn(list) } + @Test + fun `test that crashReporter is invoked when the worker starts doing work`() = + runTest { + underTest.doWork() + verify(crashReporter, times(2)).log(any()) + } + @Test fun `test that the initial notification is displayed when the worker runs`() = runTest { underTest.doWork() diff --git a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt index beef002719..ef6aa9f425 100644 --- a/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/data/worker/ChatUploadsWorkerTest.kt @@ -36,15 +36,16 @@ import mega.privacy.android.domain.entity.transfer.TransferAppData import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType import mega.privacy.android.domain.exception.MegaException +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.repository.chat.ChatMessageRepository import mega.privacy.android.domain.usecase.chat.message.AttachNodeWithPendingMessageUseCase import mega.privacy.android.domain.usecase.chat.message.CheckFinishedChatUploadsUseCase import mega.privacy.android.domain.usecase.chat.message.UpdatePendingMessageUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase -import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.active.GetActiveTransferTotalsUseCase +import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.active.MonitorOngoingActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.paused.AreTransfersPausedUseCase import org.junit.Before @@ -53,6 +54,7 @@ import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock +import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import java.util.UUID @@ -89,6 +91,7 @@ class ChatUploadsWorkerTest { private val updatePendingMessageUseCase = mock() private val checkFinishedChatUploadsUseCase = mock() private val setForeground = mock() + private val crashReporter = mock() @Before fun init() { @@ -132,10 +135,19 @@ class ChatUploadsWorkerTest { attachNodeWithPendingMessageUseCase, updatePendingMessageUseCase, checkFinishedChatUploadsUseCase, + crashReporter, setForeground, ) } + @Test + fun `test that crashReporter is invoked when the worker starts doing work`() = + runTest { + commonStub() + underTest.doWork() + verify(crashReporter, times(2)).log(any()) + } + @Test fun `test that node is attached to chat once upload is finished`() = runTest { val finishEvent = commonStub() diff --git a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt index ed951b1f33..88e20f60f7 100644 --- a/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/transfers/DownloadsWorkerTest.kt @@ -36,6 +36,7 @@ import mega.privacy.android.domain.entity.transfer.MonitorOngoingActiveTransfers import mega.privacy.android.domain.entity.transfer.Transfer import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.usecase.qrcode.ScanMediaFileUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase @@ -54,6 +55,7 @@ import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock +import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever @@ -87,6 +89,7 @@ class DownloadsWorkerTest { private val workProgressUpdater = mock() private val scanMediaFileUseCase = mock() private val setForeground = mock() + private val crashReporter = mock() @Before fun setup() { @@ -129,6 +132,7 @@ class DownloadsWorkerTest { clearActiveTransfersIfFinishedUseCase = clearActiveTransfersIfFinishedUseCase, transfersFinishedNotificationMapper = transfersFinishedNotificationMapper, scanMediaFileUseCase = scanMediaFileUseCase, + crashReporter = crashReporter, foregroundSetter = setForeground ) } @@ -147,6 +151,14 @@ class DownloadsWorkerTest { verify(monitorTransferEventsUseCase).invoke() } + @Test + fun `test that crashReporter is invoked when the worker starts doing work`() = + runTest { + commonStub() + underTest.doWork() + verify(crashReporter, times(2)).log(any()) + } + @Test fun `test that correctActiveTransfersUseCase is invoked when the worker starts doing work`() = runTest { diff --git a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt index 05198ce05c..038be8cb85 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt @@ -170,11 +170,7 @@ class WorkManagerGatewayImpl @Inject constructor( cameraUploadWorkRequest, ).await() - Timber.d( - "CameraUploads Unique Work Status: ${ - workManager.getWorkInfosByTag(CAMERA_UPLOAD_TAG).get() - }" - ) + Timber.d("CameraUploads Unique Work enqueued") // If no CU periodic worker are currently running, cancel the worker // It will be rescheduled at the end of the one time request cancelPeriodicCameraUploadWorkRequest() @@ -210,11 +206,7 @@ class WorkManagerGatewayImpl @Inject constructor( ExistingPeriodicWorkPolicy.KEEP, cameraUploadWorkRequest ).await() - Timber.d( - "CameraUploads Periodic Work Status: ${ - workManager.getWorkInfosByTag(CAMERA_UPLOAD_TAG).get() - }" - ) + Timber.d("CameraUploads Periodic Work enqueued") } /** @@ -239,11 +231,7 @@ class WorkManagerGatewayImpl @Inject constructor( ExistingPeriodicWorkPolicy.KEEP, cuSyncActiveHeartbeatWorkRequest ).await() - Timber.d( - "CameraUpload Schedule Heartbeat Work Status: ${ - workManager.getWorkInfosByTag(HEART_BEAT_TAG).get() - }" - ) + Timber.d("CameraUploads Heartbeat Periodic Work enqueued") } /** diff --git a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt index d6e59ced1b..341a59d95f 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/AbstractTransfersWorker.kt @@ -25,6 +25,7 @@ import mega.privacy.android.data.mapper.transfer.OverQuotaNotificationBuilder import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase @@ -53,6 +54,7 @@ abstract class AbstractTransfersWorker( private val areNotificationsEnabledUseCase: AreNotificationsEnabledUseCase, private val correctActiveTransfersUseCase: CorrectActiveTransfersUseCase, private val clearActiveTransfersIfFinishedUseCase: ClearActiveTransfersIfFinishedUseCase, + private val crashReporter: CrashReporter, private val foregroundSetter: ForegroundSetter?, ) : CoroutineWorker(context, workerParams) { @@ -92,6 +94,7 @@ abstract class AbstractTransfersWorker( override suspend fun doWork() = withContext(ioDispatcher) { Timber.d("${this@AbstractTransfersWorker::class.java.simpleName} Started") + crashReporter.log("${this@AbstractTransfersWorker::class.java.simpleName} Started") val monitorJob = monitorTransferEvents(this) correctActiveTransfersUseCase(type) //to be sure we haven't missed any event before monitoring them val activeTransferTotals = getActiveTransferTotalsUseCase(type) @@ -106,6 +109,7 @@ abstract class AbstractTransfersWorker( // Signal to not kill the worker if the app is killed val foregroundInfo = getForegroundInfo(activeTransferTotals, areTransfersPausedUseCase()) foregroundSetter?.setForeground(foregroundInfo) ?: run { + crashReporter.log("${this@AbstractTransfersWorker::class.java.simpleName} start foreground") setForeground(foregroundInfo) } @@ -144,6 +148,8 @@ abstract class AbstractTransfersWorker( Timber.d("${this@AbstractTransfersWorker::class.java.simpleName}finished Failure: $lastActiveTransferTotals") Result.failure()//to retry in the future } + }.also { + crashReporter.log("${this@AbstractTransfersWorker::class.java.simpleName} Finished") } } diff --git a/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt index 27688854de..09534512c5 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt @@ -71,6 +71,7 @@ import mega.privacy.android.domain.entity.transfer.Transfer import mega.privacy.android.domain.exception.MegaException import mega.privacy.android.domain.exception.NotEnoughStorageException import mega.privacy.android.domain.exception.QuotaExceededMegaException +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.qualifier.LoginMutex import mega.privacy.android.domain.repository.FileSystemRepository @@ -181,6 +182,7 @@ class CameraUploadsWorker @AssistedInject constructor( private val getFileByPathUseCase: GetFileByPathUseCase, private val fileSystemRepository: FileSystemRepository, private val timeSystemRepository: TimeSystemRepository, + private val crashReporter: CrashReporter, @LoginMutex private val loginMutex: Mutex, ) : CoroutineWorker(context, workerParams) { @@ -290,7 +292,7 @@ class CameraUploadsWorker @AssistedInject constructor( override suspend fun doWork(): Result = withContext(ioDispatcher) { runCatching { Timber.d("Start CU Worker") - + crashReporter.log("${CameraUploadsWorker::class.java.simpleName} Started") // Signal to not kill the worker if the app is killed setForegroundAsync(getForegroundInfo()) @@ -304,7 +306,7 @@ class CameraUploadsWorker @AssistedInject constructor( canRunCameraUploads()?.let { finishedReason -> when (finishedReason) { CameraUploadsFinishedReason.MEDIA_PERMISSION_NOT_GRANTED, - CameraUploadsFinishedReason.LOCAL_PRIMARY_FOLDER_NOT_VALID + CameraUploadsFinishedReason.LOCAL_PRIMARY_FOLDER_NOT_VALID, -> abortWork( reason = finishedReason, @@ -368,7 +370,9 @@ class CameraUploadsWorker @AssistedInject constructor( return@withContext withContext(NonCancellable) { cleanResources() sendFinishedStatus(finishedReason ?: CameraUploadsFinishedReason.COMPLETED) - endWork(finishedReason ?: CameraUploadsFinishedReason.COMPLETED, restartMode) + endWork(finishedReason ?: CameraUploadsFinishedReason.COMPLETED, restartMode).also { + crashReporter.log("${CameraUploadsWorker::class.java.simpleName} Finished") + } } } @@ -891,7 +895,7 @@ class CameraUploadsWorker @AssistedInject constructor( */ private suspend fun processProgressEvent(progressEvent: CameraUploadsTransferProgress) { when (progressEvent) { - is CameraUploadsTransferProgress.ToUpload + is CameraUploadsTransferProgress.ToUpload, -> processToUploadEvent(progressEvent) is CameraUploadsTransferProgress.ToCopy, @@ -934,7 +938,7 @@ class CameraUploadsWorker @AssistedInject constructor( * @param progressEvent */ private suspend fun processToUploadEvent( - progressEvent: CameraUploadsTransferProgress.ToUpload + progressEvent: CameraUploadsTransferProgress.ToUpload, ) { updateToUploadCount( filePath = progressEvent.record.tempFilePath diff --git a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt index 4b0c63b8cc..2d384528a9 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/ChatUploadsWorker.kt @@ -16,6 +16,7 @@ import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType import mega.privacy.android.domain.entity.transfer.pendingMessageId +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.usecase.chat.message.AttachNodeWithPendingMessageUseCase import mega.privacy.android.domain.usecase.chat.message.CheckFinishedChatUploadsUseCase @@ -52,23 +53,25 @@ class ChatUploadsWorker @AssistedInject constructor( private val attachNodeWithPendingMessageUseCase: AttachNodeWithPendingMessageUseCase, private val updatePendingMessageUseCase: UpdatePendingMessageUseCase, private val checkFinishedChatUploadsUseCase: CheckFinishedChatUploadsUseCase, + crashReporter: CrashReporter, foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( - context, - workerParams, - TransferType.CHAT_UPLOAD, - ioDispatcher, - monitorTransferEventsUseCase, - handleTransferEventUseCase, - monitorOngoingActiveTransfersUseCase, - areTransfersPausedUseCase, - getActiveTransferTotalsUseCase, - overQuotaNotificationBuilder, - notificationManager, - areNotificationsEnabledUseCase, - correctActiveTransfersUseCase, - clearActiveTransfersIfFinishedUseCase, - foregroundSetter, + context = context, + workerParams = workerParams, + type = TransferType.CHAT_UPLOAD, + ioDispatcher = ioDispatcher, + monitorTransferEventsUseCase = monitorTransferEventsUseCase, + handleTransferEventUseCase = handleTransferEventUseCase, + monitorOngoingActiveTransfersUseCase = monitorOngoingActiveTransfersUseCase, + areTransfersPausedUseCase = areTransfersPausedUseCase, + getActiveTransferTotalsUseCase = getActiveTransferTotalsUseCase, + overQuotaNotificationBuilder = overQuotaNotificationBuilder, + notificationManager = notificationManager, + areNotificationsEnabledUseCase = areNotificationsEnabledUseCase, + correctActiveTransfersUseCase = correctActiveTransfersUseCase, + clearActiveTransfersIfFinishedUseCase = clearActiveTransfersIfFinishedUseCase, + crashReporter = crashReporter, + foregroundSetter = foregroundSetter, ) { override val updateNotificationId = NOTIFICATION_CHAT_UPLOAD diff --git a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt index a8f914d029..f3a5453d41 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/DownloadsWorker.kt @@ -13,6 +13,7 @@ import mega.privacy.android.data.mapper.transfer.TransfersFinishedNotificationMa import mega.privacy.android.domain.entity.transfer.ActiveTransferTotals import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.entity.transfer.TransferType +import mega.privacy.android.domain.monitoring.CrashReporter import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.usecase.qrcode.ScanMediaFileUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase @@ -46,23 +47,25 @@ class DownloadsWorker @AssistedInject constructor( private val downloadNotificationMapper: DownloadNotificationMapper, private val transfersFinishedNotificationMapper: TransfersFinishedNotificationMapper, private val scanMediaFileUseCase: ScanMediaFileUseCase, + crashReporter: CrashReporter, foregroundSetter: ForegroundSetter? = null, ) : AbstractTransfersWorker( - context, - workerParams, - TransferType.DOWNLOAD, - ioDispatcher, - monitorTransferEventsUseCase, - handleTransferEventUseCase, - monitorOngoingActiveTransfersUseCase, - areTransfersPausedUseCase, - getActiveTransferTotalsUseCase, - overQuotaNotificationBuilder, - notificationManager, - areNotificationsEnabledUseCase, - correctActiveTransfersUseCase, - clearActiveTransfersIfFinishedUseCase, - foregroundSetter, + context = context, + workerParams = workerParams, + type = TransferType.DOWNLOAD, + ioDispatcher = ioDispatcher, + monitorTransferEventsUseCase = monitorTransferEventsUseCase, + handleTransferEventUseCase = handleTransferEventUseCase, + monitorOngoingActiveTransfersUseCase = monitorOngoingActiveTransfersUseCase, + areTransfersPausedUseCase = areTransfersPausedUseCase, + getActiveTransferTotalsUseCase = getActiveTransferTotalsUseCase, + overQuotaNotificationBuilder = overQuotaNotificationBuilder, + notificationManager = notificationManager, + areNotificationsEnabledUseCase = areNotificationsEnabledUseCase, + correctActiveTransfersUseCase = correctActiveTransfersUseCase, + clearActiveTransfersIfFinishedUseCase = clearActiveTransfersIfFinishedUseCase, + crashReporter = crashReporter, + foregroundSetter = foregroundSetter, ) { override val finalNotificationId = DOWNLOAD_NOTIFICATION_ID From 8d85ed9632413c80bd1e59b2e9b1f89202c14bd6 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 11 Apr 2024 21:28:56 +1200 Subject: [PATCH 088/261] Pre-release 12.0 --- app/src/main/res/values-ar/strings.xml | 60 +++++++------- app/src/main/res/values-de/strings.xml | 42 +++++----- app/src/main/res/values-es/strings.xml | 47 ++++++----- app/src/main/res/values-fr/strings.xml | 44 +++++------ app/src/main/res/values-in/strings.xml | 41 +++++----- app/src/main/res/values-it/strings.xml | 63 ++++++++------- app/src/main/res/values-ja/strings.xml | 34 ++++---- app/src/main/res/values-ko/strings.xml | 41 +++++----- app/src/main/res/values-nl/strings.xml | 42 +++++----- app/src/main/res/values-pl/strings.xml | 46 ++++++----- app/src/main/res/values-pt/strings.xml | 38 ++++----- app/src/main/res/values-ro/strings.xml | 79 ++++++++++--------- app/src/main/res/values-ru/strings.xml | 40 +++++----- app/src/main/res/values-th/strings.xml | 41 +++++----- app/src/main/res/values-vi/strings.xml | 41 +++++----- app/src/main/res/values-zh-rCN/strings.xml | 59 +++++++------- app/src/main/res/values-zh-rTW/strings.xml | 43 +++++----- app/src/main/res/values/strings.xml | 60 +++++++------- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 34 ++++---- .../strings_device_center_feature.xml | 22 +++--- .../strings_device_center_feature.xml | 34 ++++---- .../strings_device_center_feature.xml | 28 +++---- .../strings_device_center_feature.xml | 22 +++--- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 20 ++--- .../strings_device_center_feature.xml | 30 +++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 32 ++++---- .../strings_device_center_feature.xml | 30 +++---- .../res/values-ar/strings_sync_feature.xml | 6 +- .../res/values-de/strings_sync_feature.xml | 6 +- .../res/values-es/strings_sync_feature.xml | 6 +- .../res/values-fr/strings_sync_feature.xml | 6 +- .../res/values-in/strings_sync_feature.xml | 6 +- .../res/values-it/strings_sync_feature.xml | 8 +- .../res/values-ja/strings_sync_feature.xml | 4 +- .../res/values-ko/strings_sync_feature.xml | 6 +- .../res/values-nl/strings_sync_feature.xml | 6 +- .../res/values-pl/strings_sync_feature.xml | 6 +- .../res/values-pt/strings_sync_feature.xml | 4 +- .../res/values-ro/strings_sync_feature.xml | 8 +- .../res/values-ru/strings_sync_feature.xml | 6 +- .../res/values-th/strings_sync_feature.xml | 6 +- .../res/values-vi/strings_sync_feature.xml | 6 +- .../values-zh-rCN/strings_sync_feature.xml | 8 +- .../values-zh-rTW/strings_sync_feature.xml | 6 +- .../src/main/res/values-ar/strings_shared.xml | 22 +++++- .../src/main/res/values-de/strings_shared.xml | 20 ++++- .../src/main/res/values-es/strings_shared.xml | 24 +++++- .../src/main/res/values-fr/strings_shared.xml | 30 +++++-- .../src/main/res/values-in/strings_shared.xml | 22 +++++- .../src/main/res/values-it/strings_shared.xml | 70 +++++++++------- .../src/main/res/values-ja/strings_shared.xml | 24 +++++- .../src/main/res/values-ko/strings_shared.xml | 20 ++++- .../src/main/res/values-nl/strings_shared.xml | 24 +++++- .../src/main/res/values-pl/strings_shared.xml | 22 +++++- .../src/main/res/values-pt/strings_shared.xml | 38 ++++++--- .../src/main/res/values-ro/strings_shared.xml | 62 +++++++++------ .../src/main/res/values-ru/strings_shared.xml | 20 ++++- .../src/main/res/values-th/strings_shared.xml | 20 ++++- .../src/main/res/values-vi/strings_shared.xml | 20 ++++- .../main/res/values-zh-rCN/strings_shared.xml | 20 ++++- .../main/res/values-zh-rTW/strings_shared.xml | 34 +++++--- .../src/main/res/values/strings_shared.xml | 42 +++++++--- 70 files changed, 1147 insertions(+), 860 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index dc3efce6e7..ea0559768b 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -791,7 +791,7 @@ توثيق عنوان البريد الإلكتروني - الرجاء تفقد بريدك الالكتروني للاستمرار. + تحقق من صندوق البريد الإلكتروني الخاص بك للمتابعة. خطأ حصل. الرجاء المحاولة مرة أخرى. @@ -835,7 +835,7 @@ هذا هو عنوان بريدك الإلكتروني الحالي. - هذه هي الخطوة الأخيرة لتغيير البريد الإلكتروني الخاص بك. يرجى إدخال كلمة المرور أدناه. + هذه هي الخطوة الأخيرة لتغيير عنوان بريدك الإلكتروني. أدخل كلمة المرور الخاصة بك أدناه. تغيير البريد الإلكتروني @@ -851,7 +851,7 @@ جاري الحصول على المعلومات… - عنوان بريدك الإلكتروني الجديد يحتاج إلى التحقق من صحته. يرجى التحقق من البريد الإلكتروني الخاص بك والاستمرار. + يجب التحقق من صحة عنوان بريدك الإلكتروني الجديد. تحقق من البريد الوارد لعنوان البريد الإلكتروني الجديد للمتابعة. هل تريد حذف صورة ملفك الشخصي؟ @@ -884,7 +884,7 @@ هناك الكثير من المحاولات الفاشلة لتسجيل الدخول، يرجى الانتظار لمدة ساعة. - لم يتم التحقق من هذا الحساب بعد. من فضلك تفقد بريدك الالكتروني. + لم يتم التحقق من صحة هذا الحساب حتى الآن. تحقق من صندوق البريد الإلكتروني الخاص بك. رابط المجلد غير متوفر @@ -898,7 +898,7 @@ بانتظار تأكيد البريد الإلكتروني - يُرجى التحقق من البريد الإلكتروني الخاص بك واضغط على الرابط لتأكيد حسابك. + تحقق من صندوق البريد الإلكتروني الخاص بك واتبع الرابط لتأكيد حسابك. %1$d عنصر @@ -2238,7 +2238,7 @@ اختر ملف اختر ملف - اختر ملفات + اختر ملفين اختر ملفات اختر ملفات اختر ملفات @@ -2540,7 +2540,7 @@ تمكين المكالمات - منح حق الوصول إلى دفتر العناوين الخاص بك + Allow access to your address book اكتشف جهات الاتصال بسهولة من دفتر العناوين الخاص بك على ميغا MEGA. @@ -3758,7 +3758,7 @@ لديك بالفعل اشتراك. إذا اشتريت واحدة أخرى ، فسيتم محاسبتك مرتين. لتجنب ذلك، قم بإلغاء اشتراكك الحالي بالانتقال إلى ميغا MEGA في متصفح الحاسوب المكتبي أو الهاتف المحمول. قم بزيارة مركز المساعدة للحصول على مزيد من المعلومات. - انتقل إلى الإعدادات لمنح ميغا MEGA الإذن للوصول إلى أجهزتك القريبة باستخدام البلوتوث. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. نحن غير قادرين على المضي قدماً في الفواتير. إذا كنت تستخدم تطبيقًا مزدوجًا ، فالرجاء تسجيل الدخول إلى ميغا MEGA بدونه. إذا لم يكن كذلك، فحاول الترقية من خلال متصفح الويب الخاص بك. @@ -4140,7 +4140,7 @@ هذا هو المكان الذي يتم فيه تخزين الملفات والمجلدات التي تم نسخها احتياطيًا. العناصر التي تم نسخها احتياطيًا هي ”للقراءة فقط“ لحمايتها من التعديل العرضي في السواقة السحابية الخاص بك.\nيمكنك نسخ العناصر احتياطيًا من جهاز الكمبيوتر الخاص بك إلى ميغا MEGA باستخدام تطبيق الحاسوب المكتبي الخاص بنا. - تم تعليق حساب ميغا MEGA الخاص بك بسبب الادعاءات المتكررة بانتهاكات حقوق النشر. هذا يعني أنه لا يمكنك الوصول إلى حسابك أو البيانات الموجودة فيه.\n تحقق من بريدنا الإلكتروني للحصول على مزيد من المعلومات حول كيفية تقديم إشعار مضاد. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. تم إنهاء حسابك بسبب خرق لشروط خدمة ميغا MEGA.\n لن تتمكن من استعادة الوصول إلى بياناتك المخزنة أو لن يُسمح لك بتسجيل حساب ميغا MEGA جديد. @@ -4291,9 +4291,9 @@ إزالة من الألبوم؟ - لتمكين ترفيعات الكاميرا، امنح ميغا MEGA إمكانية الوصول إلى صورك والوسائط الأخرى على جهازك. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - منح اذن الوصول + السماح بالوصول لا تمنح @@ -5895,7 +5895,7 @@ تم تحديث التطبيق - Relaunch the app + أعد تشغيل التطبيق السماح بالوصول إلى الملفات الصوتية @@ -6030,14 +6030,14 @@ يضمن النظام عرض البيانات الواردة من المرسل، وعدم التلاعب بمحتواها أثناء النقل. احصل على المزيد مع باقة برو Pro - - قم بالترقية إلى باقة برو Pro لمزيد من مساحة التخزين والكثير من الميزات الإضافية. تبدأ باقاتنا من %s في الشهر الواحد. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - بعض الميزات التي تتطلع إليها هي: + MEGA Pro plans include: - مساحة تخزين سخية - - قم بتخزين بيانات غير محدودة، بدءًا من %s + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. مشاركة تراسل المعطيات @@ -6047,7 +6047,7 @@ قم بتعيين كلمات المرور وتواريخ انتهاء الصلاحية لروابط الملفات والمجلدات. - عرض باقات برو Pro + Upgrade to Pro today %1$s يقوم بالتقديم @@ -6158,9 +6158,9 @@ يتم تجديد الاشتراكات تلقائيًا لفترات اشتراك متتالية من نفس المدة وبنفس سعر الفترة الأولية المختارة. يمكنك إيقاف التجديد التلقائي لاشتراك ميغا برو MEGA Pro الخاص بك في موعد لا يتجاوز 24 ساعة قبل استحقاق دفعة الاشتراك التالية عبر الاشتراكات في [A]غوغل بلاي Google Play[/A]. - السماح بالوصول إلى معرض الصور الخاص بك + Allow access to your Gallery - منح اذن الوصول + السماح بالوصول التحديث مطلوب @@ -6283,19 +6283,19 @@ حسنًا، فهمت ذلك - Hidden files and folders + الملفات والمجلدات المخفية - Hide important files and folders + إخفاء الملفات والمجلدات المهمة - You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + يمكنك إخفاء الملفات والمجلدات الحساسة للخصوصية. يمكنك فقط الكشف عنها إما بشكل فردي أو عن طريق عرض العناصر المخفية مؤقتًا من الإعدادات. - Exclude from Timeline + الاستبعاد من المخطط الزمني - Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + لا يمكن الوصول إلى العناصر المخفية إلا من خلال السواقة السحابية ولن تظهر في الصور أو الألبومات أو الأحداث الأخيرة. - Out of sight + بعيدًا عن الأنظار - You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + عليك أن تقرر متى تكون الملفات المخفية مرئية. هناك إعداد جديد لإظهار العناصر المخفية مؤقتًا. %1$d item hidden @@ -6304,7 +6304,7 @@ • Priority support - Upgrade to Pro to get unlimited calls + قم بالترقية إلى برو Pro للحصول على مكالمات غير محدودة وصلت مكالمتك إلى حد 60 دقيقة وانتهت. يتمتع مستخدمو برو Pro بمدة مكالمات غير محدودة ويمكنهم دعوة ما يصل إلى 1000 مشارك. @@ -6340,7 +6340,7 @@ Report your issue - Show hidden items + عرض العناصر المخفية All hidden items will be visible, but blurred to indicate their “hidden” status diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f22f32daff..36ede9dbf7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -755,7 +755,7 @@ Verifizierung der E-Mail-Adresse - Bitte sehen Sie in Ihrem Posteingang nach. + Check your email inbox to proceed. Ein Fehler ist aufgetreten, bitte versuchen Sie es erneut. @@ -799,7 +799,7 @@ Dies ist Ihre aktuelle E-Mail-Adresse. - Um Ihre E-Mail-Adresse jetzt zu ändern, geben Sie bitte Ihr Passwort ein. + This is the last step to change your email address. Enter your password below. E-Mail-Adresse ändern @@ -815,7 +815,7 @@ Informationen werden angefordert… - Ihre neue E-Mail-Adresse muss nun bestätigt werden. Bitte sehen Sie in Ihrem Posteingang nach. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Profilbild löschen? @@ -844,7 +844,7 @@ Zuviele Login-Fehlversuche. Bitte warten Sie eine Stunde. - Dieser Account wurde noch nicht validiert. Wir haben Ihnen eine E-Mail geschickt. + This account has not been validated yet. Check your email inbox. Ordnerlink nicht verfügbar @@ -858,7 +858,7 @@ Warte auf E-Mail-Bestätigung - Bitte öffnen Sie Ihre E-Mail und bestätigen Sie Ihren Account, indem Sie den entsprechenden Link antippen. + Check your email inbox and follow the link to confirm your account. %1$d Element @@ -2056,8 +2056,8 @@ Weitere - Datei auswählen - Dateien auswählen + Choose file + Choose files Ordner auswählen @@ -2324,7 +2324,7 @@ Anrufe aktivieren - Gewähren Sie Zugriff auf Ihre Kontakte + Allow access to your address book Sehen Sie, welcher Ihrer Kontakte MEGA bereits nutzt. @@ -3390,7 +3390,7 @@ Sie haben bereits ein Abonnement. Wenn Sie ein weiteres Abonnement kaufen, müssen Sie doppelt zahlen. Um dies zu vermeiden, kündigen Sie Ihr aktuelles Abonnement, indem Sie MEGA in einem Desktop- oder mobilen Webbrowser öffnen. Weitere Informationen finden Sie in unserem Hilfecenter. - Öffnen Sie die Einstellungen und erteilen Sie MEGA die Erlaubnis, über Bluetooth auf Geräte in der Nähe zuzugreifen. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. Die Abrechnung kann nicht fortgesetzt werden. Wenn Sie eine duale App verwenden, melden Sie sich eventuell ohne diese Funktion bei MEGA an. Ansonsten versuchen Sie, das Upgrade in Ihrem Webbrowser durchzuführen. @@ -3748,7 +3748,7 @@ Hier werden Ihre gesicherten Dateien und Ordner gespeichert. Die gesicherten Objekte sind schreibgeschützt, damit sie nicht versehentlich in Ihrem Cloud Drive geändert werden.\nMit unserer Desktop-App können Sie die Inhalte Ihres Computers auf MEGA sichern. - Ihr MEGA-Account wurde aufgrund von wiederholten Vorwürfen von Urheberrechtsverstößen gesperrt. Dies bedeutet, dass Sie nicht auf Ihren Account oder die darin enthaltenen Daten zugreifen können.\nIn unserer E-Mail finden Sie weitere Informationen darüber, wie Sie eine Löschbeanstandung einreichen können. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Ihr Account wurde aufgrund eines Verstoßes gegen die Nutzungsbedingungen von MEGA gekündigt.\nSie können nicht mehr auf Ihre gespeicherten Daten zugreifen und sind nicht berechtigt, einen neuen MEGA-Account zu registrieren. @@ -3879,9 +3879,9 @@ Aus Album entfernen? - Um Kamera-Uploads zu ermöglichen, gewähren Sie MEGA Zugriff auf Fotos und andere Medien auf Ihrem Gerät. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Zugriff gewähren + Zugriff freigeben Nicht gewähren @@ -5106,14 +5106,14 @@ Das System stellt sicher, dass die empfangenen Daten tatsächlich vom angezeigten Benutzer stammen und zwischenzeitlich nicht verändert wurden. Mit einem Pro-Paket bekommen Sie mehr - - Ein Pro-Paket bietet Ihnen mehr Speicherplatz und viele zusätzliche Funktionen. Unsere Pakete erhalten Sie bereits ab %s pro Monat. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Sie können sich unter anderem auf folgende Funktionen freuen: + MEGA Pro plans include: - Großzügiger Speicherplatz - - Speichern Sie beliebig viele Daten, beginnend mit %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Transfervolumen teilen @@ -5123,7 +5123,7 @@ Schützen Sie Datei- und Ordnerlinks mit Passwort und Ablaufdatum. - Pro-Pakete ansehen + Upgrade to Pro today %1$s moderiert @@ -5222,9 +5222,9 @@ Abonnements werden automatisch für den ursprünglich gewählten Abonnementzeitraum und zum gleichen Preis verlängert. Sie können die automatische Verlängerung Ihres MEGA-Pro-Abonnements bis spätestens 24 Stunden vor Fälligkeit Ihrer nächsten Abonnementzahlung in [A]Google Play[/A] unter Abonnements deaktivieren. - Gewähren Sie Zugriff auf Ihre Galerie + Allow access to your Gallery - Zugriff gewähren + Zugriff freigeben Update erforderlich diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 8ecbf68461..1d4f53fbec 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -764,7 +764,7 @@ Confirma el correo electrónico - Ve a la bandeja de entrada de tu correo electrónico para continuar. + Check your email inbox to proceed. Se ha producido un error, por favor inténtalo de nuevo. @@ -808,7 +808,7 @@ Esta es tu dirección de correo electrónico actual. - Este es el último paso para cambiar tu correo electrónico. Por favor, introduce tu contraseña. + This is the last step to change your email address. Enter your password below. Cambiar correo electrónico @@ -824,7 +824,7 @@ Obteniendo información… - Tienes que confirmar la nueva dirección de correo electrónico. Ve a tu nueva cuenta de correo electrónico para proceder. + Es necesario validar tu nueva dirección de correo electrónico. Revisa la bandeja de entrada de la nueva dirección de correo electrónico para continuar. ¿Eliminar imagen del perfil? @@ -854,7 +854,7 @@ Demasiados intentos de acceso incorréctos. Vuelve a intentarlo en una hora. - Todavía no has confirmado la cuenta. Ve a la bandeja de entrada de tu correo electrónico. + Todavía no has confirmado la cuenta. Ve a la bandeja de entrada de tu correo electrónico para proceder. Enlace de la carpeta no disponible @@ -868,7 +868,7 @@ Confirma tu cuenta - Ve a la bandeja de entrada de tu correo electrónico y pulsa en el enlace para confirmar tu cuenta. + Ve a la bandeja de entrada de tu correo y pulsa en el enlace que te hemos envíado para confirmar tu cuenta. %1$d elemento @@ -2101,9 +2101,8 @@ Más - Seleccionar archivo - Elegir archivos - Elegir archivos + Choose file + Choose files Elige carpeta @@ -2378,7 +2377,7 @@ Activar llamadas - Permitir el acceso a tus contactos + Permite el acceso a tus contactos Descubre contactos de tu agenda que tienen MEGA. @@ -3846,7 +3845,7 @@ Aquí es donde se almacenan los backups de tus archivos y carpetas. Estos backups son de “solo lectura” para protegerlos de modificaciones accidentales en tu Nube.\nPuedes crear backups en MEGA desde tu pc usando nuestra aplicación de escritorio. - Tu cuenta de MEGA ha sido suspendida debido a repetidas notificaciones de presuntas infracciones de derechos de autor. Como consecuencia, no podrás acceder a tu cuenta ni a tus datos.\nRevisa el correo electrónico que te enviamos para obtener más información sobre cómo presentar una contranotificación. + Tu cuenta de MEGA ha sido suspendida debido a repetidas notificaciones de presuntas infracciones de derechos de autor. Como consecuencia, no podrás acceder a tu cuenta ni a tus datos.\nRevisa el correo electrónico que enviamos a tu dirección de correo para obtener más información sobre cómo presentar una contranotificación. Hemos cerrado tu cuenta debido a un incumplimiento de los Términos de servicio de MEGA.\nNo podrás recuperar el acceso a tus datos ni estás autorizado a registrar una nueva cuenta de MEGA. @@ -3982,9 +3981,9 @@ ¿Eliminar del álbum? - Para activar las subidas desde la cámara, permite a MEGA acceder a tus fotos y vídeos entu dispositivo. + Para activar las subidas desde la cámara, permite a MEGA acceder a tus fotos y vídeos en tu dispositivo. - Conceder acceso + Permitir acceso No conceder @@ -5337,14 +5336,14 @@ El sistema comprueba que los datos recibidos procedan del remitente original y que su contenido no haya sido manipulado durante la transmisión. Obtén más con un plan Pro - - Amplía a un plan Pro para obtener más almacenamiento y muchas funciones adicionales. Nuestros planes comienzan desde %s al mes. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Algunas de las características que esperamos con ansias son: + MEGA Pro plans include: - Almacenamiento generoso - - Almacena datos ilimitados, a partir de %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Transferencia compartida @@ -5354,7 +5353,7 @@ Establece contraseñas y fechas de caducidad para los enlaces a carpetas y archivos. - Descubre los planes Pro + Upgrade to Pro today %1$s está presentando @@ -5456,9 +5455,9 @@ La suscripción se renueva automáticamente con la misma duración y precio elegidos inicialmente. Puedes desactivar la renovación automática de la suscripción a MEGA Pro en la página de suscripciones de [A]Google Play[/A] hasta 24 horas antes de la renovación programada. - Permitir acceso a la galería + Permite el acceso a la galería - Conceder acceso + Permitir acceso Actualización requerida @@ -5634,9 +5633,9 @@ Todos los elementos ocultos estarán visibles, pero desenfocados para indicar su estado “oculto” - Photo - Flash mode on + Foto + Modo flash activado Flash mode off Flash mode auto - Send to %1$s + Enviar a %1$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 d448c0ae00..96c3114686 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -764,7 +764,7 @@ Confirmation de l’adresse courriel - Veuillez vérifier vos courriels afin de poursuivre. + Vérifiez votre boîte de réception des courriels afin de poursuivre. Une erreur est survenue, veuillez réessayer. @@ -808,7 +808,7 @@ Ceci est votre adresse courriel existante. - Ceci est la dernière étape pour changer votre adresse courriel. Veuillez saisir votre mot de passe ci-dessous. + Ceci est la dernière étape pour changer votre adresse courriel. Saisissez votre mot de passe ci-dessous. Changer l’adresse courriel @@ -824,7 +824,7 @@ Récupération des renseignements… - Votre nouvelle adresse courriel doit être validée. Veuillez vérifier vos courriels poursuivre. + Votre nouvelle adresse courriel doit être validée. Vérifiez la boîte de réception de la nouvelle adresse courriel afin de poursuivre. Supprimer votre image de profil ? @@ -854,7 +854,7 @@ Trop de tentatives infructueuses de connexion, veuillez patienter pendant une heure. - Ce compte n’a pas encore été validé. Veuillez vérifier vos courriels. + Ce compte n’a pas encore été validé. Vérifiez votre boîte de réception des courriels. Le lien de dossier est inaccessible @@ -868,7 +868,7 @@ En attente de la confirmation par courriel - Veuillez vérifier vos courriels et toucher le lien pour confirmer votre compte. + Vérifiez votre boîte de réception des courriels et suivez le lien pour confirmer votre compte. %1$d élément @@ -2378,7 +2378,7 @@ Autoriser les appels - Accorder l’accès à votre carnet d’adresses + Autoriser l’accès à votre carnet d’adresses Trouvez facilement les contacts de votre carnet d’adresses sur MEGA. @@ -3482,7 +3482,7 @@ Vous avez déjà un abonnement. Si vous en achetez un autre, les deux vous seront facturés. Pour éviter cela, annulez votre abonnement actuel en accédant à MEGA dans un navigateur Web mobile ou pour ordinateur. Pour plus de précisions, visitez notre centre d’assistance. - Accédez aux Paramètres pour accorder à MEGA l’autorisation d’accéder par Bluetooth à vos appareils à proximité. + Accédez aux Paramètres pour autoriser MEGA à accéder par Bluetooth à vos appareils à proximité. Il nous est impossible de procéder à la facturation. Si vous utilisez une double appli, veuillez envisager de vous connecter à MEGA sans elle. Si ce n’est pas le cas, essayez de surclasser votre compte dans un navigateur Web. @@ -3846,7 +3846,7 @@ Vos fichiers et dossiers sauvegardés y sont stockés. Vos éléments sauvegardés sont en « lecture seulement » pour empêcher qu’ils soient modifiés par accident dans votre disque nuagique.Vous pouvez sauvegarder des éléments de votre ordinateur vers MEGA grâce à notre appli pour ordinateur. - Votre compte MEGA a été désactivé en raison d’allégations répétées de violation des droits d’auteur. Cela signifie que vous ne pouvez ni accéder à votre compte ni à ses données.\nPour de plus amples renseignements sur la manière de déposer un contre-avis, consultez notre courriel. + Votre compte MEGA a été désactivé en raison d’allégations répétées de violation des droits d’auteur. Cela signifie que vous ne pouvez ni accéder à votre compte ni à ses données.\nPour de plus amples renseignements sur la manière de déposer un contre-avis, vérifiez votre boîte de réception des courriels. Votre compte a été résilié en raison du non-respect des Conditions générales d’utilisation de MEGA.\nVous ne pourrez pas accéder à vos données stockées de nouveau ni être autorisé à créer un nouveau compte MEGA. @@ -3982,9 +3982,9 @@ Supprimer de l’album ? - Pour activer les Téléversements de l’appareil photo, veuillez accorder à MEGA l’accès à vos photos et aux autres médias de votre appareil. + Pour activer les téléversements de l’appareil photo, autorisez MEGA à accéder à vos photos et aux autres médias de votre appareil. - Accorder l’accès + Autoriser l’accès Ne pas accorder @@ -5337,14 +5337,14 @@ Le système garantit que les données reçues proviennent de l’expéditeur indiqué et que le contenu n’a pas été manipulé pendant le transfert. Obtenir davantage avec un abonnement Pro - - Passez à un abonnement Pro et obtenez davantage d’espace de stockage et de nombreuses fonctions supplémentaires. Nos abonnements commencent à %s par mois. + + Souscrivez un abonnement Pro pour accéder à davantage d’espace de stockage ainsi qu’aux fonctions Pro. Nos abonnements commencent à %1$s par mois. - Voici ce que vous obtiendrez : + Les abonnements MEGA Pro comprennent : - Espace de stockage généreux - - Stockez des données sans limite, à partir de %s + La plus grande flexibilité en matière d’espace de stockage + + À partir de %1$s, trouvez la réponse idéale à vos besoins de stockage. Partage des transferts @@ -5354,7 +5354,7 @@ Définissez des mots de passe et des dates d’expiration pour les liens de fichier et de dossier. - Afficher les abonnements Pro + Passer à un abonnement Pro %1$s présente @@ -5456,9 +5456,9 @@ Les abonnements sont renouvelés automatiquement pour des périodes d’abonnement successives de même durée et au même prix que la période initiale choisie. Vous pouvez désactiver le renouvellement automatique de votre abonnement MEGA Pro au plus tard 24 heures avant la date de paiement de votre prochain abonnement dans Abonnements de [A]Google Play[/A]. - Autoriser l’accès à votre galerie + Autoriser l’accès à votre Galerie - Accorder l’accès + Autoriser l’accès Une mise à jour est nécessaire @@ -5635,8 +5635,8 @@ Tous les éléments cachés seront visibles, mais flous pour indiquer leur état « caché » Photo - Flash mode on - Flash mode off - Flash mode auto + Flash activé + Flash désactivé + Flash automatique Envoyer vers %1$s \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 9ea93d6788..b89dc74c39 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -746,7 +746,7 @@ Verifikasi alamat email - Harap cek e-mail anda untuk melanjutkan. + Check your email inbox to proceed. Sebuah kesalahan terjadi, harap coba kembali. @@ -790,7 +790,7 @@ Ini adalah alamat e-mail anda yang sudah ada. - Ini adalah langkah terakhir untuk mengganti e-mail anda. Harap masukan password anda di bawah ini. + This is the last step to change your email address. Enter your password below. Ganti e-mail @@ -806,7 +806,7 @@ Mendapatkan info… - Alamat e-mail baru anda perlu di validasi. Harap cek e-mail anda untuk melanjutkan. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Hapus gambar profile anda? @@ -834,7 +834,7 @@ Terlalu banyak coba masuk yang gagal, mohon tunggu selama satu jam. - Akun ini belum divalidasi. Tolong cek e-mail anda. + This account has not been validated yet. Check your email inbox. Tautan folder tidak tersedia @@ -848,7 +848,7 @@ Menunggu konfirmasi e-mail - Silakan periksa e-mail anda dan ketuk tautan untuk mengonfirmasi akun anda. + Check your email inbox and follow the link to confirm your account. %1$d barang @@ -2011,7 +2011,8 @@ Selebihnya - Pilih Files + Choose file + Choose files Pilih folder @@ -2270,7 +2271,7 @@ Aktifkan panggilan - Berikan akses ke buku alamat anda + Allow access to your address book Temukan kontak dari buku alamat anda dengan mudah di MEGA. @@ -3298,7 +3299,7 @@ Anda sudah memiliki langganan. Jika anda membeli satu lagi, anda akan dikenakan biaya dua kali. Untuk menghindarinya, batalkan langganan anda saat ini dengan membuka MEGA di browser web desktop atau seluler. Kunjungi Pusat Bantuan kami untuk informasi lebih lanjut. - Buka Pengaturan untuk memberikan izin kepada MEGA untuk mengakses perangkat terdekat anda menggunakan Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. Kami tidak dapat melanjutkan penagihan. Jika anda menggunakan aplikasi ganda, harap pertimbangkan untuk masuk ke MEGA tanpa itu. Jika tidak, coba perbarui melalui browser web anda. @@ -3650,7 +3651,7 @@ Di sinilah file dan folder yang dicadangkan disimpan. Item yang dicadangkan “hanya-baca” untuk melindunginya agar tidak dimodifikasi secara tidak sengaja di drive cloud anda.Anda dapat mencadangkan item dari komputer anda ke MEGA menggunakan aplikasi desktop kami. - Akun MEGA anda telah ditangguhkan karena tuduhan pelanggaran hak cipta berulang kali. Ini berarti anda tidak dapat mengakses akun atau data anda di dalamnya.\nPeriksa email kami untuk informasi lebih lanjut tentang cara mengajukan pemberitahuan tanggapan. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Akun anda dihentikan karena pelanggaran Ketentuan Layanan MEGA.\nAnda tidak akan bisa mendapatkan kembali akses ke data yang disimpan atau diberi wewenang untuk mendaftarkan akun MEGA baru. @@ -3776,9 +3777,9 @@ Hapus dari album? - Untuk mengaktifkan unggahan kamera, beri MEGA akses ke foto anda dan media lain di perangkat anda. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Berikan akses + Izinkan Akses Jangan berikan @@ -4875,14 +4876,14 @@ Sistem memastikan bahwa data yang diterima berasal dari pengirim yang ditampilkan, dan isinya tidak dimanipulasi selama transit. Dapatkan lebih banyak dengan paket Pro - - Tingkatkan ke paket Pro untuk penyimpanan lebih besar dan banyak fitur tambahan. Rencana kami dimulai pada %s per bulan. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Beberapa fitur yang dinantikan adalah: + MEGA Pro plans include: - Penyimpanan murah hati - - Menyimpan data tanpa batas, mulai dari %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Berbagi transfer @@ -4892,7 +4893,7 @@ Tetapkan kata sandi dan tanggal kedaluwarsa untuk tautan file dan folder. - Lihat paket Pro + Upgrade to Pro today %1$s sedang mempresentasikan @@ -4988,9 +4989,9 @@ Langganan diperpanjang secara otomatis untuk periode berlangganan berturut-turut dengan durasi yang sama dan dengan harga yang sama dengan periode awal yang dipilih. Anda dapat mematikan perpanjangan otomatis langganan MEGA   Pro anda selambat-lambatnya 24 jam sebelum pembayaran langganan berikutnya jatuh tempo melalui Langganan di [A]Google Play[/A]. - Izinkan akses ke galeri anda + Allow access to your Gallery - Berikan akses + Izinkan Akses Diperlukan pembaruan diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index af8cfb8ede..010a5ca457 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -764,7 +764,7 @@ Verifica dell\’indirizzo email - Per favore, controlla la tua e-mail per procedere. + Controlla la tua casella di posta elettronica per procedere. È stato riscontrato un errore, per favore, riprova. @@ -808,7 +808,7 @@ Questo è il tuo indirizzo e-mail esistente. - Questo è l’ultimo passaggio per cambiare la tua e-mail. Per favore, inserisci la tua password qui sotto. + Questo è l\’ultimo passaggio per modificare il tuo indirizzo email. Inserisci la tua password qui sotto. Cambia e-mail @@ -824,7 +824,7 @@ Acquisizione delle informazioni in corso… - La tua nuova e-mail deve essere validata. Per favore, controlla la tua e-mail per procedere. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Cancellare l’immagine del profilo? @@ -854,7 +854,7 @@ Troppi tentativi falliti di effettuare il login, per favore aspetta un’ora. - Il tuo account non è ancora stato validato. Per favore, controlla la tua e-mail. + Questo account non è stato ancora verificato. Controlla la tua casella di posta elettronica. Link della cartella non disponibile @@ -868,7 +868,7 @@ In attesa della conferma dell’e-mail - Per favore, controlla la tua e-mail e poi tocca sul link per confermare il tuo account. + Controlla la tua casella di posta elettronica e segui il link per confermare il tuo account. %1$d oggetto @@ -2101,9 +2101,8 @@ Altro - Scegli file - Scegli file - Scegli file + Choose file + Choose files Scegli cartella @@ -2378,7 +2377,7 @@ Attiva chiamate - Garantisci l\’accesso alla tua Rubrica + Consenti l\’accesso alla tua rubrica Trova facilmente i tuoi contatti che hai in rubrica su MEGA. @@ -3482,7 +3481,7 @@ Già hai un abbonamento attivo. Se ne acquisti un altro, ti verranno addebitati entrambi. Per evitare ciò, annulla il tuo abbonamento corrente andando su MEGA da un browser desktop o mobile. Visita il nostro Centro d\’aiuto per maggiori informazioni. - Vai nelle Impostazioni per dare a MEGA il permesso di accedere ai tuoi dispositivi vicini utilizzando il Bluetooth. + Vai nelle Impostazioni per permettere a MEGA di accedere ai tuoi dispositivi vicini utilizzando il Bluetooth. Non riusciamo a portare a termine la fatturazione. Se stai utilizzando un\’app duplicata, per favore considera di effettuare il login su MEGA senza di essa. Altrimenti, prova ad effettuare l\’upgrade tramite un browser web. @@ -3846,7 +3845,7 @@ Questo posto è dove vengono archiviati i backup di file e cartelle. I tuoi backup sono di “sola lettura” per proteggerli da modifiche accidentali nel tuo Cloud drive.\nPuoi effettuare il backup degli oggetti dal tuo computer su MEGA utilizzando la nostra app per desktop. - Il tuo account MEGA è stato sospeso a causa di ripetute accuse di violazione di copyright. Ciò significa che non puoi accedere al tuo account o ai dati che contiene.\nControlla la nostra email per ottenere maggiori informazioni su come puoi inviare una contro-notifica. + Il tuo account MEGA è stato sospeso a causa di ripetute accuse di violazione di copyright. Questo significa che non puoi accedere al tuo account o ai dati al suo interno.\nControlla la tua casella di posta elettronica per maggiori informazioni su come puoi inviare una contro-notifica. Il tuo account MEGA è stato chiuso a causa di una violazione dei Termini di Servizio di MEGA.\nNon puoi riottenere accesso ai dati che hai archiviato o registrare un nuovo account. @@ -3982,9 +3981,9 @@ Rimuovere dall\’album? - Per attivare i caricamenti da fotocamera, permetti a MEGA l\’accesso alle tue foto e agli altri media sul tuo dispositivo. + Per attivare i Caricamenti da fotocamera, permetti a MEGA l\’accesso alle tue foto e agli altri media sul tuo dispositivo. - Garantisci l\’accesso + Permetti accesso Non permettere @@ -5214,7 +5213,7 @@ L\’app è stata aggiornata - Relaunch the app + Riavvia l\’app Permetti l\’accesso ai file audio @@ -5337,14 +5336,14 @@ Il sistema assicura che i dati ricevuti sono arrivati dal mittente mostrato, e i suoi contenuti non sono stati manipolati durante l’invio. Ottieni di più con un piano Pro - - Effettua l\’upgrade ad un piano Pro per maggiore spazio di archiviazione e molte funzioni extra. I nostri piani partono da %s al mese. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Alcune funzioni che puoi trovare sono: + MEGA Pro plans include: - Grande archivio - - Archivia dati illimitati, a partire da %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Condivisione della banda di trasferimento @@ -5354,7 +5353,7 @@ Imposta password e date di scadenza per i link di file e cartelle. - Vedi i piani Pro + Upgrade to Pro today %1$s sta presentando @@ -5456,9 +5455,9 @@ Gli abbonamenti vengono rinnovati automaticamente per periodi di abbonamento successivi della stessa durata e allo stesso prezzo del periodo iniziale scelto. Puoi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro entro 24 ore prima della scadenza del prossimo pagamento dell\’abbonamento tramite Abbonamenti nel [A]Google Play[/A]. - Permetti l\’accesso alla tua galleria + Permetti l\’accesso alla tua Galleria - Garantisci l\’accesso + Permetti accesso Aggiornamento necessario @@ -5552,7 +5551,7 @@ Scade il giorno %1$s alle ore %2$s - Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + Solo 100 partecipanti possono partecipare alla chiamata. Eventuali partecipanti aggiuntivi potranno solo inviare e ricevere messaggi. L\’organizzatore può effettuare l\’upgrade a Pro per rimuovere queste restrizioni. Only 100 participants can join the call. Any additional participants will only be able to send and read chats. Ask the organiser to remove this restriction. @@ -5592,7 +5591,7 @@ %1$d oggetti nascosti - • Priority support + • Supporto prioritario Effettua l\’upgrade a Pro per avere chiamate illimitate @@ -5626,17 +5625,17 @@ Vecchio - Trouble logging in? + Problemi con il login? - Report your issue + Segnala il tuo problema - Show hidden items + Mostra gli oggetti nascosti - All hidden items will be visible, but blurred to indicate their “hidden” status + Tutti gli oggetti nascosti saranno visibili, ma sfocati per indicare il loro status “nascosto” - Photo - Flash mode on + Foto + Flash attivo Flash mode off Flash mode auto - Send to %1$s + Invia a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 76b5ff1280..390a4b89c0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -746,7 +746,7 @@ メールアドレスの認証 - メールを確認して続行してください。 + メール受信箱を確認して続行してください。 エラーが発生しました。もう一度やり直してください。 @@ -806,7 +806,7 @@ 情報を取得中… - 新しいメールアドレスを検証する必要があります。続行するにはメールを確認してください。 + 新しいメールアドレスを検証する必要があります。新しいメールアドレスの受信箱を確認して続行してください。 プロファイル画像を削除しますか? @@ -834,7 +834,7 @@ ログインに失敗した回数が多すぎます。1時間お待ちください - このアカウントはまだ検証されていません。メールを確認してください。 + このアカウントはまだ検証されていません。メール受信箱をご確認ください。 フォルダリンクが使用できません @@ -848,7 +848,7 @@ メールの確認を待っています - 受信トレイに移動し、アカウントを確認するためにリンクをタップしてください。 + メール受信箱を確認し、リンクをクリックしてアカウントを認証してください。 %1$d項目 @@ -3298,7 +3298,7 @@ すでにサブスクリプションをお持ちです。もう一つご購入されると、二重課金になります。これを避けるには、デスクトップまたはモバイルのウェブブラウザでMEGAにアクセスし、現在のサブスクリプションを解約してください。詳しくは、ヘルプセンターをご覧ください。 - 設定から、MEGAにBluetoothを使用してお近くの機器にアクセスする権限を与えてください。 + 「設定」に移動し、MEGAがBluetoothを使用してお近くのデバイスにアクセスすることを許可してください。 ご請求を進めることができません。デュアルアプリをお使いの方は、デュアルアプリなしでのログインをご検討ください。そうでない場合は、ウェブブラウザでアップグレードしてみてください。 @@ -3650,7 +3650,7 @@ ここにバックアップしたファイルやフォルダが保存されます。バックアップされたアイテムは、クラウドドライブ内で誤って変更されないように「読み取り専用」になります。\n当社のデスクトップアプリケーションを使用して、パソコンからMEGAにアイテムをバックアップすることができます。 - 度重なる著作権侵害の申し立てにより、あなたのMEGAアカウントは停止されました。これは、アカウントまたはアカウント内のデータにアクセスできないことを意味します。\n異議申し立て通知を提出する方法の詳細については、メールを確認してください。 + 度重なる著作権侵害の申し立てにより、あなたのMEGAアカウントは停止されました。これは、アカウントまたはアカウント内のデータにアクセスできないことを意味します。\n異議申し立て通知を提出する方法の詳細については、メール受信箱を確認してください。 MEGAのご利用規約違反により、あなたのアカウントは停止されました。\n保存されたデータへのアクセスを回復したり、MEGAアカウントを新規登録したりすることはできません。 @@ -4875,14 +4875,14 @@ このシステムは、受信したデータが表示された送信者からのものであり、そのコンテンツが転送中に操作されていないことを保証します。 Proプランでさらに充実 - - Proプランにアップグレードしていただくと、より多くのストレージと多くの追加機能をご利用いただけます。当社のプランは月額%sから始まります。 + + Proプランにアップグレードしていただくと、ストレージが増え、各種Pro機能をご利用いただけるようになります。プランは月額%1$sからご利用いただけます - ご期待いただける機能としては次のようなものがあります。 + MEGA Pro plans include: - 豊富なストレージ - - 無制限にデータを保管できます(%sから)。 + 究極のストレージの柔軟性 + + %1$sから始めて、お客様のストレージのニーズに最適なものを見つけてください。 転送共有 @@ -4892,7 +4892,7 @@ ファイルとフォルダのリンクのパスワードと有効期限を設定できます。 - Proプランを見る + 今すぐProにアップグレード %1$sさんがプレゼン中です @@ -5159,8 +5159,8 @@ 非表示の項目はすべて表示されますが、「非表示」ステータスを示すためにぼかされます 写真 - Flash mode on - Flash mode off - Flash mode auto - Send to %1$s + フラッシュモードオン + フラッシュモードオフ + フラッシュモード自動 + %1$sに送信 \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 69356008e1..bd13ee1cc2 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -746,7 +746,7 @@ 이메일 주소 인증 - 진행하려면 이메일을 확인하세요. + Check your email inbox to proceed. 오류가 발생했습니다, 다시 시도하세요. @@ -790,7 +790,7 @@ 이것은 현재 당신의 이메일 주소입니다. - 이메일을 변경하는 마지막 단계입니다. 아래에 암호를 입력하세요. + This is the last step to change your email address. Enter your password below. 이메일 변경 @@ -806,7 +806,7 @@ 정보 받는 중… - 새 이메일 주소를 검증해야합니다. 진행하려면 이메일을 확인하세요, + Your new email address needs to be validated. Check the inbox of the new email address to proceed. 프로필 사진을 삭제할까요? @@ -834,7 +834,7 @@ 로그인 시도 실패가 너무 많습니다, 1시간 동안 기다려주세요. - 이 계정은 아직 확인되지 않았습니다. 이메일을 확인하세요. + This account has not been validated yet. Check your email inbox. 폴더 링크가 사용불가입니다 @@ -848,7 +848,7 @@ 이메일 인증 대기중 - 계정을 확인하려면 이메일을 확인하고 링크를 탭하세요. + Check your email inbox and follow the link to confirm your account. %1$d개의 항목 @@ -2011,7 +2011,8 @@ 더 보기 - 파일 선택 + Choose file + Choose files 폴더 선택 @@ -2270,7 +2271,7 @@ 통화 활성화 - 주소록에 대한 접근 허가 + Allow access to your address book MEGA에서 당신의 주소록에 있는 지인들을 쉽게 찾으세요. @@ -3298,7 +3299,7 @@ 당신에게 이미 구독이 있습니다. 만약 다른 것을 구매하면 두번 결제됩니다. 이것을 피하려면, MEGA를 데스크톱 또는 모바일 웹 브라우저에서 접속하여 현재 구독을 취소하세요. 자세한 정보는 우리의 도움 센터를 방문하세요. - 설정에 가서 MEGA가 Bluetooth를 사용하여 주변 기기에 접근할 수 있도록 허용해주세요. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. 결제를 처리할 수 없습니다. 만약 이중 앱을 사용하고 있다면, 사용하지 않은 상태에서 MEGA에 로그인 하세요. 만약 아니라면 웹 브라우저를 통해 업그레이드 하세요. @@ -3650,7 +3651,7 @@ 이곳은 백업된 파일과 폴더가 보관되는 곳입니다. 백업된 항목은 실수로 클라우드 드라이브에서 수정되는 것을 방지하지 위해 “읽기 전용”이 됩니다.\n데스크톱 앱을 이용하여 컴퓨터에서 MEGA로 항목들을 백업할 수 있습니다. - 당신의 MEGA 계정이 반복된 저작권 침해 혐의로 인해 정지 되었습니다. 이것은 당신의 계정이나 그 안의 데이터에 접근할 수 없다는 뜻입니다.\n이의 제기를 접수하는 방법에 대한 자세한 정보는 이메일을 확인하세요. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. 당신의 계정이 MEGA의 이용 약관 위반으로 삭제되었습니다.\n저장된 데이터에 대한 접근 또는 새 MEGA 계정을 등록하는 것이 금지됩니다. @@ -3776,9 +3777,9 @@ 사진첩에서 제거할까요? - 카메라 업로드를 활성화 하려면, MEGA가 당신의 장치의 사진과 다른 미디어에 접근할 수 있도록 허용해주세요. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - 접근 허가 + 접근 허용 허용하지 않음 @@ -4875,14 +4876,14 @@ 시스템이 표기된 발송자로부터 데이터를 수신하였으며, 그 내용이 전송 중 조작되지 않았음을 보증합니다. Pro 요금제로 더 받기 - - 더 많은 저장소와 추가 기능을 위해 Pro 요금제로 업그레이드 하세요. 요금제는 월 %s부터 시작합니다. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - 기대할 수 있는 몇 가지 기능은 다음과 같습니다: + MEGA Pro plans include: - 넉넉한 저장소 - - 무제한 데이터 보관, %s부터 시작 + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. 전송 공유 @@ -4892,7 +4893,7 @@ 파일과 폴더 링크에 암호와 만료일을 설정 - Pro 요금제 보기 + Upgrade to Pro today %1$s 님이 발표 중입니다 @@ -4988,9 +4989,9 @@ 구독은 처음 선택한 기간과 같은 기간 그리고 같은 가격으로 연속적으로 자동 갱신 됩니다. MEGA Pro 구독 자동 갱신을 [A]Google Play[/A]의 구독을 통해 다음 구독의 결제 24시간 전에 취소할 수 있습니다. - 갤러리에 접근 허용 + Allow access to your Gallery - 접근 허가 + 접근 허용 업데이트가 필요합니다 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 85373f451d..d788f91705 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -755,7 +755,7 @@ E-mail adres verificatie - Controleer uw e-mail om door te gaan. + Check your email inbox to proceed. Er is een fout opgetreden, probeer nogmaals. @@ -799,7 +799,7 @@ Dit is uw bestaande e-mailadres. - Dit is de laatste stap om uw e-mail te wijzigen. Vul alstublieft hieronder uw wachtwoord in. + This is the last step to change your email address. Enter your password below. E-mailadres wijzigen @@ -815,7 +815,7 @@ Wachten op informatie… - Uw nieuwe e-mailadres moet worden bevestigd. Controleer alstublieft uw e-mail om door te gaan. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Uw profielfoto verwijderen? @@ -844,7 +844,7 @@ Teveel mislukte pogingen om in te loggen, alstublieft wacht voor een uur. - Dit account is nog niet gevalideerd. Controleer uw e-mail. + This account has not been validated yet. Check your email inbox. Link naar map is niet beschikbaar @@ -858,7 +858,7 @@ In afwachting op e-mail bevestiging - Check uw e-mail en tik op de link om uw account te bevestigen. + Check your email inbox and follow the link to confirm your account. %1$d item @@ -2056,8 +2056,8 @@ Meer - Kies Bestand - Kies Bestanden + Choose file + Choose files Kies map @@ -2324,7 +2324,7 @@ Oproepen inschakelen - Geef toegang tot uw adresboek + Allow access to your address book Ontdek gemakkelijk contacten uit uw adresboek op MEGA. @@ -3390,7 +3390,7 @@ U heeft al een abonnement. Koopt u er nog één, dan betaalt u twee keer. Om dit te voorkomen, zegt u uw huidige abonnement op door naar MEGA te gaan in een desktop- of mobiele webbrowser. Bezoek ons ​​Helpcentrum voor meer informatie. - Ga naar Instellingen om MEGA toestemming te geven voor toegang tot dichtbijzijnde apparaten via Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. We kunnen de facturering niet voortzetten. Als u een dubbele applicatie gebruikt, overweeg dan om zonder in te loggen op MEGA. Als dit niet het geval is, probeer dan te upgraden via uw webbrowser. @@ -3748,7 +3748,7 @@ Dit is waar uw back-upbestanden en mappen worden opgeslagen. Uw back-upitems zijn “alleen-lezen” om te voorkomen dat ze per ongeluk worden gewijzigd in uw clouddrive.\nU kunt een back-up maken van items op uw computer naar MEGA met behulp van onze desktop-applicatie. - Uw MEGA-account is opgeschort vanwege herhaalde beschuldigingen van inbreuk op het auteursrecht. Dit betekent dat u geen toegang heeft tot uw account of de gegevens daarin.\nBekijk onze e-mail voor meer informatie over het indienen van een tegenmelding. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Uw account is beëindigd vanwege een schending van MEGA\’s Algemene Voorwaarden.\nU kunt geen toegang meer krijgen tot uw opgeslagen gegevens of worden geautoriseerd om een ​​nieuw MEGA-account te registreren. @@ -3879,9 +3879,9 @@ Verwijderen van album? - Om camera uploads in te schakelen, geef MEGA toegang tot uw foto\’s en andere media op uw apparaat. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Toegang verlenen + Toegang Toestaan Niet toestaan @@ -5106,14 +5106,14 @@ Het systeem zorgt ervoor dat de ontvangen gegevens afkomstig zijn van de weergegeven afzender en dat de inhoud ervan tijdens de verzending niet is gemanipuleerd. Krijg meer met een Pro abonnement - - Upgrade naar een Pro-abonnement voor meer opslagruimte en veel extra functies. Onze plannen beginnen bij %s per maand. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Enkele functies om naar uit te kijken zijn: + MEGA Pro plans include: - Gulle opslag - - Bewaar onbeperkt data, vanaf %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Overdracht deling @@ -5123,7 +5123,7 @@ Stel wachtwoorden en vervaldata in voor bestands- en mapkoppelingen. - Bekijk Pro abonnementen + Upgrade to Pro today %1$s is aan het presenteren @@ -5222,9 +5222,9 @@ Abonnementen worden automatisch verlengd voor opeenvolgende abonnementsperioden van dezelfde duur en tegen dezelfde prijs als de gekozen initiële periode. U kunt de automatische verlenging van uw MEGA   Pro-abonnement uiterlijk 24 uur voordat uw volgende abonnementsbetaling verschuldigd is, uitschakelen via Abonnementen in [A]Google Play[/A]. - Geef toegang tot uw gallerij + Allow access to your Gallery - Toegang verlenen + Toegang Toestaan Update vereist diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index c8f5047da3..b053e8d11d 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -773,7 +773,7 @@ Weryfikacja adresu e-mail - Sprawdź swój e-mail aby kontynuować. + Check your email inbox to proceed. Wystąpił błąd, spróbuj ponownie. @@ -817,7 +817,7 @@ Jest to Twój dotychczasowy adres e-mail. - To jest ostatni moment na zmianę adresu e-mail. Wprowadź swoje hasło poniżej. + This is the last step to change your email address. Enter your password below. Zmień e-mail @@ -833,7 +833,7 @@ Pobieranie danych… - Twój nowy adres e-mail musi zostać zweryfikowany. Sprawdź swoją skrzynkę odbiorczą aby kontynuować. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Usunąć zdjęcia profilowe? @@ -864,7 +864,7 @@ Zbyt wiele nieudanych prób logowania. Zaczekaj godzinę. - To konto nie zostało jeszcze zweryfikowane. Proszę sprawdzić e-mail. + This account has not been validated yet. Check your email inbox. Link do katalogu jest niedostępny @@ -878,7 +878,7 @@ Oczekiwanie na potwierdzenia konta - Sprawdź swoją wiadomość e-mail i kliknij link, aby potwierdzić swoje konto. + Check your email inbox and follow the link to confirm your account. %1$d element @@ -2146,10 +2146,8 @@ Więcej - Wybierz plik - Wybierz pliki - Wybierz pliki - Wybierz pliki + Choose file + Choose files Wybierz katalog @@ -2432,7 +2430,7 @@ Włącz połączenia - Udzielanie dostępu do książki adresowej + Allow access to your address book Łatwo odkrywaj kontakty z książki adresowej na MEGA. @@ -3574,7 +3572,7 @@ Masz już wykupioną subskrypcję. Jeśli kupisz kolejną, zostaniesz obciążony podwójną opłatą. Aby tego uniknąć, anuluj swoją obecną subskrypcję, wchodząc na stronę MEGA w przeglądarce internetowej na komputerze lub w telefonie komórkowym. Odwiedź nasze Centrum Pomocy, aby uzyskać więcej informacji. - Przejdź do Ustawień, aby udzielić MEGA pozwolenia na dostęp do pobliskich urządzeń poprzez Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. Nie możemy kontynuować rozliczenia. Jeśli używasz podwójnej aplikacji, rozważ możliwość zalogowania się do MEGA bez niej. Jeśli nie, spróbuj dokonać aktualizacji przez przeglądarkę internetową. @@ -3944,7 +3942,7 @@ W tym miejscu są przechowywane pliki i foldery, których kopie zapasowe zostały utworzone. Kopie zapasowe są dostępne „tylko do odczytu”, co chroni je przed przypadkową modyfikacją na dysku w chmurze.Kopię zapasową elementów z komputera możesz utworzyć na MEGA za pomocą naszej aplikacji desktopowej. - Twoje konto MEGA zostało zawieszone z powodu powtarzających się zarzutów naruszenia praw autorskich. Oznacza to, że nie możesz uzyskać dostępu do swojego konta ani danych na nim zawartych. \nSprawdź naszą wiadomość e-mail, aby uzyskać więcej informacji na temat składania kontr-zawiadomienia. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Twoje konto zostało zamknięte z powodu naruszenia Warunków świadczenia usług MEGA. \nNie będziesz w stanie odzyskać dostępu do przechowywanych danych ani uzyskać autoryzacji do rejestracji nowego konta MEGA. @@ -4085,9 +4083,9 @@ Usunąć z albumu? - Aby umożliwić wysyłanie aparatem, udostępnij MEGA dostęp do swoich zdjęć i innych mediów w urządzeniu. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Przyznaj dostęp + Udostępnik Nie przyznawaj @@ -5568,14 +5566,14 @@ System zapewnia, że otrzymane dane pochodzą od nadawcy, a ich zawartość nie została zmanipulowana podczas przesyłania. Zyskaj więcej dzięki planowi Pro - - Uaktualnij do planu Pro, aby uzyskać więcej miejsca na dane i wiele dodatkowych funkcji. Nasze plany zaczynają się od %s miesięcznie. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Niektóre funkcje, których można się spodziewać, to: + MEGA Pro plans include: - Pojemna pamięć - - Przechowuj nieograniczone dane, zaczynając od %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Współdzielenie transferu @@ -5585,7 +5583,7 @@ Ustawianie haseł i dat wygaśnięcia dla łączy do plików i katalogów. - Zobacz plany Pro + Upgrade to Pro today %1$s prezentuje @@ -5690,9 +5688,9 @@ Subskrypcje są odnawiane automatycznie na kolejne okresy subskrypcji o tym samym czasie trwania i w tej samej cenie, co wybrany okres początkowy. Użytkownik może wyłączyć automatyczne odnawianie subskrypcji MEGA Pro nie później niż 24 godziny przed terminem płatności kolejnej subskrypcji za pośrednictwem Subskrypcji w [A]Google Play[/A]. - Zezwalaj na dostęp do swojej galerii + Allow access to your Gallery - Przyznaj dostęp + Udostępnik Wymagana aktualizacja @@ -5868,7 +5866,7 @@ Zgłoś swój problem - Show hidden items + Pokaż ukryte elementy All hidden items will be visible, but blurred to indicate their “hidden” status diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 448e1dcb6d..6c00cc17b7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -764,7 +764,7 @@ Comprovação de email - Por favor, verifique seu e-mail para continuar. + Acesse o seu email para continuar. Ocorreu um erro. Por favor, tente novamente. @@ -808,7 +808,7 @@ Este é o seu e-mail atual. - Este é o último passo para alterar o seu e-mail. Por favor, digite a sua senha abaixo. + Este é o último passo para alterar o seu email: digite a sua senha abaixo. Alterar email @@ -824,7 +824,7 @@ Obtendo informação… - Seu novo endereço de e-mail precisa ser validada. Por favor, verifique seu e-mail para prosseguir. + O seu novo email precisa ser confirmado. Acesse a conta do seu novo email para continuar. Você quer deletar a sua foto de perfil? @@ -854,7 +854,7 @@ Muitas tentativas de login incorretas. Por favor, aguarde uma hora. - Esta conta ainda não foi confirmada. Por favor, verifique o seu e-mail. + Esta conta ainda não foi confirmada. Acesse o seu email. O link da pasta não está disponível @@ -868,7 +868,7 @@ Esperando confirmação por e-mail - Por favor, verifique o seu e-mail e toque no link para confirmar a sua conta. + Acesse o seu email e clique no link para confirmar a sua conta. %1$d item @@ -2102,8 +2102,8 @@ Escolher arquivo - Enviar arquivos - Enviar arquivos + Escolher arquivos + Escolher arquivos Escolher pasta @@ -3846,7 +3846,7 @@ É aqui que os seus arquivos e as pastas de backup são armazenados. Os itens de backup são “somente leitura” para protegê-los de alterações acidentais na sua Nuvem de arquivos. \nVocê pode fazer o backup de itens do seu computador para o MEGA usando o nosso aplicativo para desktop. - A sua conta no MEGA foi suspensa devido a repetidas alegações de infrações de direitos autorais, o que significa que você não poderá acessar a sua conta, nem os dados armazenados.\nEnviamos um email informações sobre como enviar uma contra-notificação. + A sua conta no MEGA foi suspensa devido a repetidas alegações de infrações de direitos autorais, e portanto você não poderá acessar a sua conta ou os dados armazenados. \nAcesse o seu email para obter mais informações sobre como enviar uma contranotificação. A sua conta foi encerrada devido a uma infração dos Termos de serviço do MEGA.\nVocê não poderá recuperar o acesso aos seus dados armazenados, nem está autorizado a registrar uma nova conta no MEGA. @@ -5337,14 +5337,14 @@ O sistema garante que os dados recebidos sejam do remetente exibido, e que o conteúdo não tenha sido manipulado durante o trânsito. Obtenha mais com um plano Pro - - Faça o upgrade a um plano Pro para obter mais armazenamento e muitos recursos adicionais. O nossos planos são a partir de %s por mês. + + Faça o upgrade a um plano Pro para obter mais armazenamento e acessar recursos exclusivos. O nossos planos são a partir de %1$s por mês - Alguns dos recursos incluídos são: + Os planos Pro do MEGA incluem: - Amplo espaço de armazenamento - - Armazene uma quantidade ilimitada de dados, a partir de %s. + Flexibilidade de armazenamento máxima + + Encontre o melhor opção para as suas necessidades de armazenamento a partir de %1$s. Compartilhamento de transferência @@ -5354,7 +5354,7 @@ Adicione senhas e datas de validade para links de arquivos e de pastas. - Conheça os planos Pro + Fazer o upgrade a um plano Pro %1$s está apresentando @@ -5456,7 +5456,7 @@ As assinaturas serão renovadas automaticamente por períodos sucessivos com a mesma duração e pelo mesmo preço do período inicial. Você pode desativar a renovação automática da sua assinatura Pro do MEGA até 24 horas antes do vencimento do próximo pagamento nas Assinaturas da [A]Google Play[/A]. - Permitir o acesso à sua galeria + Permitir o acesso à sua Galeria Permitir acesso @@ -5635,8 +5635,8 @@ Todos os itens ocultos ficarão visíveis, mas desfocados para indicar o seu status “oculto” Foto - Flash mode on - Flash mode off - Flash mode auto + Flash ativo + Flash desativado + Flash automático Enviar a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a193878902..f4ae3ae843 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -764,7 +764,7 @@ Verificarea adresei de e-mail - Vă rugăm să verificați adresa de e-mail pentru a continua. + Verificați căsuța dvs. de e-mail pentru a continua. A apărut o eroare, încercați din nou. @@ -808,7 +808,7 @@ Aceasta este adresa ta de e-mail existentă. - Acesta este ultimul pas pentru a vă schimba e-mailul. Vă rugăm să introduceți parola mai jos. + Acesta este ultimul pas pentru a vă schimba adresa dvs. de e-mail. Introduceți parola mai jos. Modifică e-mailul @@ -824,7 +824,7 @@ Se obțin informații… - Noua dvs. adresă de e-mail trebuie validată. Vă rugăm să verificați adresa de e-mail pentru a continua. + Noua dvs. adresă de e-mail trebuie validată. Verificați căsuța de e-mail a noii adrese de e-mail pentru a continua. Îți ștergi poza de profil? @@ -854,7 +854,7 @@ Prea multe încercări eșuate de autentificare, vă rugăm să așteptați o oră. - Acest cont nu a fost încă validat. Vă rugăm să verificați adresa de e-mail. + Acest cont nu a fost încă validat. Verificați căsuța de e-mail. Linkul folderului indisponibil @@ -868,7 +868,7 @@ În așteptarea confirmării e-mailului - Vă rugăm să verificați adresa de e-mail și să atingeți linkul pentru a vă confirma contul. + Verificați căsuța de e-mail și urmați linkul pentru a vă confirma contul. %1$d element @@ -2101,9 +2101,9 @@ Mai multe - Alege un fișier - Alege fișiere - Alege fișiere + Alegeţi fişierul + Alegeți fișiere + Alegeți fișiere Alege un folder @@ -2378,7 +2378,7 @@ Activează apelurile - Acordă accesul la agenda de adrese + Permiteți accesul la agenda dvs. de adrese Descoperă cu ușurință contactele din agenda de adrese pe MEGA. @@ -3482,7 +3482,7 @@ Aveți deja un abonament. Dacă cumpărați altul, veți fi taxat de două ori. Pentru a evita acest lucru, anulați abonamentul curent accesând MEGA într-un browser web desktop sau mobil. Vizitați Centrul nostru de ajutor pentru mai multe informații. - Mergi la Setări pentru a-i acorda lui MEGA permisiunea de a accesa dispozitivele din apropiere folosind Bluetooth. + Accesați Setări pentru a permite MEGA permisiunea de a accesa dispozitivele din apropiere utilizând Bluetooth. Nu putem continua cu facturarea. Dacă utilizați o aplicație duală, vă rugăm să luați în considerare conectarea la MEGA fără ea. Dacă nu, încercați să actualizați prin browserul dvs. web. @@ -3846,7 +3846,7 @@ Aici sunt stocate fișierele și folderele pentru care s-a făcut backup. Elementele pentru care s-a făcut backup sunt de tip „numai citire” pentru a le proteja împotriva modificării accidentale în Unitatea cloud.\nPoți face backupuri ale elementelor de pe calculator pe MEGA folosind aplicația noastră desktop. - Contul dvs. MEGA a fost suspendat din cauza acuzațiilor repetate de încălcare a drepturilor de autor. Aceasta înseamnă că nu vă puteți accesa contul sau datele din cadrul acestuia.\nConsultați e-mailul nostru pentru mai multe informații despre cum să depuneți o contranotificare. + Contul dvs. MEGA a fost suspendat din cauza acuzațiilor repetate de încălcare a drepturilor de autor. Aceasta înseamnă că nu vă puteți accesa contul sau datele din acesta.\nVerificați căsuța de e-mail pentru mai multe informații despre cum să depuneți o contranotificare. Contul dvs. a fost desființat din cauza unei încălcări a Termenilor de utilizare a serviciului MEGA.\nNu veți putea recâștiga accesul la datele stocate sau nu veți putea fi autorizat să înregistrați un nou cont MEGA. @@ -3982,9 +3982,9 @@ Elimini din album? - Pentru a activa încărcările camerei, acordați MEGA acces la fotografiile și alte suporturi media de pe dispozitiv dvs.. + Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe dispozitiv. - Acordă acces + Activează accesul Nu acorda @@ -5214,7 +5214,7 @@ Aplicația a fost actualizată - Relaunch the app + Relansați aplicația Permiteți accesul la fișiere audio @@ -5337,14 +5337,14 @@ Sistemul se asigură că datele primite sunt într-adevăr de la expeditorul specificat, iar conținutul său nu a fost manipulat în timpul tranzitului. Obțineți mai mult cu un abonament Pro - - Treceți la un abonament Pro pentru mai mult spațiu de stocare și o mulțime de funcții suplimentare. Planurile noastre încep de la %s o lună. + + Treceți la un abonament Pro și obțineți mai mult spațiu de stocare și acces la funcțiile Pro. Planurile încep de la %1$s o lună - Lată ce obțineți: + MEGA Pro plans include: - Spațiu de stocare generos - - Stocați date nelimitate, începând de la %s. + Flexibilitate maximă în spațiu de stocare + + Începând de la %1$s, găsiți potrivirea perfectă pentru nevoile dvs. de stocare. Partajarea transferurilor @@ -5354,7 +5354,7 @@ Setați parolele și datele de expirare pentru linkurile de fișiere și folder. - Vezi abonamentele Pro + Upgradeați la un abonament Pro %1$s prezintă @@ -5456,9 +5456,9 @@ Abonamentele sunt reînnoite automat pentru perioade succesive de abonament cu aceeași durată și la același preț ca perioada inițială aleasă. Puteți dezactiva reînnoirea automată a abonamentului MEGA Pro cu cel mult 24 de ore înainte de scadența următoarei plăți a abonamentului prin Abonamente în [A]Google Play[/A]. - Permiteți accesul la galeria dvs. + Permiteți accesul la Galeria dvs. - Acordă acces + Activează accesul Actualizarea necesară @@ -5552,7 +5552,7 @@ Expiră la %1$s la ora %2$s - Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + Doar 100 de participanți se pot alătura apelului. Orice participanți suplimentari vor putea trimite și primi mesaje. Persoana care organizează apelul poate încheia un abonament Pro pentru a ridica aceste restricții. Doar 100 de participanți se pot alătura apelului. Orice participanți suplimentari vor putea trimite și citi doar chat-uri. Solicitați organizatorului să elimine această restricție. @@ -5576,22 +5576,23 @@ Ascundeți fișierele și folderele importante - You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + Puteți ascunde fișierele și folderele sensibile pentru confidențialitate. Numai dvs. le puteți dezvălui, fie individual, fie prin afișarea temporară a elementelor ascunse din setări. - Exclude from Timeline + Excludeți din vizualizarea cronologică Elementele ascunse sunt accesibile numai prin Unitatea cloud și nu vor apărea în Fotografii, Albume sau Recente. Invizibile - You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + Dvs. decideți când sunt vizibile fișierele ascunse. Există o nouă setare pentru a afișa temporar elementele ascunse. - %1$d item hidden - %1$d items hidden + %1$d element ascuns + %1$d elemente ascunse + %1$d de elemente ascunse - • Priority support + • Asistență prioritară Upgradați la Pro pentru a primi apeluri nelimitate @@ -5625,17 +5626,17 @@ Mai vechi - Trouble logging in? + Aveți probleme de conectare? - Report your issue + Raportați problema dvs. - Show hidden items + Afișați elementele ascunse - All hidden items will be visible, but blurred to indicate their “hidden” status + Toate elementele ascunse vor fi vizibile, dar încețoșate pentru a indica starea lor „ascunse” - Photo - Flash mode on - Flash mode off - Flash mode auto - Send to %1$s + Fotografie + Flash activat + Flash dezactivat + Flash automat + Trimiteți la %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index be909d59e6..41850f8601 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -773,7 +773,7 @@ Подтверждение электронной почты - Проверьте электронную почту для продолжения. + Check your email inbox to proceed. Произошла ошибка, попробуйте снова. @@ -817,7 +817,7 @@ Это ваш существующий адрес электронной почты. - Остался один шаг до смены адреса электронной почты. Введите пароль. + This is the last step to change your email address. Enter your password below. Изменение электронной почты @@ -833,7 +833,7 @@ Получение информации… - Новый адрес электронной почты нужно подтвердить. Проверьте почтовый ящик, чтобы продолжить. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Удалить изображение профиля? @@ -864,7 +864,7 @@ Слишком много неудачных попыток войти. Пожалуйста, подождите час. - Аккаунт ещё не подтверждён. Проверьте почту. + This account has not been validated yet. Check your email inbox. Ссылка на папку недоступна @@ -878,7 +878,7 @@ Ожидание подтверждения по электронной почте - Проверьте электронную почту и перейдите по ссылке для подтверждения аккаунта. + Check your email inbox and follow the link to confirm your account. %1$d элемент @@ -2146,10 +2146,8 @@ Больше - Выбор файла - Выбор файлов - Выбор файлов - Выбор файлов + Choose file + Choose files Выбрать папку @@ -2432,7 +2430,7 @@ Разрешить звонки - Откройте доступ к адресной книге + Allow access to your address book Легко находите контакты из своей адресной книги в MEGA. @@ -3574,7 +3572,7 @@ У вас уже есть подписка. Если вы оформите ещё одну, вы будете платить дважды. Чтобы избежать этого, отмените текущую подписку, зайдя в MEGA в настольном или мобильном веб-браузере. Посетите наш справочный центр для получения дополнительной информации. - Перейдите в «Настройки», чтобы предоставить MEGA разрешение на доступ к устройствам поблизости с помощью Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. Мы не можем продолжить выставление счёта. Если вы используете клонированное приложение, попробуйте войти в MEGA без него. Если нет, попробуйте улучшить аккаунт через веб-браузер. @@ -3944,7 +3942,7 @@ Здесь хранятся резервные копии файлов и папок. Резервные копии доступны «только для чтения», чтобы защитить их от случайного изменения на Облачном диске.\nВы можете делать резервные копии элементов со своего компьютера в MEGA с помощью нашего настольного приложения. - Ваш аккаунт MEGA был заблокирован из-за неоднократных обвинений в нарушении авторских прав. Это означает, что вы не можете получить доступ к аккаунту или данным в нём.\nДля получения дополнительной информации о том, как подать встречное заявление, проверьте электронную почту. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Ваш аккаунт был удалён из-за нарушения Условий использования MEGA.\nВы не сможете восстановить доступ к своим сохранённым данным или зарегистрировать новый аккаунт MEGA. @@ -4085,7 +4083,7 @@ Удалить из альбома? - Чтобы включить загрузку из камеры, предоставьте MEGA доступ к фотографиям и другим медиафайлам на вашем устройстве. + To enable camera uploads, allow MEGA access to your photos and other media on your device. Открыть доступ @@ -5568,14 +5566,14 @@ Система гарантирует, что данные получены от отображаемого отправителя, и их содержимое не было изменено во время пересылки. Получите больше с планом Pro - - Перейдите на план Pro, чтобы получить больше места и множество дополнительных функций. Наши планы стоят от %s в месяц. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Некоторые особенности, которые вас ждут: + MEGA Pro plans include: - Выгодный объём - - Храните неограниченный объём данных, начиная с %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Обмен объёмами передач @@ -5585,7 +5583,7 @@ Устанавливайте пароли и сроки действия для ссылок на файлы и папки. - Посмотреть + Upgrade to Pro today %1$s выступает @@ -5690,7 +5688,7 @@ Подписки продлеваются автоматически на последующие периоды той же продолжительности и по той же цене, что и первоначально выбранный период. Вы можете отключить автоматическое продление подписки MEGA Pro не позднее чем за 24 часа до следующего платежа за подписку на странице «Подписки» в [A]Google Play[/A]. - Разрешите доступ к галерее + Allow access to your Gallery Открыть доступ diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 1451faf735..62570fa017 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -746,7 +746,7 @@ การยืนยันที่อยู่อีเมล - โปรดตรวจสอบอีเมลของคุณเพื่อดำเนินการต่อ + Check your email inbox to proceed. เกิดข้อผิดพลาด กรุณาลองอีกครั้ง @@ -790,7 +790,7 @@ นี่คืออีเมลที่คุณมีอยู่ - นี่เป็นขั้นตอนสุดท้ายในการเปลี่ยนอีเมลของคุณ กรุณากรอกรหัสผ่านของคุณด้านล่าง + This is the last step to change your email address. Enter your password below. เปลี่ยนอีเมล @@ -806,7 +806,7 @@ กำลังรับข้อมูล… - ต้องมีการตรวจสอบที่อยู่อีเมลใหม่ของคุณ กรุณาตรวจสอบอีเมลของคุณเพื่อดำเนินการต่อ + Your new email address needs to be validated. Check the inbox of the new email address to proceed. ลบรูปโปรไฟล์ของคุณหรือไม่ @@ -834,7 +834,7 @@ มีการเข้าสู่ระบบไม่สำเร็จหลายครั้งเกินไป กรุณารอประมาณหนึ่งชั่วโมง - บัญชีนี้ยังไม่ผ่านการตรวจสอบ กรุณาตรวจสอบอีเมลของคุณ + This account has not been validated yet. Check your email inbox. ลิงก์โฟลเดอร์ยังไม่พร้อมใช้งาน @@ -848,7 +848,7 @@ กำลังรอการยืนยันทางอีเมล - กรุณาตรวจสอบอีเมลของคุณและแตะลิงก์เพื่อยืนยันบัญชีของคุณ + Check your email inbox and follow the link to confirm your account. %1$d รายการ @@ -2011,7 +2011,8 @@ เพิ่มเติม - เลือกไฟล์ + Choose file + Choose files เลือกโฟลเดอร์ @@ -2270,7 +2271,7 @@ เปิดใช้งานการโทร - ให้สิทธิ์เข้าถึงสมุดรายชื่อของคุณ + Allow access to your address book ค้นหารายชื่อจากสมุดรายชื่อของคุณได้อย่างง่ายดายบน MEGA @@ -3298,7 +3299,7 @@ คุณมีการสมัครใช้งานอยู่แล้ว หากคุณซื้ออีกรายการหนึ่ง คุณจะถูกเรียกเก็บเงินสองครั้ง เพื่อหลีกเลี่ยงปัญหานี้ ให้ยกเลิกการสมัครใช้งานปัจจุบันของคุณโดยไปที่ MEGA ในเบราว์เซอร์เดสก์ท็อปหรือมือถือ เยี่ยมชมศูนย์ช่วยเหลือของเราเพื่อศึกษาข้อมูลเพิ่มเติม - ไปที่การตั้งค่าเพื่อให้สิทธิ์ MEGA เข้าถึงอุปกรณ์บลูทูธที่อยู่บริเวณใกล้เคียง + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. เราไม่สามารถดำเนินการเรียกเก็บเงินได้ หากคุณกำลังใช้แอปที่ติดตั้งแบบซ้ำกันอยู่ กรุณาพิจารณาลงชื่อเข้าใช้ MEGA โดยไม่ใช้แอปนี้ หากไม่เป็นเช่นนั้น ให้ลองอัปเกรดผ่านเว็บเบราว์เซอร์ของคุณแทน @@ -3650,7 +3651,7 @@ นี่คือที่จัดเก็บไฟล์และโฟลเดอร์สำหรับสำรองข้อมูล รายการที่สำรองไว้ของคุณเป็นแบบ “อ่านอย่างเดียว” เพื่อป้องกันไม่ให้ถูกแก้ไขโดยไม่ได้ตั้งใจในไดรฟ์ระบบคลาวด์ของคุณ\nคุณสามารถสำรองข้อมูลไฟล์ต่าง ๆ ได้จากคอมพิวเตอร์ของคุณไปยัง MEGA โดยใช้แอปเดสก์ท็อปของเรา - บัญชี MEGA ของคุณถูกระงับเนื่องจากมีข้อกล่าวหาการละเมิดลิขสิทธิ์ซ้ำหลายครั้ง ซึ่งหมายความว่าคุณไม่สามารถเข้าถึงบัญชีหรือข้อมูลภายในได้ \nกรุณาตรวจสอบอีเมลของเราเพื่อข้อมูลเพิ่มเติมเกี่ยวกับวิธีการยื่นข้อโต้แย้ง + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. บัญชีของคุณถูกยุติการใช้งานเนื่องจากละเมิดเงื่อนไขการให้บริการของ MEGA\nคุณจะไม่สามารถเข้าถึงข้อมูลที่เก็บไว้หรือลงทะเบียนบัญชี MEGA ใหม่ได้อีกต่อไป @@ -3776,9 +3777,9 @@ นำออกจากอัลบั้มหรือไม่ - หากต้องการเปิดใช้งานการอัปโหลดจากกล้อง ต้องให้สิทธิ์ MEGA เข้าถึงรูปภาพและสื่ออื่น ๆ บนอุปกรณ์ของคุณ + To enable camera uploads, allow MEGA access to your photos and other media on your device. - ให้สิทธิ์เข้าถึง + อนุญาตให้เข้าถึง ไม่ต้องให้สิทธิ์ @@ -4875,14 +4876,14 @@ ระบบตรวจสอบความถูกต้องของข้อมูลที่ได้รับ โดยตรวจสอบว่าข้อมูลนั้นมาจากผู้ส่งที่ถูกต้อง และเนื้อหาของข้อมูลนั้นไม่ได้ถูกแก้ไขในระหว่างการขนส่ง รับสิทธิประโยชน์เพิ่มเติมด้วยการอัปเกรดเป็นแผน Pro - - อัปเกรดเป็นแผน Pro เพื่อเพิ่มพื้นที่เก็บข้อมูลและคุณสมบัติพิเศษอีกมากมาย แผนของเราเริ่มต้นที่ %s ต่อเดือน + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - คุณสมบัติที่คุณจะได้สัมผัสอย่างเต็มอิ่มคือ: + MEGA Pro plans include: - พื้นที่เก็บข้อมูลจุได้ไม่อั้น - - เก็บข้อมูลได้ไม่จำกัด เริ่มต้นที่ %s + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. แชร์การถ่ายโอนของคุณให้คนอื่นได้ @@ -4892,7 +4893,7 @@ ลิงก์ไฟล์และโฟลเดอร์สามารถตั้งรหัสผ่านและวันหมดอายุได้ - ดูแผน Pro + Upgrade to Pro today %1$s กำลังนำเสนออยู่ @@ -4988,9 +4989,9 @@ เมื่อสมัครใช้งานแล้ว ระบบจะต่ออายุสมาชิกให้อัตโนมัติตามระยะเวลาและราคาเดิมที่เลือกไว้ คุณสามารถยกเลิกการต่ออายุสมาชิก MEGA Pro อัตโนมัติได้ไม่เกิน 24 ชั่วโมงก่อนวันครบกำหนดชำระค่าสมาชิกครั้งต่อไปผ่านระบบสมาชิกใน [A]Google Play[/A] - อนุญาตให้เข้าถึงแกลเลอรี่ของคุณ + Allow access to your Gallery - ให้สิทธิ์เข้าถึง + อนุญาตให้เข้าถึง จำเป็นต้องได้รับการอัปเดต diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 528ec41fc1..28baf4115b 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -746,7 +746,7 @@ Xác thực địa chỉ email - Xin kiểm tra hộp thư e-mail để thục hiện bước kế tiếp. + Check your email inbox to proceed. Phát sinh lỗi, xin thử lại sau. @@ -790,7 +790,7 @@ Đây là địa chỉ e-mail hiện tại của bạn. - Đây là bước cuối cùng để hoàn tất việc thay đổi địa chỉ e-mail. Xin vui lòng nhập mật khẩu ở dưới. + This is the last step to change your email address. Enter your password below. Đổi e-mail @@ -806,7 +806,7 @@ Đang lấy thông tin… - Địa chỉ e-mail của bạn cần phải được xác minh. Vui lòng kiểm tra hộp thư e-mail để thực hiện bước kế tiếp. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Xóa ảnh đại diện? @@ -834,7 +834,7 @@ Đăng nhập sai quá nhiều lần, xin chờ một tiếng đồng hồ rồi thử lại. - Tài khoản này chưa được kích hoạt. Xin vui lòng kiểm tra hộp thư e-mail. + This account has not been validated yet. Check your email inbox. Liên kết thư mục bất khả dụng @@ -848,7 +848,7 @@ Đang chờ xác nhận địa chỉ e-mail - Vui lòng kiểm tra hộp thư e-mail và chạm vào đường liên kết để xác nhận tài khoản của bạn. + Check your email inbox and follow the link to confirm your account. %1$d mục @@ -2011,7 +2011,8 @@ Thêm nữa - Chọn Tệp + Choose file + Choose files Chọn thư mục @@ -2270,7 +2271,7 @@ Thực hiện cuộc gọi - Cấp quyền cho phép truy cập vào sổ danh bạ + Allow access to your address book Dễ dàng tìm thêm người để kết nối trên MEGA từ sổ danh bạ của bạn. @@ -3298,7 +3299,7 @@ Bạn đã có đăng ký một gói dịch vụ rồi. Nếu bạn mua một cái khác, bạn sẽ bị tính phí gấp đôi. Để tránh khỏi điều này, hãy hủy đăng ký gói hiện tại bằng cách vào MEGA với trình duyệt web trên máy tính hoặc điện thoại. Tới trang Thư Viện Hướng Dẫn để có thêm chi tiết. - Đi tới phần Thiết Đặt và cấp quyền cho MEGA truy cập vào các thiết bị gần bạn thông qua Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. Chúng tôi không tiến hành được việc thanh toán. Nếu quý khách đang sử dụng ứng dụng kép, vui lòng đăng nhập vào MEGA mà không có ứng dụng đó. Còn không, hãy thử nâng cấp thông qua trình duyệt web. @@ -3650,7 +3651,7 @@ Đây là thư mục chứa các tệp tin và thư mục đã được sao lưu dự phòng. Các mục lưu dự phòng là dạng “chỉ-được-xem” để phòng tránh bị chỉnh sửa trong Ổ Mây của bạn.Bạn có thể lưu dự phòng dữ liệu của mình từ máy tính lên MEGA bằng cách sử dụng App MEGA cho Máy Tính. - Tài khoản MEGA của quý vị đã bị đình chỉ do đã nhiều lần bị cáo buộc vi phạm bản quyền. Điều này có nghĩa là quý vị không được phép truy cập tài khoản của mình hoặc bất cứ dữ liệu bên trong. \nKiểm tra thư email chúng tôi đã gửi tới quý vị để biết thêm thông tin và về cách gửi đơn phản đối. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Tài khoản của quý vị đã bị chấm dứt do vi phạm Điều Khoản Dịch Vụ của MEGA.\nQuý vị sẽ không thể lấy lại quyền truy cập vào dữ liệu đã được lưu trữ của mình hoặc được phép đăng ký tài khoản MEGA mới. @@ -3776,9 +3777,9 @@ Loại bỏ khỏi album? - Để bật đăng tải camêra, cấp quyền cho MEGA truy cập vào kho hình ảnh và các nội dung phương tiện khác có trong thiết bị của bạn. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Cấp quyền + Cho phép quyền truy cập Không cấp quyền @@ -4875,14 +4876,14 @@ Hệ thống đảm bảo rằng các dữ liệu nhận được từ người gửi sẽ hiển thị rõ ràng, và nội dung bên trong không bị chế tác trong quá trình truyền tải. Nhận được nhiều hơn với gói Pro - - Nâng cấp lên gói Pro để có thêm không gian lưu trữ và nhiều tính năng bổ sung. Các gói của chúng tôi có giá từ %s mỗi tháng. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Một số tính năng được mong đợi là: + MEGA Pro plans include: - Không gian hào phóng - - Lưu trữ dữ liệu không giới hạn, bắt đầu từ %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Chia sẻ lượng truyền tải @@ -4892,7 +4893,7 @@ Đặt mật khẩu và ngày hết hạn cho các đường liên kết tệp tin và thư mục. - Xem các gói Pro + Upgrade to Pro today %1$s hiện đang trình bày @@ -4988,9 +4989,9 @@ Các gói đăng ký được tự động gia hạn cho khoảng thời gian đăng ký kế tiếp có cùng thời lượng và ở cùng mức giá như khoảng thời gian ban đầu đã chọn. Bạn có thể tắt tự động gia hạn gói đăng ký MEGA Pro của mình không được ít hơn 24 giờ trước khi đến kỳ hạn thanh toán cho gói đăng ký tiếp theo thông qua trang Gói thuê bao trong [A]Google Play[/A]. - Cho phép truy cập vào thư viện hình ảnh của bạn + Allow access to your Gallery - Cấp quyền + Cho phép quyền truy cập Cần phải cập nhật diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 53ab5473fb..5223ac4375 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -746,7 +746,7 @@ 电子邮件地址验证 - 请确认您的电子邮箱以继续。 + Check your email inbox to proceed. 发生错误,请再试一次。 @@ -790,7 +790,7 @@ 这是您当前的电子邮件地址。 - 这是更改您电子邮件地址的最后一步。请在下方输入您的密码。 + This is the last step to change your email address. Enter your password below. 更改电子邮件地址 @@ -806,7 +806,7 @@ 正在获取信息… - 您的新电子邮件地址需要经过验证。请检查您的电子邮件以继续。 + Your new email address needs to be validated. Check the inbox of the new email address to proceed. 是否删除您的头像? @@ -834,7 +834,7 @@ 尝试登录次数过多,请一小时后再试。 - 此帐户尚未验证。请检查您的电子邮件。 + This account has not been validated yet. Check your email inbox. 文件夹链接不可用 @@ -848,7 +848,7 @@ 正在等待电子邮件确认 - 请检查您的电子邮件并点击链接以确认您的帐户。 + 查看您的电子邮件收件箱并跟随链接确认您的帐户。 %1$d个项目 @@ -2011,7 +2011,8 @@ 更多 - 选择文件 + Choose file + Choose files 选择文件夹 @@ -2270,7 +2271,7 @@ 启用通话 - 授予访问您的通讯录的权限 + Allow access to your address book 从您的MEGA通讯录中轻松发现联系人。 @@ -3298,7 +3299,7 @@ 您当前已经有一个订阅。若购买另一个,您将被收取两次费用。为避免重复订阅,请在电脑或手机网页浏览器中登录MEGA以取消您当前的订阅。访问我们的帮助中心了解更多信息。 - 前往“设置”并授予MEGA使用蓝牙访问附近设备的权限。 + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. 我们无法处理您的购买。如果您正在使用双应用程序,请尝试退出一个后登录MEGA。否则,请尝试通过网络浏览器进行升级。 @@ -3650,7 +3651,7 @@ 这是存储您备份的文件和文件夹的地方。您备份的项目是“只读”以保护它们不会在您的云驱动器中被意外修改。您可以使用我们的桌面应用程序将计算机中的项目备份到MEGA。 - 由于多次指控侵犯版权,您的MEGA帐户已被暂停。这意味着您无法访问自己的帐户或其中的数据。\n请查看我们的电子邮件,了解有关如何提交抗辩通知的更多信息。 + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. 由于违反MEGA的服务条款,您的帐户已被终止。\n您将无法重新获得对存储数据的访问权限,也无法被授权注册新的MEGA账户。 @@ -3776,9 +3777,9 @@ 要从相册中移除吗? - 要启用相机上传,请授予MEGA访问您设备上的照片和其他媒体的权限。 + To enable camera uploads, allow MEGA access to your photos and other media on your device. - 授予权限 + 允许访问 不授予 @@ -4875,14 +4876,14 @@ 我们的系统确保接收到的数据来自显示的发送人,并且其内容在传输过程中不会被篡改。 通过Pro方案获得更多权益 - - 升级到Pro方案可获得更多存储空间和更多额外功能。我们的会员方案从每月%s起。 + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - 一些值得期待的功能是: + MEGA Pro plans include: - 大容量存储空间 - - 存储无限数据,从%s起。 + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. 传输流量共享 @@ -4892,7 +4893,7 @@ 为文件和文件夹链接设置密码和到期日期。 - 查看Pro方案 + Upgrade to Pro today %1$s正在展示 @@ -4988,9 +4989,9 @@ 订阅将自动续订,续订周期与初始选择的周期相同,并且以相同的价格进行续订。您可以在下一次订阅付款到期前24小时以内,通过[A]Google Play[/A]订阅界面关闭MEGA Pro订阅的自动续订功能。 - 允许访问您的图库 + Allow access to your Gallery - 授予权限 + 允许访问 需要更新 @@ -5098,19 +5099,19 @@ 好的,明白了 - Hidden files and folders + 隐藏的文件和文件夹 - Hide important files and folders + 隐藏重要的文件和文件夹 - You can conceal sensitive files and folders for privacy. Only you can reveal them, either individually or by temporarily displaying hidden items from the settings. + 您可以隐藏敏感的文件和文件夹以保护隐私。只有您可以单独或通过设置中的暂时显示隐藏项目来显示它们。 - Exclude from Timeline + 从时间线中排除 - Hidden items are only accessible through the Cloud drive and will not appear in your Photos, Albums or Recents. + 隐藏的项目只能通过云盘访问,不会出现在您的照片、相册或近期照片中。 - Out of sight + 隐藏 - You decide when hidden files are visible. There is a new setting to show hidden items temporarily. + 您可以决定何时显示隐藏的文件。有一个新的设置可以暂时显示隐藏的项目。 %1$d item hidden @@ -5119,7 +5120,7 @@ • Priority support - Upgrade to Pro to get unlimited calls + 升级到Pro版即可获得无限通话 您的通话已达到60分钟限制并已结束。Pro会员用户具有无限通话时长,并且可以邀请多达1000名参与者。 @@ -5155,7 +5156,7 @@ Report your issue - Show hidden items + 显示隐藏的项目 All hidden items will be visible, but blurred to indicate their “hidden” status diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 06de33448c..6080b46c57 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -746,7 +746,7 @@ 電子郵件地址驗證 - 請確認您的電子信箱以繼續。 + Check your email inbox to proceed. 發生錯誤,請再試一次。 @@ -790,7 +790,7 @@ 這是您目前的電子郵件地址。 - 這是變更您電子信箱的最後一步了。請於下方輸入您的密碼。 + This is the last step to change your email address. Enter your password below. 更改電子信箱 @@ -806,7 +806,7 @@ 正在取得資訊⋯ - 您的新電子郵件地址需要驗證確認。請至您的電子信箱收信並進行驗證。 + Your new email address needs to be validated. Check the inbox of the new email address to proceed. 要刪除您的個人資料相片嗎? @@ -834,7 +834,7 @@ 嘗試登入失敗的次數太多,請稍候一個小時後再試。 - 此帳戶尚未驗證啟用。請至你的電子信箱收信確認。 + 此帳戶尚未通過驗證。請檢查您的電子郵件收件匣。 資料夾連結無法使用 @@ -848,7 +848,7 @@ 等待電子郵件確認中 - 請檢查您的電子郵件,然後點擊信件中的連結來確認您的帳戶。 + 檢查您的電子郵件收件匣,並點選連結以確認您的帳戶。 %1$d個項目 @@ -2011,7 +2011,8 @@ 更多 - 選擇檔案 + Choose file + Choose files 選擇資料夾 @@ -2270,7 +2271,7 @@ 啟用通話 - 授予對您通訊錄的存取權限 + 允許存取您的通訊錄 輕易的在您通訊錄中找到有在使用MEGA的聯絡人。 @@ -3298,7 +3299,7 @@ 您目前已經有一個訂閱。如果再購買,您將被收取兩次費用。為避免重複訂閱,請在電腦版或手機版網頁瀏覽器中登入MEGA來取消您目前的訂閱。造訪我們的幫助中心瞭解更多訊息。 - 請至設定授予MEGA使用藍牙連線存取您附近裝置的權限。 + 前往設定並授予MEGA使用藍牙存取附近裝置的權限。 我們無法處理您的付款。如果您正在使用雙開應用程式,請嘗試不要使用它來登入MEGA。否則請透過網頁瀏覽器進行升級。 @@ -3650,7 +3651,7 @@ 這是您備份檔案和資料夾存放的地方。您備份的項目是「唯讀」的,以避免它們在您的雲端硬碟中被意外竄改。您可以使用我們桌面應用程式將您電腦中的項目備份到MEGA。 - 由於多次指控侵犯版權,您的MEGA帳戶已被暫停。這意味著您無法存取您的帳戶或其中的資料。\n請查看我們的電子郵件,瞭解有關如何提交反對通知的更多資訊。 + 由於多次侵犯版權的指控,您的MEGA帳戶已被暫停。這意味著您無法存取您的帳戶或當中的資料。\n檢查您的電子郵件收件匣,瞭解有關如何提交反對通知的更多資訊。 您的帳戶由於違反MEGA的服務條款而被終止。\n您將無法重新存取您儲存的資料,也無法被授權註冊新的MEGA帳戶。 @@ -3776,9 +3777,9 @@ 要從相簿中移除嗎? - 若要啟用相機上傳,請授予MEGA存取您裝置上的相片和其它媒體的權限。 + 若要啟用相機上傳,請允許予MEGA存取您裝置上的相片和其它媒體。 - 授予權限 + 允許存取 不要授予 @@ -4875,14 +4876,14 @@ 我們的系統能確保收到的資料是來自所顯示的發送人,且其內容在傳輸過程中不會被篡改。 透過Pro方案獲得更多功能 - - 升級到Pro方案可獲得更多儲存空間和更多額外的功能。我們的會員方案從每月%s起。 + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - 一些值得期待的功能: + MEGA Pro plans include: - 大容量儲存空間 - - 儲存無限資料,從%s起。 + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. 傳輸流量共享 @@ -4892,7 +4893,7 @@ 為檔案和資料夾連結設定密碼和到期日期。 - 查看Pro方案 + Upgrade to Pro today %1$s正在展示 @@ -4990,7 +4991,7 @@ 允許存取您的相簿 - 授予權限 + 允許存取 需要更新 @@ -5159,8 +5160,8 @@ 可看到所有隱藏的項目,但會模糊顯示以表示其「隱藏」狀態 拍照 - Flash mode on + 閃光模式開啟 Flash mode off Flash mode auto - Send to %1$s + 發送至%1$s \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f35b4c520d..30ca7ab4df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -755,7 +755,7 @@ Email address verification - Please check your email to proceed. + Check your email inbox to proceed. An error occurred, please try again. @@ -799,7 +799,7 @@ This is your existing email address. - This is the last step to change your email. Please enter your password below. + This is the last step to change your email address. Enter your password below. Change email address @@ -815,7 +815,7 @@ Getting info… - Your new email address needs to be validated. Please check your email to proceed. + Your new email address needs to be validated. Check the inbox of the new email address to proceed. Delete your profile picture? @@ -844,7 +844,7 @@ Too many failed attempts to log in, please wait for an hour. - This account has not been validated yet. Please check your email. + This account has not been validated yet. Check your email inbox. Folder link unavailable @@ -858,7 +858,7 @@ Awaiting email confirmation - Please check your email and tap the link to confirm your account. + Check your email inbox and follow the link to confirm your account. %1$d item @@ -2056,8 +2056,8 @@ More - Choose File - Choose Files + Choose file + Choose files Choose folder @@ -2324,7 +2324,7 @@ Enable calls - Grant access to your address book + Allow access to your address book Easily discover contacts from your address book on MEGA. @@ -3390,7 +3390,7 @@ You already have a subscription. If you buy another one, you will be charged twice. To avoid this, cancel your current subscription by going to MEGA in a desktop or mobile web browser. Visit our Help Centre for more information. - Go to Settings to grant MEGA permission to access your nearby devices using Bluetooth. + Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. We are unable to proceed with the billing. If you are using a dual app, please consider logging in to MEGA without it. If not, try to upgrade through your web browser. @@ -3748,7 +3748,7 @@ This is where your backed up files and folders are stored. Your backed up items are “read-only” to protect them from being accidentally modified in your Cloud drive.\nYou can back up items from your computer to MEGA using our desktop app. - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck our email for more information on how to file a counter-notice. + Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. Your account was terminated due to a breach of MEGA’s Terms of Service.\nYou will not be able to regain access to your stored data or be authorised to register a new MEGA account. @@ -3879,9 +3879,9 @@ Remove from album? - To enable camera uploads, grant MEGA access to your photos and other media on your device. + To enable camera uploads, allow MEGA access to your photos and other media on your device. - Grant access + Allow access Don’t grant @@ -5112,14 +5112,14 @@ The system ensures that the data received is from the sender displayed, and its content has not been manipulated during transit. Get more with a Pro plan - - Upgrade to a Pro plan for more storage and lots of extra features. Our plans start at %s a month. + + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month - Some features to look forward to are: + MEGA Pro plans include: - Generous storage - - Store unlimited data, starting from %s. + Ultimate storage flexibility + + Starting from %1$s, find the perfect fit for your storage needs. Transfer sharing @@ -5129,7 +5129,7 @@ Set passwords and expiry dates for file and folder links. - View Pro plans + Upgrade to Pro today %1$s is presenting @@ -5227,10 +5227,10 @@ Subscription details Subscriptions are renewed automatically for successive subscription periods of the same duration and at the same price as the initial period chosen. You can switch off the automatic renewal of your MEGA Pro subscription no later than 24 hours before your next subscription payment is due via Subscriptions in [A]Google Play[/A]. - - Allow access to your gallery - - Grant access + + Allow access to your Gallery + + Allow access Update required @@ -5364,7 +5364,7 @@ Upgrade to Pro to get unlimited calls - Your call reached the 60 minute limit and has ended. Pro users have unlimited calls and up to 1000 participants. + Your call reached the 60-minute limit and has ended. Pro users have unlimited call duration and can invite up to 1000 participants. Upgrade now @@ -5397,18 +5397,14 @@ Trouble logging in? Report your issue + + Show hidden items + + All hidden items will be visible, but blurred to indicate their “hidden” status Photo - Flash mode on - Flash mode off - Flash mode auto - Send to %1$s - - Show hidden items - - All hidden items will be visible, but blurred to indicate their “hidden” status \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml index a4530d1585..90a508f5e0 100644 --- a/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml @@ -59,7 +59,7 @@ لا يوجد خطأ في المزامنة - لا يمكن لميغا MEGA مزامنة هذا المجلد أو نسخه احتياطيًا لأن نظام الملفات على جهازك غير مدعوم. + MEGA can’t sync or backup this folder because the file system on your device is not supported لا يمكن مزامنة المجلد الذي اخترته @@ -71,33 +71,33 @@ تم الوصول إلى الحد الأقصى لمساحة التخزين. - تم الوصول إلى الحد الأقصى لمساحة التخزين. غير قادر على مزامنة هذا المجلد أو نسخه احتياطيًا نظرًا لانتهاء باقتك. + Unable to sync or back up this folder as your plan has expired - لا يمكن مزامنة المجلد لأن المستخدم الذي شارك هذا المجلد قد وصل إلى الحد المتاح من مساحة التخزين الخاصة به. + Folder can’t be synced as the user who shared this folder has reached their storage quota لا يمكن تحديد موقع المجلد الموجود في ميغا MEGA نظرًا لأنه تم نقله أو حذفه، أو ربما ليس لديك إذن للوصول إليه. - لا يمكن مزامنة المجلد لأنه مجلد مشترك بدون إذن وصول كامل. + Folder can’t be synced as it’s a shared folder without full access - لا يمكن مزامنة الملفات الموجودة في هذا المجلد أو نسخها احتياطيًا. ستحتاج إلى إعادة تمكين المزامنة أو النسخ الاحتياطي من تطبيق الحاسوب المكتبي. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - لا يمكن مزامنة المجلد لأنه يحتوي بالفعل على مجلدات متزامنة. + Folder can’t be synced as it already contains synced folders - لا تستطيع ميغا MEGA مزامنة مجلدات VirtualBox أو نسخها احتياطيًا. + MEGA can’t sync or back up VirtualBox folders - غير قادر على مزامنة هذا المجلد أو عمل نسخة احتياطية منه لأنه تم حظر الحساب. + Unable to sync or back up this folder as the account has been blocked - حدثت مشكلة في مزامنة هذا المجلد أو نسخه احتياطيًا. حاول مرة أخرى في وقت لاحق. إذا استمرت المشكلة، تواصل مع قسم الدعم. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. تمت إعادة تحميل الحساب. لم يتم تطبيق أي تحديثات فائتة على النسخ الاحتياطية أو المزامنات الخاصة بك. - تم إيقاف المزامنة أو النسخ الاحتياطي حيث يبدو أنك قمت بتسجيل الخروج من تطبيق الحاسوب المكتبي. قم بتسجيل الدخول مرة أخرى عبر تطبيق الحاسوب المكتبي واستأنف المزامنة أو النسخ الاحتياطي. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. غير متوفر لا يمكن تحديد موقع المجلد الموجود في السواقة الخارجية. - يوجد بالفعل مجلد متزامن في نفس المسار. + يوجد بالفعل مجلد تمت مزامنته على نفس المسار فشلت عملية إعادة التسمية. @@ -105,7 +105,7 @@ تعذرت قراءة تكوين المزامنة. حاول مرة أخرى لاحقًا أو تحقق من أذونات المجلد. - مسار سواقة المزامنة غير معروف. + Sync folder location is unknown الفاصل الزمني للفحص غير صالح. تحقق من إعداد الفاصل الزمني للفحص وحاول مرة أخرى. @@ -125,17 +125,17 @@ حدث خطأ ما. - لا يمكن مزامنة المجلد أو نسخه احتياطيًا لأن مجلد ميغا MEGA موجود في سلة المحذوفات. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin لا يمكن تحديد موقع المجلد الموجود في جهازك الآن، حاول مرة أخرى لاحقًا. لا يمكن تحديد موقع المجلد في جهازك - حدثت مشكلة أثناء مزامنة هذا المجلد أو نسخه احتياطيًا بسبب التغييرات التي تم إجراؤها على مجلد ميغا MEGA. أوقف المزامنة أو النسخ الاحتياطي وحاول إعداده مرة أخرى في تطبيق الحاسوب المكتبي أو تواصل مع قسم الدعم. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. حدثت مشكلة في مزامنة هذا المجلد أو نسخه احتياطيًا. أوقف المزامنة أو النسخ الاحتياطي وحاول إعداده مرة أخرى في تطبيق الحاسوب المكتبي أو تواصل مع قسم الدعم. - لا يمكن مزامنة المجلد لأنه داخل مجلد متزامن. + Folder can’t be synced as it’s already inside a synced folder تم تعطيل ترفيعات الكاميرا @@ -157,7 +157,7 @@ لا يوجد اتصال بالإنترنت - لا يمكن مزامنة الملفات الموجودة في هذا المجلد أو نسخها احتياطيًا. ستحتاج إلى إعادة تمكين المزامنة أو النسخ الاحتياطي من تطبيق الحاسوب المكتبي. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. لم يتم إعداد أي شيء حتى الآن diff --git a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml index 34259f215f..322eae9b87 100644 --- a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA kann diesen Ordner nicht synchronisieren oder sichern, da das Dateisystem Ihres Geräts nicht unterstützt wird. + MEGA can’t sync or backup this folder because the file system on your device is not supported Der gewählte Ordner kann nicht synchronisiert werden @@ -71,33 +71,33 @@ Der belegte Speicherplatz hat das Limit erreicht. - Dieser Ordner kann nicht synchronisiert oder gesichert werden, da Ihr Paket abgelaufen ist. + Dieser Ordner kann nicht synchronisiert oder gesichert werden, da Ihr Paket abgelaufen ist - Der Ordner kann nicht synchronisiert werden, da der freigebende Benutzer sein Speicherplatzlimit erreicht hat. + Folder can’t be synced as the user who shared this folder has reached their storage quota Der Ordner wurde auf MEGA nicht gefunden, da er verschoben oder gelöscht wurde oder Sie keinen Zugriff auf ihn haben. - Der Ordner kann nicht synchronisiert werden, da es sich um einen freigegebenen Ordner handelt, auf den Sie keinen Vollzugriff haben. + Folder can’t be synced as it’s a shared folder without full access - Die Dateien in diesem Ordner können nicht synchronisiert oder gesichert werden. Sie müssen die Synchronisierung bzw. das Backup in der Desktop-App wieder aktivieren. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Der Ordner kann nicht synchronisiert werden, da er bereits synchronisierte Ordner enthält. + Der Ordner kann nicht synchronisiert werden, da er bereits synchronisierte Ordner enthält - MEGA kann VirtualBox-Ordner nicht synchronisieren oder sichern. + MEGA kann VirtualBox-Ordner nicht synchronisieren oder sichern - Der Account wurde gesperrt + Unable to sync or back up this folder as the account has been blocked - Problem bei der Synchronisierung oder Sicherung dieses Ordners. Bitte versuchen Sie es später erneut. Wenn das Problem weiterhin besteht, wenden Sie sich an den Support. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Account neu geladen. Verpasste Updates Ihrer Backups oder Synchronisierungen wurden nicht übernommen. - Die Synchronisierung oder das Backup wurde angehalten, da Sie sich anscheinend in der Desktop-App ausgeloggt haben. Loggen Sie sich in der Desktop-App wieder ein und aktivieren Sie die Synchronisierung bzw. das Backup erneut. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Ordner auf externem Laufwerk nicht gefunden. - Es gibt bereits einen synchronisierten Ordner unter demselben Pfad + There’s already a synced folder at the same path Die Umbenennung ist fehlgeschlagen. @@ -105,7 +105,7 @@ Synchronisierungskonfigurationen konnten nicht vom Laufwerk gelesen werden. - Laufwerkspfad der Synchronisierung ist unbekannt + Sync folder location is unknown Ungültiges Scan-Intervall @@ -125,17 +125,17 @@ Something went wrong. - Der Ordner kann nicht synchronisiert oder gesichert werden, da sich der MEGA-Ordner im Papierkorb befindet. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Der Ordner auf Ihrem Gerät kann derzeit nicht gefunden werden, bitte versuchen Sie es später erneut. Der Ordner auf Ihrem Gerät kann nicht gefunden werden - Problem bei der Synchronisierung oder Sicherung dieses Ordners aufgrund von Änderungen am MEGA-Ordner. Beenden Sie die Synchronisierung bzw. das Backup und richten Sie sie in der Desktop-App erneut ein oder wenden Sie sich an den Support. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Problem bei der Synchronisierung oder Sicherung dieses Ordners. Beenden Sie die Synchronisierung bzw. das Backup und richten Sie sie in der Desktop-App erneut ein oder wenden Sie sich an den Support. - Der Ordner kann nicht synchronisiert werden, da er sich bereits innerhalb eines synchronisierten Ordners befindet. + Folder can’t be synced as it’s already inside a synced folder Kamera-Uploads deaktiviert @@ -157,7 +157,7 @@ Keine Internetverbindung - Die Dateien in diesem Ordner können nicht synchronisiert oder gesichert werden. Sie müssen die Synchronisierung bzw. das Backup in der Desktop-App wieder aktivieren. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Noch nichts eingerichtet diff --git a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml index e18b039953..147a129c03 100644 --- a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - No se puede sincronizar ni hacer un backup de esta carpeta ya que el sistema de archivos de tu dispositivo no es compatible. + MEGA can’t sync or backup this folder because the file system on your device is not supported The folder you chose can’t be synced @@ -71,33 +71,33 @@ Se ha alcanzado el límite de cuota de almacenamiento. - No se ha podido sincronizar ni hacer un backup de esta carpeta porque tu plan ha caducado. + Unable to sync or back up this folder as your plan has expired - La carpeta no se puede sincronizar porque el usuario que la ha compartido ha alcanzado el límite de su cuota de almacenamiento. + Folder can’t be synced as the user who shared this folder has reached their storage quota No se ha podido localizar la carpeta en MEGA porque se ha movido o eliminado, o puede que no tengas acceso a ella. - La carpeta no se puede sincronizar porque es una carpeta compartida sin acceso completo. + Folder can’t be synced as it’s a shared folder without full access - Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup. Reactiva la sincronización o el backup desde la aplicación de escritorio. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - La carpeta no se puede sincronizar porque ya contiene carpetas sincronizadas. + Folder can’t be synced as it already contains synced folders - MEGA no puede sincronizar ni hacer backups de las carpetas de VirtualBox. + MEGA can’t sync or back up VirtualBox folders - No se puede sincronizar ni hacer backups de esta carpeta porque la cuenta está bloqueada. + Unable to sync or back up this folder as the account has been blocked - Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Vuelve a intentarlo más tarde. Si el problema persiste, ponte en contacto con el servicio de soporte. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Cuenta recargada. No se han realizado actualizaciones pendientes de tus backups o sincronizaciones. - La sincronización o el backup se han detenido porque parece que has cerrado sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A No es posible encontrar la carpeta en la unidad externa. - Ya existe una carpeta sincronizada en la misma ruta. + There’s already a synced folder at the same path Error al cambiar el nombre. @@ -105,13 +105,13 @@ Couldn’t read sync configuration. Try again later or check folder permissions. - Se desconoce la ruta de la unidad de sincronización. + Sync folder location is unknown Intervalo de escaneo no válido. Comprueba la configuración del intervalo de escaneo e inténtalo de nuevo. No se ha podido comunicar con la ubicación de la carpeta. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + No se puede añadir una vigilancia del sistema de archivos. Asegúrate de que haya suficiente espacio libre y suficiente memoria y de que los permisos para la ubicación de la carpeta estén concedidos. No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. @@ -125,17 +125,17 @@ Something went wrong. - No se puede sincronizar o hacer un backup de la carpeta porque la carpeta de MEGA está en la Papelera. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin No se ha podido localizar la carpeta de tu dispositivo, inténtalo de nuevo más tarde. Folder in your device can’t be located - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Detén la sincronización o el backup e intenta volver a configurarlos en la aplicación de escritorio, o ponte en contacto con el servicio de soporte. - La carpeta no se puede sincronizar porque ya está dentro de una carpeta sincronizada. + Folder can’t be synced as it’s already inside a synced folder Subidas de la cámara desactivadas @@ -157,7 +157,7 @@ No hay conexión a internet - Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup. Reactiva la sincronización o el backup desde la aplicación de escritorio. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Aún no hay nada configurado diff --git a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml index e15fed0424..b1f42d73f4 100644 --- a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge. + MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge Le dossier que vous avez choisi ne peut pas être synchronisé @@ -71,21 +71,21 @@ La limite du quota d’espace de stockage a été atteinte. - Impossible de synchroniser ou sauvegarder ce dossier, car votre abonnement est expiré. + Impossible de synchroniser ou sauvegarder ce dossier, car votre abonnement est expiré - Le dossier ne peut pas être synchronisé, car l’utilisateur qui l’a partagé a dépassé son quota de stockage. + Le dossier ne peut pas être synchronisé, car l’utilisateur qui l’a partagé a dépassé son quota de stockage Impossible de trouver le dossier dans MEGA. Soit il a été déplacé, soit il a été supprimé, soit vous n’y avez pas accès. - Impossible de synchroniser le dossier, car c’est un dossier partagé sans accès total. + Impossible de synchroniser le dossier, car c’est un dossier partagé sans accès total Les fichiers de ce dossier ne peuvent être ni synchronisés ni sauvegardés. Vous devez réactiver la synchronisation ou la sauvegarde dans l’appli pour ordinateur. - Le dossier ne peut pas être synchronisé, car il comprend déjà des dossiers synchronisés. + Le dossier ne peut pas être synchronisé, car il comprend déjà des dossiers synchronisés - MEGA ne peut ni synchroniser ni sauvegarder les dossiers VirtualBox. + MEGA ne peut ni synchroniser ni sauvegarder les dossiers VirtualBox - Impossible de synchroniser ou sauvegarder ce dossier, car le compte a été bloqué. + Impossible de synchroniser ou sauvegarder ce dossier, car le compte a été bloqué Problème de synchronisation ou de sauvegarde de ce dossier. Réessayez ultérieurement. Si la situation persiste, contactez l’assistance. @@ -97,7 +97,7 @@ Impossible de trouver le fichier sur le lecteur externe. - Un dossier synchronisé porte déjà ce nom dans le même chemin. + Un dossier synchronisé porte déjà ce nom dans le même chemin Échec de renommage. @@ -105,7 +105,7 @@ Impossible de lire la configuration de la synchronisation. Réessayez ultérieurement ou vérifiez les droits du dossier. - Le chemin du lecteur de la synchronisation est inconnu. + L’emplacement du dossier de la synchronisation est inconnu L’intervalle d’analyse est invalide. Vérifiez la configuration de l’intervalle d’analyse et réessayez. @@ -125,7 +125,7 @@ Something went wrong. - Le dossier ne peut ni être synchronisé ni sauvegardé, car le dossier MEGA est dans la Corbeille. + Le dossier ne peut ni être synchronisé ni sauvegardé, car le dossier MEGA est dans la Corbeille Impossible de trouver le dossier sur votre appareil. Réessayez plus tard. @@ -135,7 +135,7 @@ Problème de synchronisation ou de sauvegarde de ce dossier. Arrêtez la synchronisation ou la sauvegarde, puis tentez de la définir de nouveau dans l’appli pour ordinateur ou contactez l’assistance. - Le dossier ne peut pas être synchronisé, car il fait déjà partie d’un dossier synchronisé. + Le dossier ne peut pas être synchronisé, car il fait déjà partie d’un dossier synchronisé Les Téléversements de l’appareil photo sont désactivés diff --git a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml index a78f2ebfd2..718e80e59b 100644 --- a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA tidak dapat menyinkronkan atau mencadangkan folder ini karena sistem file pada perangkat anda tidak didukung. + MEGA can’t sync or backup this folder because the file system on your device is not supported The folder you chose can’t be synced @@ -71,33 +71,33 @@ Batas kuota penyimpanan tercapai. - Tidak dapat menyinkronkan atau membuat cadangan folder ini karena paket anda telah kedaluwarsa. + Unable to sync or back up this folder as your plan has expired - Folder can’t be synced as the user who shared this folder has reached their storage quota. + Folder can’t be synced as the user who shared this folder has reached their storage quota Folder di MEGA tidak dapat ditemukan karena telah dipindahkan atau dihapus, atau anda mungkin tidak memiliki akses. - Folder tidak dapat disinkronkan karena merupakan folder bersama tanpa akses penuh. + Folder can’t be synced as it’s a shared folder without full access - File dalam folder ini tidak dapat disinkronkan atau dicadangkan. Anda harus mengaktifkan kembali sinkronisasi atau cadangan dari aplikasi Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Folder tidak dapat disinkronkan karena sudah berisi folder yang disinkronkan. + Folder can’t be synced as it already contains synced folders - MEGA tidak dapat menyinkronkan atau mencadangkan folder VirtualBox. + MEGA can’t sync or back up VirtualBox folders - Tidak dapat menyinkronkan atau mencadangkan folder ini karena akun telah diblokir. + Unable to sync or back up this folder as the account has been blocked - Masalah saat menyinkronkan atau membuat cadangan folder ini. Coba lagi nanti. Jika masalah berlanjut, hubungi Bantuan. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Akun dimuat ulang. Pembaruan apa pun yang terlewat untuk cadangan atau sinkronisasi anda belum diterapkan. - Sinkronisasi atau pencadangan telah dihentikan karena anda tampaknya keluar dari aplikasi Desktop. Masuk kembali melalui aplikasi Desktop, dan lanjutkan sinkronisasi atau pencadangan. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Folder di drive eksternal tidak dapat ditemukan. - Sudah ada folder yang disinkronkan di jalur yang sama. + There’s already a synced folder at the same path Mengganti nama gagal. @@ -105,13 +105,13 @@ Couldn’t read sync configuration. Try again later or check folder permissions. - Jalur drive Sync tidak diketahui. + Sync folder location is unknown Interval pemindaian tidak valid. Periksa pengaturan interval pemindaian dan coba lagi. Tidak dapat berkomunikasi dengan lokasi folder. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Tidak dapat menambahkan pengawasan sistem file. Pastikan ada ruang kosong dan memori yang cukup, dan bahwa anda telah memberikan izin untuk lokasi folder. Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. @@ -125,17 +125,17 @@ Something went wrong. - Folder tidak dapat disinkronkan atau dicadangkan karena folder MEGA ada di Tempat Sampah. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder di perangkat anda tidak dapat ditemukan sekarang, coba lagi nanti. Folder in your device can’t be located - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Masalah saat menyinkronkan atau membuat cadangan folder ini. Hentikan sinkronisasi atau pencadangan dan coba atur lagi di aplikasi Desktop, atau hubungi Bantuan. - Folder tidak dapat disinkronkan karena sudah berada di dalam folder yang disinkronkan. + Folder can’t be synced as it’s already inside a synced folder Camera uploads disabled @@ -157,7 +157,7 @@ Tidak ada koneksi internet - File dalam folder ini tidak dapat disinkronkan atau dicadangkan. Anda harus mengaktifkan kembali sinkronisasi atau cadangan dari aplikasi Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Belum ada yang disiapkan diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index 4038b18382..d7c793a0e5 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato. + MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato La cartella che hai scelto non può essere sincronizzata @@ -71,23 +71,23 @@ Limite della banda di trasferimento raggiunto. - Impossibile sincronizzare o effettuare il backup perché il tuo piano è scaduto. + Impossibile sincronizzare o effettuare il backup perché il tuo piano è scaduto - La cartella non può essere sincronizzata poiché l\’utente che ha condiviso questa cartella ha esaurito il proprio spazio di archiviazione. + La cartella non può essere sincronizzata poiché l\’utente che ha condiviso questa cartella ha esaurito il proprio spazio di archiviazione La cartella in MEGA non può essere trovata perché è stata eliminata o spostata, o potresti non avere accesso ad essa. - La cartella non può essere sincronizzata perché è una cartella condivisa senza pieno accesso. + La cartella non può essere sincronizzata perché è una cartella condivisa senza pieno accesso I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. - La cartella non può essere sincronizzata perché già contiene cartelle sincronizzate. + La cartella non può essere sincronizzata perché già contiene cartelle sincronizzate - MEGA non è in grado di sincronizzare o eseguire il backup delle cartelle VirtualBox. + MEGA non è in grado di sincronizzare o eseguire il backup delle cartelle VirtualBox - Impossibile sincronizzare o effettuare il backup di questa cartella perché l\’account è stato bloccato. + Impossibile sincronizzare o effettuare il backup di questa cartella perché l\’account è stato bloccato - Problema nella sincronizzazione o nel backup di questa cartella. Riprova più tardi. Se il problema persiste, contatta il Supporto. + Problema nella sincronizzazione o nel backup di questa cartella. Riprova più tardi. Se il problema persiste, contatta il supporto. Account ricaricato. Qualsiasi aggiornamento mancato ai tuoi backup o alle tue sincronizzazioni non è stato applicato. @@ -97,15 +97,15 @@ La cartella nel drive esterno non può essere trovata. - C\’è già una cartella sincronizzata allo stesso percorso. + C\’è già una cartella sincronizzata allo stesso percorso Rinominazione fallita. - Couldn’t create a .megaignore file for this sync + Impossibile creare un file .megaignore per questa sincronizzazione Impossibile leggere la configurazione della sincronizzazione. Riprova più tardi o controlla le autorizzazioni della cartella. - Il percorso della sincronizzazione è sconosciuto. + La posizione della cartella di sincronizzazione è sconosciuta Intervallo della scansione invalido. Controlla l\’impostazione dell\’intervallo della scansione e riprova. @@ -125,17 +125,17 @@ Something went wrong. - La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino. + La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino La cartella nel tuo dispositivo non può essere trovata, riprova più tardi. La cartella nel dispositivo non può essere localizzata - Problemi durante la sincronizzazione o il backup di questa cartella a causa di modifiche alla cartella MEGA. Interrompi la sincronizzazione o il backup e prova a configurarli nuovamente nell\’app desktop oppure contatta il Supporto. + Problemi durante la sincronizzazione o il backup di questa cartella a causa di modifiche alla cartella MEGA. Interrompi la sincronizzazione o il backup e prova a configurarli nuovamente nell\’app desktop oppure contatta il supporto. Problemi nella sincronizzazione o nel backup di questa cartella. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente dall\’app per desktop, o contatta il Supporto. - La cartella non può essere sincronizzata in quanto è già dentro una cartella sincronizzata. + La cartella non può essere sincronizzata in quanto è già dentro una cartella sincronizzata Caricamenti da fotocamera disattivati diff --git a/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml index 9371799115..62a2d0b9dd 100644 --- a/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml @@ -59,7 +59,7 @@ 同期エラーはありません - デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません。 + デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません 選択したフォルダは同期できません @@ -71,23 +71,23 @@ ストレージ容量の制限に達しました。 - お客様のプランの有効期限が切れているため、このフォルダを同期またはバックアップできません。 + お客様のプランの有効期限が切れているため、このフォルダを同期またはバックアップできません - このフォルダを共有したユーザーはストレージ容量に達したため、フォルダを同期できません。 + このフォルダを共有したユーザーはストレージ容量に達したため、フォルダを同期できません MEGA内のフォルダは、移動または削除されたため見つからないか、アクセス権がない可能性があります。 - フォルダは、フルアクセスのない共有フォルダであるため、同期できません。 + フォルダは、フルアクセスのない共有フォルダであるため、同期できません このフォルダ内のファイルは同期またはバックアップできません。デスクトップアプリから同期またはバックアップを再度有効にする必要があります。 フォルダにはすでに同期フォルダが含まれているため、フォルダを同期できません。 - MEGAはVirtualBoxフォルダを同期またはバックアップできません。 + MEGAはVirtualBoxフォルダを同期またはバックアップできません アカウントがブロックされているため、このフォルダを同期またはバックアップできません。 - このフォルダの同期またはバックアップ中に問題が発生しました。あとでもう一度お試しください。問題が解決しない場合は、サポートにお問い合わせください。 + このフォルダの同期またはバックアップ中に問題が発生しました。あとでもう一度お試しください。問題が解決しない場合は、サポートにご連絡ください。 アカウントが再読み込みされました。バックアップまたは同期に対して欠落した更新は適用されていません。 @@ -97,7 +97,7 @@ 外付けドライブのフォルダが見つかりません。 - 同じパスに同期フォルダがすでに存在します。 + 同じパスに同期フォルダがすでに存在します 名前の変更に失敗しました。 @@ -105,7 +105,7 @@ 同期構成を読み取れませんでした。後でもう一度試すか、フォルダのアクセス許可を確認してください。 - 同期のドライブパスが不明です。 + 同期フォルダの場所が不明です 無効なスキャン間隔です。スキャン間隔の設定を確認して、再試行してください。 @@ -125,7 +125,7 @@ 何か問題が発生しました。 - リモートノードはごみ箱の中にあります。 + MEGAフォルダはごみ箱にあるため、フォルダを同期またはバックアップできません 現在、デバイス内のフォルダが見つかりません。後でもう一度お試しください。 @@ -133,9 +133,9 @@ MEGAフォルダへの変更により、このフォルダの同期またはバックアップ中に問題が発生しました。バックアップを停止し、デスクトップアプリでもう一度セットアップしてみるか、サポートにご連絡ください。 - このフォルダの同期またはバックアップ中に問題が発生しました。同期またはバックアップを停止し、デスクトップアプリでもう一度設定してみるか、サポートにお問い合わせください。 + このフォルダの同期またはバックアップ中に問題が発生しました。同期またはバックアップを停止し、デスクトップアプリでもう一度設定してみるか、サポートにご連絡ください。 - パスの上にアクティブな同期。 + フォルダは、すでに同期フォルダ内にあるため同期できません カメラアップロードが無効になっています diff --git a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml index 7bc4d79694..2e108755d3 100644 --- a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - 이 폴더는 당신의 기기의 파일 시스템이 지원하지 않기 때문에 MEGA에서 동기화 하거나 백업할 수 없습니다. + MEGA can’t sync or backup this folder because the file system on your device is not supported 선택한 폴더는 동기화할 수 없습니다 @@ -71,33 +71,33 @@ 저장소 할당량 한도에 도달하였습니다. - 요금제가 만료되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다. + 요금제가 만료되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 - 이 폴더를 공유한 사람의 저장소 할당량에 도달하여 폴더를 동기화할 수 없습니다. + Folder can’t be synced as the user who shared this folder has reached their storage quota MEGA의 폴더가 이동 되었거나, 삭제 되었거나, 접근 권한이 없어서 찾을 수 없습니다. - 전체 권한 없이 공유된 폴더이기 때문에 폴더를 동기화할 수 없습니다. + Folder can’t be synced as it’s a shared folder without full access - 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - 동기화된 폴더가 포함되어 있는 폴더이기 때문에 동기화할 수 없습니다. + 동기화된 폴더가 포함되어 있는 폴더이기 때문에 동기화할 수 없습니다 - MEGA는 VirtualBox 폴더를 동기화 또는 백업할 수 없습니다. + MEGA는 VirtualBox 폴더를 동기화 또는 백업할 수 없습니다 - 계정이 차단되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다. + Unable to sync or back up this folder as the account has been blocked - 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 나중에 다시 시도하세요. 만약 문제가 계속되면, 지원에 연락주세요. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. 계정을 다시 불러왔습니다. 백업 또는 동기화에 누락된 변경사항이 적용되지 않습니다. - 데스크톱 앱에서 로그아웃한 것으로 나타나서 동기화 또는 백업이 멈추었습니다. 데스크톱 앱에서 다시 로그인하고, 동기화 또는 백업을 재개하세요. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A 외부 드라이브에 있는 폴더를 찾을 수 없습니다. - 같은 경로에 이미 동기화된 폴더가 있습니다. + There’s already a synced folder at the same path 이름 변경 실패. @@ -105,7 +105,7 @@ 동기화 설정을 읽을 수 없습니다. 나중에 다시 시도하거나 폴더 권한을 확인하세요. - 동기화 드라이브 경로를 알 수 없습니다. + Sync folder location is unknown 잘못된 탐색 간격. 탐색 간격 설정을 확인하고 다시 시도하세요. @@ -125,17 +125,17 @@ Something went wrong. - MEGA 폴더가 휴지통에 있어서 폴더를 동기화 또는 백업할 수 없습니다. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin 장치의 폴더를 찾을 수 없습니다, 나중에 다시 시도하세요. 장치의 폴더를 찾을 수 없습니다 - 이 폴더를 동기화 또는 백업하던 중 MEGA 폴더의 변경으로 인해 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. - 동기화된 폴더 안에 위치한 폴더이기 때문에 동기화할 수 없습니다. + Folder can’t be synced as it’s already inside a synced folder 카메라 업로드 비활성화됨 @@ -157,7 +157,7 @@ 인터넷 연결이 없습니다 - 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. 아직 아무 것도 설정되지 않았습니다 diff --git a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml index b5fc8987f0..6404d33699 100644 --- a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml @@ -59,7 +59,7 @@ Geen synchronisatiefout - MEGA kan geen synchronisatie of back-up van deze map maken omdat het bestandsysteem op uw apparaat niet ondersteund is. + MEGA can’t sync or backup this folder because the file system on your device is not supported De map die u heeft gekozen, kan niet worden gesynchroniseerd @@ -71,33 +71,33 @@ Opslag tegoed limiet bereikt. - Kan deze map niet synchroniseren of er een back-up van maken, omdat uw abonnement is verlopen. + U kunt deze map niet synchroniseren of er een back-up van maken omdat uw abonnement is verlopen - De map kan niet worden gesynchroniseerd omdat de gebruiker die deze map heeft gedeeld het opslagtegoed heeft bereikt. + Folder can’t be synced as the user who shared this folder has reached their storage quota De map in MEGA kan niet worden gevonden omdat deze is verplaatst of verwijderd, of u heeft mogelijk geen toegang. - Map kan niet worden gesynchroniseerd omdat het een gedeelde map is zonder volledige toegang. + Folder can’t be synced as it’s a shared folder without full access - Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet de synchronisatie of back-up opnieuw inschakelen via de desktop-applicatie. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Map kan niet worden gesynchroniseerd omdat deze al gesynchroniseerde mappen bevat. + De map kan niet worden gesynchroniseerd omdat deze al gesynchroniseerde mappen bevat - MEGA kan VirtualBox-mappen niet synchroniseren of backuppen. + MEGA kan VirtualBox-mappen niet synchroniseren of er een back-up van maken - Kan deze map niet synchroniseren of er een back-up van maken, omdat het account is geblokkeerd. + Unable to sync or back up this folder as the account has been blocked - Probleem bij het synchroniseren of back-uppen van deze map. Probeer het later nog eens. Neem contact op met de ondersteuning als het probleem zich blijft voordoen. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Account opnieuw geladen. Eventuele gemiste updates voor uw back-ups of synchronisaties zijn niet toegepast. - Synchronisatie of back-up is gestopt omdat het lijkt alsof u bent afgemeld bij de Desktop-applicatie. Meld u opnieuw aan via de Desktop-applicatie en hervat de synchronisatie of back-up. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Map in lokale schijf kan niet gevonden worden. - Er is al een gesynchroniseerde map op hetzelfde pad. + Er is al een gesynchroniseerde map op hetzelfde pad Hernoemen is mislukt. @@ -105,7 +105,7 @@ Kon de synchronisatieconfiguratie niet lezen. Probeer het later opnieuw of controleer de mapmachtigingen. - Het schijfpad van Sync is onbekend. + Sync folder location is unknown Ongeldig scaninterval. Controleer de instellingen voor het scaninterval en probeer het opnieuw. @@ -125,17 +125,17 @@ Er is iets misgegaan. - Map kan niet gesynchroniseerd worden of opgeslagen omdat de MEGA map in de Prullenbak is. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin De map op uw apparaat kan nu niet worden gevonden. Probeer het later opnieuw. De map op uw apparaat kan niet worden gevonden - Probleem bij het synchroniseren of maken van een reservekopie van deze map vanwege wijzigingen in de MEGA-map. Stop het synchroniseren of de backup en probeer het opnieuw in te stellen in de desktop applicatie, of neem contact op met de Ondersteuning. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Probleem bij het synchroniseren of back-uppen van deze map. Stop de synchronisatie of back-up en probeer deze opnieuw in te stellen in de Desktop-applicatie, of neem contact op met de ondersteuning. - Map kan niet gesynchroniseert worden omdat het al binnen een gesynchroniseerde map is. + Folder can’t be synced as it’s already inside a synced folder Camera uploads uitgeschakeld @@ -157,7 +157,7 @@ Geen internet verbinding - Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet de synchronisatie of back-up opnieuw inschakelen via de desktop-applicatie. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Nog niets ingesteld diff --git a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml index c5d51bf459..c70c3decdf 100644 --- a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA nie może zsynchronizować ani wykonać kopii zapasowej tego katalogu, ponieważ system plików na urządzeniu nie jest obsługiwany. + MEGA can’t sync or backup this folder because the file system on your device is not supported Nie można zsynchronizować wybranego katalogu @@ -71,33 +71,33 @@ Osiągnięto limit przydziału pamięci. - Nie można zsynchronizować lub utworzyć kopii zapasowej tego katalogu, ponieważ plan wygasł. + Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ plan wygasł - Nie można zsynchronizować katalogu, ponieważ użytkownik, który udostępnił ten katalog, osiągnął swój pojemność. + Folder can’t be synced as the user who shared this folder has reached their storage quota Katalog w MEGA nie może zostać zlokalizowany, ponieważ został przeniesiony lub usunięty, lub możesz nie mieć do niego dostępu. - Katalog nie może być zsynchronizowany, ponieważ jest to katalog współdzielony bez pełnego dostępu. + Folder can’t be synced as it’s a shared folder without full access - Plików w tym katalogu nie można synchronizować ani tworzyć ich kopii zapasowych. Konieczne będzie ponowne włączenie synchronizacji lub tworzenia kopii zapasowych w aplikacji Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Katalog nie może być zsynchronizowany, ponieważ zawiera już zsynchronizowane katalogi. + Nie można zsynchronizować katalogu, ponieważ zawiera już zsynchronizowane katalogi - MEGA nie może synchronizować ani tworzyć kopii zapasowych katalogów VirtualBox. + MEGA nie może synchronizować ani tworzyć kopii zapasowych katalogu VirtualBox - Nie można zsynchronizować lub utworzyć kopii zapasowej tego katalogu, ponieważ konto zostało zablokowane. + Unable to sync or back up this folder as the account has been blocked - Problem z synchronizacją lub kopią zapasową tego katalogu. Spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z pomocą techniczną. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Konto zostało przeładowane. Wszelkie pominięte aktualizacje kopii zapasowych lub synchronizacji nie zostały zastosowane. - Synchronizacja lub tworzenie kopii zapasowej zostały zatrzymane, ponieważ wygląda na to, że użytkownik wylogował się z aplikacji Desktop. Zaloguj się ponownie za pomocą aplikacji Desktop i wznów synchronizację lub tworzenie kopii zapasowej. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Nie można zlokalizować katalogu na dysku zewnętrznym. - W tej samej ścieżce znajduje się już zsynchronizowany katalog. + There’s already a synced folder at the same path Zmiana nazwy nie powiodła się. @@ -105,7 +105,7 @@ Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. - Ścieżka dysku synchonizacji jest nieznana. + Sync folder location is unknown Nieprawidłowy interwał skanowania. Sprawdź ustawienia interwału skanowania i spróbuj ponownie. @@ -125,17 +125,17 @@ Something went wrong. - Katalogu nie można zsynchronizować ani wykonać kopii zapasowej, ponieważ MEGA katalog znajduje się w Koszu. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Nie można teraz zlokalizować katalogu w urządzeniu, spróbuj ponownie później. Nie można zlokalizować katalogu w urządzeniu - Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu z powodu zmian w katalogu MEGA. Zatrzymaj synchronizację lub kopię zapasową i spróbuj ponownie skonfigurować ją w aplikacja desktopowa komputerowej lub kontakt techniczną. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Problem z synchronizacją lub kopią zapasową tego katalogu. Zatrzymaj synchronizację lub tworzenie kopii zapasowej i spróbuj skonfigurować je ponownie w aplikacji Desktop lub skontaktuj się z pomocą techniczną. - Katalog nie może być zsynchronizowany, ponieważ znajduje się już w zsynchronizowanym katalogu. + Folder can’t be synced as it’s already inside a synced folder Przesyłanie z kamery wyłączone @@ -157,7 +157,7 @@ Brak połączenia z internetem - Plików w tym katalogu nie można synchronizować ani tworzyć ich kopii zapasowych. Konieczne będzie ponowne włączenie synchronizacji lub tworzenia kopii zapasowych w aplikacji Desktop. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Nic nie zostało jeszcze skonfigurowane diff --git a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml index 7f62bb0bcf..bfbda1d8f4 100644 --- a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado. + O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado Não é possível sincronizar a pasta selecionada @@ -73,11 +73,11 @@ Não foi possível sincronizar ou fazer backup dessa pasta porque o seu plano expirou. - Não é possível sincronizar esta pasta porque o usuário que a compartilhou alcançou a cota de armazenamento da conta dele. + Não é possível sincronizar esta pasta porque o usuário que a compartilhou alcançou a cota de armazenamento da conta dele Não foi possível localizar a pasta no MEGA porque ela foi movida ou deletada, ou pode ser que você não tenha acesso a ela. - Não é possível sincronizar esta pasta porque é uma pasta compartilhada sem acesso total. + A pasta não pode ser sincronizada porque é uma pasta compartilhada sem acesso total Não foi possível sincronizar ou fazer backup dos arquivos nesta pasta. Você precisa reativar a sua sincronização ou o seu backup no aplicativo para desktop. @@ -85,9 +85,9 @@ O MEGA não pode sincronizar ou fazer backup das pastas do VirtualBox. - Não foi possível sincronizar ou fazer backup dessa pasta porque a conta foi bloqueada. + Não foi possível sincronizar ou fazer backup dessa pasta porque a conta foi bloqueada - Não foi possível sincronizar ou fazer o backup desta pasta. Tente novamente mais tarde. Se o problema persistir, entre em contato com a nossa equipe de Suporte. + Problema ao sincronizar ou fazer backup dessa pasta. Tente novamente mais tarde. Se o problema persistir, contatar o suporte. A sua conta foi recarregada. Nenhuma atualização pendente dos seus backups ou das suas sincronizações não foi feita. @@ -97,7 +97,7 @@ Não é possível localizar a pasta na unidade externa. - Já existe uma pasta sincronizada no mesmo caminho. + Já existe uma pasta sincronizada no mesmo caminho Não foi possível renomear. @@ -105,7 +105,7 @@ Não foi possível ler a configuração da sincronização. Tente novamente mais tarde ou verifique as permissões da pasta. - O caminho da unidade de sincronização é desconhecido. + A localização da pasta sincronizada é desconhecida O intervalo de escaneado é inválido. Verifique a configuração do intervalo de escaneado e tente novamente. @@ -125,17 +125,17 @@ Something went wrong. - Não é possível sincronizar ou fazer backup porque a pasta no MEGA está na Lixeira. + Não é possível sincronizar ou fazer backup porque a pasta no MEGA está na Lixeira Não foi possível localizar a pasta no seu dispositivo - tente novamente mais tarde. Não foi possível localizar a pasta no seu dispositivo - Não foi possível sincronizar ou fazer o backup desta pasta devido a alterações na pasta no MEGA. Cancele a sincronização ou o backup e tente configurá-lo novamente no aplicativo para desktop, ou entre em contato com a nossa equipe de Suporte. + Não foi possível sincronizar ou fazer o backup desta pasta devido a alterações na pasta no MEGA. Cancele a sincronização ou o backup e tente configurá-lo novamente no aplicativo para desktop, ou entre em contato com o suporte. Não foi possível sincronizar ou fazer o backup desta pasta. Cancele a sincronização ou o backup e tente configurá-lo novamente no aplicativo para desktop, ou entre em contato com a nossa equipe de Suporte. - Não é possível sincronizar esta pasta porque está dentro de uma pasta sincronizada. + Não é possível sincronizar esta pasta porque está dentro de uma pasta sincronizada Uploads da câmera desativados diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index 971d4d3ec6..ddcaec0be6 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat. + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat Folderul ales nu poate fi sincronizat @@ -71,41 +71,41 @@ Limita cotei de spațiu de stocare a fost atinsă. - Nu se poate sincroniza sau face backup pentru acest folder, deoarece abonamentul dvs. a expirat. + Nu se poate sincroniza sau backup pentru acest folder, deoarece abonamentul dvs. a expirat - Folderul nu poate fi sincronizat deoarece utilizatorul care a partajat acest folder a atins cotă de spațiu de stocare. + Folderul nu poate fi sincronizat deoarece utilizatorul care a partajat acest folder a atins cotă de spațiu de stocare Folderul din MEGA nu poate fi localizat deoarece a fost mutat sau șters sau este posibil să nu aveți acces. - Folderul nu poate fi sincronizat, deoarece este un folder partajat fără acces complet. + Folderul nu poate fi sincronizat, deoarece este un folder partajat fără acces complet Fișierele din acest folder nu pot fi sincronizate sau backup-uite. Va trebui să reactivați sincronizarea sau backupul din aplicația desktop. - Folderul nu poate fi sincronizat deoarece conține deja foldere sincronizate. + Folderul nu poate fi sincronizat deoarece conține deja foldere sincronizate - MEGA nu poate sincroniza sau face backup pentru folderele VirtualBox. + MEGA nu poate sincroniza sau face backup pentru folderele VirtualBox - Nu se poate sincroniza sau face backup pentru acest folder, deoarece contul a fost blocat. + Nu se poate sincroniza sau face backup pentru acest folder, deoarece contul a fost blocat - Problemă la sincronizarea sau backup a acestui folder. Încercați din nou mai târziu. Dacă problema persistă, contactați Asistența. + Problemă la sincronizarea sau copierea de rezervă a acestui folder. Încercați din nou mai târziu. Dacă problema persistă, contactați asistență. Contul a fost reîncărcat. Toate actualizările ratate ale backupurilor sau ale sincronizărilor nu au fost aplicate. - Sincronizarea sau backupul au fost oprite pe măsură ce parcă v-ați deconectat de la aplicația Desktop. Conectați-vă din nou prin aplicația Desktop și reluați sincronizarea sau backup-ul. + Sincronizarea sau backupul au fost oprite pe măsură ce parcă v-ați deconectat de la aplicația desktop. Conectați-vă din nou prin aplicația desktop și reluați sincronizarea sau backup-ul. N/A Folderul din unitatea externă nu poate fi localizat. - Există deja un folder sincronizat pe aceeași cale. + Există deja un folder sincronizat pe aceeași cale Redenumirea a eșuat. - Couldn’t create a .megaignore file for this sync + Nu s-a putut crea un fişier .megaignore pentru această sincronizare Nu am putut citi configurația de sincronizare. Încercați din nou mai târziu sau verificați permisiunile folder. - Calea către unitatea de sincronizare este necunoscută. + Sincronizarea locației folderului este necunoscută Interval de analiză invalid. Verificați configurarea intervalului de analiză și încercați din nou. @@ -125,17 +125,17 @@ Something went wrong. - Folderul nu poate fi sincronizat sau backup-uit, deoarece folderul MEGA se află în Coșul de gunoi. + Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi Folderul din dispozitiv nu poate fi localizat acum, încercați din nou mai târziu. Folderul din dispozitiv dvs. nu poate fi localizat - Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați Asistența. + Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați asistența. Problemă la sincronizarea sau backup a acestui folder. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. - Folderul nu poate fi sincronizat, deoarece se află deja într-un folder sincronizat. + Folderul nu poate fi sincronizat, deoarece se află deja într-un folder sincronizat Încărcări camere sunt dezactivate diff --git a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml index 54756acff0..9e4ee67080 100644 --- a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA не может синхронизировать эту папку или сделать резервную копию, потому что файловая система на вашем устройстве не поддерживается. + MEGA can’t sync or backup this folder because the file system on your device is not supported Выбранную папку невозможно синхронизировать @@ -71,33 +71,33 @@ Хранилище заполнено - Невозможно синхронизировать или создать резервную копию этой папки, так как срок действия вашего плана истёк. + Невозможно синхронизировать или создать резервную копию этой папки, так как срок действия вашего плана истёк - Невозможно синхронизировать папку, так как у пользователя, который поделился ей, хранилище полностью заполнено. + Folder can’t be synced as the user who shared this folder has reached their storage quota Не удалось найти папку в MEGA, так как она была перемещена или удалена, либо у вас нет доступа. - Папку нельзя синхронизировать, поскольку это общая папка без полного доступа. + Folder can’t be synced as it’s a shared folder without full access - Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Папку нельзя синхронизировать, так как она уже содержит синхронизируемые папки. + Папку нельзя синхронизировать, так как она уже содержит синхронизируемые папки - MEGA не может синхронизировать или создавать резервные копии папок VirtualBox. + MEGA не может синхронизировать или создавать резервные копии папок VirtualBox - Невозможно синхронизировать или создать резервную копию этой папки, так как аккаунт заблокирован. + Невозможно синхронизировать или создать резервную копию этой папки, так как аккаунт заблокирован - Проблема с синхронизацией или резервным копированием этой папки. Повторите попытку позже. Если проблема не исчезнет, обратитесь в поддержку. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Аккаунт перезагружен. Любые пропущенные обновления ваших резервных копий или синхронизаций не были применены. - Синхронизация или резервное копирование остановлены, поскольку вы, похоже, вышли из настольного приложения. Снова войдите в систему в настольном приложении и возобновите синхронизацию или резервное копирование. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Не удаётся найти папку на внешнем диске. - По тому же пути уже есть синхронизируемая папка. + There’s already a synced folder at the same path Не удалось переименовать. @@ -105,7 +105,7 @@ Не удалось прочитать конфигурацию синхронизации. Повторите попытку позже или проверьте права доступа к папке. - Путь к диску синхронизации неизвестен. + Sync folder location is unknown Недействительный интервал сканирования. Проверьте настройку интервала сканирования и попробуйте ещё раз. @@ -125,17 +125,17 @@ Something went wrong. - Папку нельзя синхронизировать или скопировать, так как папка MEGA находится в Корзине. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Не удалось найти папку на вашем устройстве. Повторите попытку позже. Не удалось найти папку на вашем устройстве - Проблема с синхронизацией или резервным копированием этой папки из-за изменений в папке MEGA. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Проблема с синхронизацией или резервным копированием этой папки. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. - Папку нельзя синхронизировать, так как она уже находится внутри синхронизируемой папки. + Folder can’t be synced as it’s already inside a synced folder Загрузки из камеры отключены @@ -157,7 +157,7 @@ Нет подключения к Интернету - Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Пока ничего не настроено diff --git a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml index 1a5a19ffc1..c4ad2b8dcc 100644 --- a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ได้ เนื่องจากไม่สนับสนุนระบบไฟล์ในอุปกรณ์ของคุณ + MEGA can’t sync or backup this folder because the file system on your device is not supported โฟลเดอร์ที่คุณเลือกไม่สามารถซิงค์ได้ @@ -71,33 +71,33 @@ โควต้าพื้นที่จัดเก็บถึงขีดจำกัดแล้ว - ไม่สามารถซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ได้เนื่องจากแผนของคุณหมดอายุแล้ว + Unable to sync or back up this folder as your plan has expired - ไม่สามารถซิงค์โฟลเดอร์ได้ เนื่องจากผู้ใช้ที่แชร์โฟลเดอร์นี้ได้ใช้พื้นที่จัดเก็บข้อมูลเต็มแล้ว + Folder can’t be synced as the user who shared this folder has reached their storage quota ไม่สามารถหาโฟลเดอร์ใน MEGAได้ อาจถูกย้ายหรือลบออก หรือคุณอาจไม่สามารถเข้าถึงได้ - ไม่สามารถซิงค์โฟลเดอร์นี้ได้เนื่องจากเป็นโฟลเดอร์ที่มีการแชร์โดยไม่มีการเข้าถึงแบบเต็ม + Folder can’t be synced as it’s a shared folder without full access - ไฟล์ในโฟลเดอร์นี้ไม่สามารถซิงค์หรือสำรองข้อมูลได้ คุณต้องเปิดใช้งานการซิงค์หรือการสำรองข้อมูลใหม่จากแอปบนเดสก์ท็อปก่อน + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - ไม่สามารถซิงค์โฟลเดอร์นี้ได้เนื่องจากอยู่ในโฟลเดอร์ที่มีการซิงค์อยู่แล้ว + Folder can’t be synced as it already contains synced folders - MEGA ไม่สามารถซิงค์หรือสำรองโฟลเดอร์ VirtualBox ได้ + MEGA can’t sync or back up VirtualBox folders - ไม่สามารถซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ได้ เนื่องจากบัญชีถูกบล็อกไว้ + Unable to sync or back up this folder as the account has been blocked - มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ ลองใหม่อีกครั้งในภายหลัง หากยังประสบปัญหาอยู่ กรุณาติดต่อฝ่ายสนับสนุน + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. บัญชีของคุณถูกโหลดซ้ำ การเปลี่ยนแปลงที่หายไปจะไม่มีผลกับการสำรองข้อมูลหรือการซิงค์ของคุณ - การซิงค์หรือการสำรองข้อมูลถูกหยุดลง ซึ่งดูเหมือนว่าคุณได้ออกจากระบบแอปเดสก์ท็อปแล้ว กรุณาเข้าสู่ระบบผ่านแอปเดสก์ท็อปแล้วเริ่มต้นการซิงค์หรือการสำรองข้อมูลใหม่อีกครั้ง + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A ไม่พบโฟลเดอร์ในไดรฟ์ภายนอก - มีโฟลเดอร์ที่ซิงค์ข้อมูลอยู่ที่เส้นทางเดียวกันแล้ว + There’s already a synced folder at the same path การเปลี่ยนชื่อไม่สำเร็จ @@ -105,7 +105,7 @@ ไม่สามารถอ่านการกำหนดค่าการซิงค์ได้ กรุณาลองใหม่ในภายหลังหรือตรวจสอบสิทธิ์ในโฟลเดอร์ของคุณอีกครั้ง - ไม่ทราบเส้นทางไดรฟ์ที่ใช้การซิงค์ได้ + Sync folder location is unknown ช่วงเวลาสแกนไม่ถูกต้อง กรุณาตรวจสอบการตั้งค่าช่วงเวลาสแกนและลองใหม่อีกครั้ง @@ -125,17 +125,17 @@ Something went wrong. - ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์ได้เนื่องจากโฟลเดอร์ MEGA อยู่ในถังขยะ + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin ไม่สามารถหาโฟลเดอร์ในอุปกรณ์ของคุณได้ในขณะนี้ กรุณาลองอีกครั้งในภายหลัง ไม่สามารถหาโฟลเดอร์ในอุปกรณ์ของคุณได้ - มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ เนื่องจากมีการเปลี่ยนแปลงในโฟลเดอร์ MEGA คุณสามารถหยุดการซิงค์หรือสำรองข้อมูลและลองตั้งค่าใหม่ในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. พบปัญหาในการซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ ให้หยุดการซิงค์หรือสำรองข้อมูล แล้วลองตั้งค่าอีกครั้งในแอปเดสก์ท็อป หรือติดต่อฝ่ายสนับสนุน - ไม่สามารถซิงค์โฟลเดอร์นี้ได้เนื่องจากอยู่ในโฟลเดอร์ที่มีการซิงค์อยู่แล้ว + Folder can’t be synced as it’s already inside a synced folder การอัปโหลดจากกล้องปิดใช้งานอยู่ @@ -157,7 +157,7 @@ ไม่มีการเชื่อมต่ออินเทอร์เน็ต - ไฟล์ในโฟลเดอร์นี้ไม่สามารถซิงค์หรือสำรองข้อมูลได้ คุณต้องเปิดใช้งานการซิงค์หรือการสำรองข้อมูลใหม่จากแอปบนเดสก์ท็อปก่อน + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. ยังไม่ได้ตั้งค่าอะไรเลย diff --git a/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml index 23277d37f0..74228d0fab 100644 --- a/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA không thể đồng bộ hoặc sao lưu thư mục này bởi vì hệ thống tệp trên thiết bị của bạn không được hỗ trợ. + MEGA can’t sync or backup this folder because the file system on your device is not supported Thư mục bạn đã chọn không thể đồng bộ được @@ -71,33 +71,33 @@ Vượt mức giới hạn không gian lưu trữ. - Không thể đồng bộ hóa hoặc sao lưu thư mục này vì gói đăng ký của bạn đã hết hạn. + Không thể đồng bộ hóa hoặc sao lưu thư mục này vì gói đăng ký của bạn đã hết hạn - Thư mục không thể đồng bộ được do tài khoản của người chia sẻ thư mục này đã vượt mức băng thông lưu trữ. + Folder can’t be synced as the user who shared this folder has reached their storage quota Không tìm thấy vị trí của thư mục trên MEGA, có thể do đã bị di chuyển hoặc bị xóa, cũng có thể là bạn không có quyền truy cập. - Thư mục không thể đồng bộ được bởi vì thư mục đã chia sẻ mà không có cấp quyền hạn truy cập toàn quyền. + Folder can’t be synced as it’s a shared folder without full access - Các tệp tin trong thư mục này không thể đồng bộ hóa hoặc sao lưu được. Bạn sẽ cần phải kích hoạt lại đồng bộ hoặc sao lưu từ ứng dụng cho máy tính. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - Thư mục không thể đồng bộ được bởi vì nó đang nằm ở trong một thư mục được đồng bộ. + Thư mục không thể đồng bộ được bởi vì nó đang nằm ở trong một thư mục được đồng bộ - MEGA không thể đồng bộ hóa hoặc sao lưu các thư mục VirtualBox. + MEGA không thể đồng bộ hóa hoặc sao lưu các thư mục VirtualBox - Không thể đồng bộ hóa hoặc sao lưu thư mục này vì tài khoản của bạn đã bị chặn. + Không thể đồng bộ hóa hoặc sao lưu thư mục này vì tài khoản của bạn đã bị chặn - Có sự cố khi đồng bộ hóa hoặc sao lưu thư mục này. Thử lại sau. Nếu sự cố vẫn tiếp diễn, hãy liên hệ với bộ phận Hỗ trợ. + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. Đã tải lại tài khoản. Mọi cập nhật bị bỏ lỡ đối với các bản sao lưu hoặc đồng bộ hóa của bạn chưa có được áp dụng. - Đồng bộ hóa hoặc sao lưu đã bị dừng do có vẻ như bạn đã đăng xuất khỏi Ứng dụng cho máy tính. Đăng nhập vào lại Ứng dụng cho máy tính để tiếp tục đồng bộ hóa hoặc sao lưu. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A Không tìm thấy vị trí của thư mục trong ổ đĩa ngoài. - Đã có một thư mục được đồng bộ hóa với cùng đường dẫn. + There’s already a synced folder at the same path Đổi tên không thành công. @@ -105,7 +105,7 @@ Không thể đọc cấu hình đồng bộ hóa. Thử lại sau hoặc kiểm tra quyền hạn của thư mục. - Không rõ đường dẫn ổ đĩa cho đồng bộ này. + Sync folder location is unknown Khoảng thời gian quét khởi đầu không hợp lệ. Kiểm tra thiết lập khoảng thời gian quét và thử lại. @@ -125,17 +125,17 @@ Something went wrong. - Thư mục không thể đồng bộ hoặc tạo sao lưu được bởi vì thư mục tương ứng trên MEGA đang nằm trong Thùng Rác. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Hiện không thể định vị được thư mục trong thiết bị của bạn, hãy thử lại sau. Không tìm thấy vị trí của thư mục trong thiết bị của bạn - Có sự cố đồng bộ hóa hoặc sao lưu thư mục này do các thay đổi của thư mục MEGA. Dừng đồng bộ hóa hoặc sao lưu và thử thiết lập lại trong app đành cho máy tính hoặc liên hệ với bộ phận Hỗ trợ. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. Có sự cố khi đồng bộ hóa hoặc sao lưu thư mục này. Hãy thử dừng đồng bộ hóa hoặc sao lưu và thử thiết lập lại trong Ứng dụng cho máy tính hoặc liên hệ với bộ phận Hỗ Trợ. - Thư mục không thể đồng bộ được bởi vì nó đang nằm ở trong một thư mục được đồng bộ. + Folder can’t be synced as it’s already inside a synced folder Đăng tải camêra đã tắt @@ -157,7 +157,7 @@ Không có kết nối internet - Các tệp tin trong thư mục này không thể đồng bộ hóa hoặc sao lưu được. Bạn sẽ cần phải kích hoạt lại đồng bộ hoặc sao lưu từ ứng dụng cho máy tính. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Chưa có gì được thiết lập diff --git a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml index d747f0a7ea..fe50f9c970 100644 --- a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA无法同步或备份此文件夹,因为尚不支持您设备上的文件系统。 + MEGA can’t sync or backup this folder because the file system on your device is not supported 您选择的文件夹无法同步 @@ -71,33 +71,33 @@ 已达到存储配额限制。 - 由于您的会员方案已过期,因此无法同步或备份此文件夹。 + Unable to sync or back up this folder as your plan has expired - 无法同步文件夹,因为共享此文件夹的用户已达到其存储配额上限。 + Folder can’t be synced as the user who shared this folder has reached their storage quota MEGA中的文件夹已被移动或删除,因此无法定位,或者您可能没有访问权限。 - 无法同步文件夹,因为它是没有完全访问权限的共享文件夹。 + Folder can’t be synced as it’s a shared folder without full access - 无法同步或备份此文件夹中的文件。您需要从桌面应用程序重新启用同步或备份。 + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. - 无法同步文件夹,因为它已经包含已同步的文件夹。 + Folder can’t be synced as it already contains synced folders - MEGA无法同步或备份VirtualBox文件夹。 + MEGA can’t sync or back up VirtualBox folders - 由于该帐户已被封锁,无法同步或备份此文件夹。 + Unable to sync or back up this folder as the account has been blocked - 同步或备份此文件夹时出现问题。请稍后再试。如果问题仍然存在,请联系支持部门。 + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. 帐户已重新加载。对备份或同步的任何更新尚未应用。 - 由于您似乎已登出桌面应用程序,因此同步或备份已停止。通过桌面应用程序重新登录,然后恢复同步或备份。 + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A 无法定位外部驱动器中的文件夹。 - 同一路径上已经有一个同步文件夹。 + There’s already a synced folder at the same path 重命名失败。 @@ -105,7 +105,7 @@ 无法读取同步配置。稍后重试或检查文件夹权限。 - 同步的的驱动器路径未知。 + Sync folder location is unknown 扫描间隔无效。请检查扫描间隔设置,然后重试。 @@ -125,17 +125,17 @@ Something went wrong. - 由于MEGA文件夹位于回收站中,文件夹无法同步或备份。 + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin 现在无法定位您设备中的文件夹,请稍后重试。 无法找到您设备中的文件夹 - 由于MEGA文件夹发生变动,同步或备份此文件夹时出现问题。请停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. 同步或备份此文件夹时出现问题。停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 - 无法同步文件夹,因为它已经在同步的文件夹中。 + Folder can’t be synced as it’s already inside a synced folder 相机上传已禁用 @@ -157,7 +157,7 @@ 无网络连接 - 无法同步或备份此文件夹中的文件。您需要从桌面应用程序重新启用同步或备份。 + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. 尚未设置任何内容 diff --git a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml index 8dbb044555..a45869960f 100644 --- a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - 因為不支援您裝置上的檔案系統,MEGA無法同步或備份此資料夾。 + MEGA無法同步或備份此資料夾,因為尚不支援您裝置上的檔案系統。 您選擇的資料夾無法同步 @@ -71,23 +71,23 @@ 已達到儲存配額限制。 - 由於您的方案已到期,因此無法同步或備份此資料夾。 + 由於您的方案已過期,因此無法同步或備份此資料夾。 - 無法同步資料夾,因為共享此資料夾的使用者已達到其儲存配額。 + Folder can’t be synced as the user who shared this folder has reached their storage quota 無法找到MEGA中的資料夾,因為它已被移動或刪除,或者您可能無權權存取。 - 無法同步資料夾,因為它是一個沒有完全存取權限的共享資料夾,。 + Folder can’t be synced as it’s a shared folder without full access - 無法同步或備份此資料夾中的檔案。您需要從桌面應用程式重新啟用同步或備份。 + 此資料夾中的檔案無法同步或備份。您需要從桌面應用程式重新啟用同步或備份。 - 無法同步資料夾,因為資料夾已包含同步的資料夾,。 + 資料夾無法同步,因為它已經包含同步的資料夾 - MEGA無法同步或備份VirtualBox資料夾。 + MEGA無法同步或備份VirtualBox資料夾 - 由於帳戶已被封鎖,因此無法同步或備份此資料夾。 + 由於帳戶已被封鎖,因此無法同步或備份此資料夾 - 同步或備份此資料夾時出現問題。稍後再試。如果問題仍然存在,請聯繫客服。 + Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 @@ -97,7 +97,7 @@ 無法找到外部磁碟的資料夾。 - 同一路徑下已經有一個同步資料夾。 + There’s already a synced folder at the same path 重新命名失敗。 @@ -105,7 +105,7 @@ 無法讀取同步設定。稍後再試或檢查資料夾權限。 - 同步的磁碟路徑未知。 + Sync folder location is unknown 掃描間隔無效。檢查掃描間隔設定並且重試。 @@ -125,17 +125,17 @@ Something went wrong. - 由於MEGA資料夾位於垃圾筒中,因此無法進行資料夾同步或備份。 + 由於MEGA資料夾位於垃圾筒中,因此資料夾無法同步或備份 現在無法找到您裝置中的資料夾,請稍後重試。 無法找到您裝置中的資料夾 - 由於MEGA資料夾發生變動,因此同步或備份此資料夾時出現問題。請停止同步或備份,然後嘗試在桌面應用程式中再次設定,或聯繫客服。 + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. 同步或備份此資料夾時出現問題。停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 - 由於資料夾已位於同步的資料夾中,因此無進行同步。 + 資料夾無法同步,因為它已經在同步資料夾中 相機上傳已停用 @@ -157,7 +157,7 @@ 無網路連線 - 無法同步或備份此資料夾中的檔案。您需要從桌面應用程式重新啟用同步或備份。 + 此資料夾中的檔案無法同步或備份。您需要從桌面應用程式重新啟用同步或備份。 尚未設定任何內容 diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 8f2c8048cd..74e4154930 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -9,9 +9,9 @@ مزامنة [A](%1$d)[/A] - نحتاج إلى الوصول إلى مساحة تخزين جهازك لمزامنة المجلد المحلي الخاص بك. انقر هنا لمنح حق الوصول. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - لمزامنة ملفاتك ومجلداتك باستمرار اسمح بتشغيل ميغا MEGA في الخلفية. + To continuously sync your files and folders, allow MEGA to run in the background %d ملف @@ -123,7 +123,7 @@ شبكة الوايرلس فقط - ستحتاج إلى إعداد مجلد محلي على جهازك يتزامن مع المجلد المختار على السواقة السحابية. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive مزامنة المراقبة diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index e69e81504f..2bd7dcd43e 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronisierungen [A](%1$d)[/A] - Um Ihren lokalen Ordner zu synchronisieren, müssen wir auf Ihren Gerätespeicher zugreifen. Tippen Sie hier, um Zugriff zu gewähren. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - Um Ihre Dateien und Ordner fortlaufend zu synchronisieren, erlauben Sie das Ausführen von MEGA im Hintergrund. + To continuously sync your files and folders, allow MEGA to run in the background %d Datei @@ -107,7 +107,7 @@ Nur via WLAN - Sie müssen einen lokalen Ordner auf Ihrem Gerät \neinrichten, der mit einem ausgewählten Ordner in \nIhrem Cloud Drive synchronisiert wird. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Synchronisierungsüberwachung diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index 0a50c16400..333e3c713b 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -9,9 +9,9 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to grant access. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - To continuously sync your files and folders, allow MEGA to run in the background. + To continuously sync your files and folders, allow MEGA to run in the background %d archivo @@ -111,7 +111,7 @@ Solo Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Monitoring syncs diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index 66a54f6609..20d29bdf4c 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronisations [A](%1$d)[/A] - Nous devons accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour accorder l’accès. + Nous devons accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour autoriser l’accès. - Afin de synchroniser en permanence vos fichiers et dossiers, autorisez MEGA à fonctionner en arrière-plan. + Afin de synchroniser en permanence vos fichiers et dossiers, autorisez MEGA à fonctionner en arrière-plan %d fichier @@ -187,7 +187,7 @@ Plusieurs éléments du même nom d’un côté de votre synchronisation deviendraient le même élément de l’autre côté de votre synchronisation - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + Un déplacement ou un renommage a été détecté sur MEGA, mais n’a pas pu être reproduit localement. Un déplacement ou un renommage a été détecté localement, mais n’a pas pu être reproduit sur MEGA. diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index 3e2a0c829a..541818a375 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -9,9 +9,9 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to grant access. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - To continuously sync your files and folders, allow MEGA to run in the background. + To continuously sync your files and folders, allow MEGA to run in the background %d file @@ -103,7 +103,7 @@ Hanya Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Monitoring syncs diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index 30289122f8..ab70fe4547 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -9,9 +9,9 @@ Sincronizzazioni [A](%1$d)[/A] - Abbiamo bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per dare l\’accesso + Abbiamo bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per dare l\’accesso. - Per sincronizzare in modo continuo i tuoi file e le tue cartelle, permetti a MEGA di operare in background. + Per sincronizzare in modo continuo i tuoi file e le tue cartelle, permetti a MEGA di operare in background %d file @@ -111,7 +111,7 @@ Solo Wi-Fi - Dovrai impostare una cartella locale su tuo\ndispositivo che sarà sincronizzata con una cartella scelta sul\ntuo Cloud Drive. + Dovrai impostare una cartella locale su tuo dispositivo che sarà sincronizzata con una cartella scelta sul tuo Cloud Drive Monitorizzazione delle sincronizzazioni @@ -187,7 +187,7 @@ Ci sono più oggetti con lo stesso nome da un lato della sincronizzazione che diverrebbero tutti lo stesso oggetto dall\’altro lato della sincronizzazione - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + MEGA ha riscontrato un\’azione di spostamento o di rinominazione, ma non riesce a ripeterla localmente. Localmente è stato riscontrato uno spostamento o una rinominazione, ma è impossibile da replicare su MEGA. diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index 0f48020365..84eef5d252 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -11,7 +11,7 @@ ローカルフォルダを同期するには、お使いのデバイスのストレージにアクセスする必要があります。こちらをタップしてアクセスを許可してください。 - ファイルとフォルダを継続的に同期するには、MEGAをバックグラウンドで実行できるようにします。 + ファイルとフォルダを継続的に同期するには、MEGAをバックグラウンドで実行できるようにします %d 個のファイル @@ -103,7 +103,7 @@ Wi-Fiのみ - クラウドドライブ上の選択したフォルダと\n同期するローカルフォルダを、デバイス上に\n設定する必要があります。 + クラウドドライブ上の選択されたフォルダと同期するローカルフォルダを、デバイス上に設定する必要があります。 同期の監視 diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index bbe1df7663..859a3eabe9 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -9,9 +9,9 @@ 동기화 [A](%1$d)[/A] - 당신의 로컬 폴더를 동기화하기 위해 장치 저장소에 접근이 필요합니다. 접근을 승인하려면 여기를 탭하세요 + We need to access your device storage in order to sync your local folder. Tap here to allow access. - 파일과 폴더를 계속 동기화하려면, MEGA가 백그라운드에서 작동하도록 허용하세요. + To continuously sync your files and folders, allow MEGA to run in the background %d개의 파일 @@ -103,7 +103,7 @@ 와이파이 전용 - 당신의 클라우드 드라이브에서\n선택한 폴더와 동기화할 장치의 로컬 폴더를\n설정해야 합니다. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive 동기화 감시 중 diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index a8720e91ee..228c862502 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronisaties [A](%1$d)[/A] - We hebben toegang tot de opslag van uw apparaat nodig om uw lokale map te kunnen synchroniseren. Tik hier om toegang te verlenen. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - Om uw bestanden en mappen continu te synchroniseren, kunt u MEGA op de achtergrond laten draaien. + To continuously sync your files and folders, allow MEGA to run in the background %d bestand @@ -107,7 +107,7 @@ Alleen Wi-Fi - U moet een lokale map op uw \napparaat instellen die wordt gesynchroniseerd met een gekozen map op \nuw clouddrive. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Synchronisaties toezien diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index da1340a8b2..bbb0ea586b 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronizacja [A](%1$d)[/A] - Aby zsynchronizować katalog lokalny, musimy uzyskać dostęp do pamięci urządzenia. Wybierz tutaj, aby przyznać dostęp. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - Aby stale synchronizować pliki i katalogi, pozwól MEGA działać w tle. + To continuously sync your files and folders, allow MEGA to run in the background %d plik @@ -115,7 +115,7 @@ Tylko Wi-Fi - Konieczne będzie skonfigurowanie lokalnego\n katalogu na urządzeniu, który będzie synchronizowany z wybranym katalogiem \nna dysku w chmurze. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Monitorowanie synchronizacji diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index 6fa7c528a7..844e6a1eaf 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -11,7 +11,7 @@ Nós precisamos acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque aqui para permitir o acesso - Para a sincronização contínua dos seus arquivos e das suas pastas, permita que o MEGA seja executado em segundo plano. + Para a sincronização contínua dos seus arquivos e das suas pastas, permita que o MEGA seja executado em segundo plano %d arquivo @@ -111,7 +111,7 @@ Somente Wi-Fi - Você precisará configurar uma pasta local no seu\ndispositivo que será sincronizada com uma pasta da\nsua Nuvem de arquivos. + Você precisará configurar uma pasta local no seu dispositivo que será sincronizada com uma pasta da sua Nuvem de arquivos Monitorando sincronizações diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index 847eb3063f..9dfbe7a217 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -9,9 +9,9 @@ Sincronizări [A](%1$d)[/A] - Trebuie să accesăm spațiul de stocare al dispozitivului pentru a vă sincroniza folderul local. Atingeți aici pentru a acorda acces. + Trebuie să accesăm spațiul de stocare al dispozitivului pentru a vă sincroniza folderul local. Atingeți aici pentru a permite accesul. - Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal. + Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal %d fișier @@ -111,7 +111,7 @@ Numai Wi-Fi - Va trebui să configurați un folder local pe\ndispozitivul dvs. care se va sincroniza cu un folder ales de pe \nUnitatea dvs. cloud. + Va trebui să configurați un folder local pe dispozitivul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud Monitorizarea sincronizărilor @@ -187,7 +187,7 @@ Există mai multe elemente cu același nume pe o parte a sincronizării dvs. care ar deveni toate același element unic pe cealaltă parte a sincronizării - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + O mutare sau redenumire a fost detectată în MEGA, dar nu a putut fi replicată local. O mutare sau redenumire a fost detectată la nivel local, dar nu a putut fi reprodusă în MEGA. diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index 56ef4d5fff..e80ef3c997 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -9,9 +9,9 @@ Синхронизации [A](%1$d)[/A] - Нам нужен доступ к памяти устройства, чтобы синхронизировать локальную папку. Нажмите здесь, чтобы предоставить доступ. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - Чтобы непрерывно синхронизировать файлы и папки, разрешите MEGA работать в фоновом режиме. + To continuously sync your files and folders, allow MEGA to run in the background %d файл @@ -115,7 +115,7 @@ Только Wi-Fi - Вам нужно будет настроить локальную папку на устройстве, которая будет синхронизироваться с выбранной папкой на Облачном диске. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Отслеживание синхронизаций diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index 1bb95dcf0a..ca049e6929 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -9,9 +9,9 @@ ซิงค์ [A](%1$d)[/A] - เราจำเป็นต้องเข้าถึงไฟล์ในเครื่องของคุณ เพื่อซิงค์รายการเหล่านั้นกับอุปกรณ์อื่น ๆ แตะที่นี่เพื่ออนุญาตให้เราเข้าถึง + We need to access your device storage in order to sync your local folder. Tap here to allow access. - เพื่อให้การซิงค์ไฟล์และโฟลเดอร์ของคุณเป็นไปอย่างต่อเนื่อง คุณต้องอนุญาตให้ MEGA ทำงานในเบื้องหลัง + To continuously sync your files and folders, allow MEGA to run in the background %d ไฟล์ @@ -103,7 +103,7 @@ Wi-Fi เท่านั้น - คุณต้องสร้างโฟลเดอร์ในอุปกรณ์ของคุณ\nที่จะซิงค์กับโฟลเดอร์ที่เลือก\nบนคลาวด์ไดร์ฟของคุณ + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive กำลังติดตามสถานะการซิงค์ diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 371c9ee82c..deac2dc0d9 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -9,9 +9,9 @@ Đồng bộ [A](%1$d)[/A] - Chúng tôi cần truy cập bộ nhớ thiết bị để đồng bộ hóa thư mục cục bộ của bạn. Chạm vào đây để cấp quyền truy cập. + We need to access your device storage in order to sync your local folder. Tap here to allow access. - Để liên tục đồng bộ hóa các tệp tin và thư mục của bạn, cho phép MEGA chạy trong nền. + To continuously sync your files and folders, allow MEGA to run in the background %d tệp tin @@ -103,7 +103,7 @@ Chỉ lúc dùng Wi-Fi - Bạn sẽ cần thiết lập một thư mục cục bộ trên thiết bị của mình sẽ đồng bộ hóa với một thư mục chọn ra trên Ổ Mây của bạn. + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive Đang giám sát các đồng bộ diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index 6a21302cd1..a05bdca570 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -9,9 +9,9 @@ 同步[A](%1$d)[/A] - 我们需要访问您设备的存储空间,才能同步您的本地文件夹。点按此处以授予访问权限。 + 我们需要访问您设备的存储空间,才能同步您的本地文件夹。点按此处以允许访问。 - 若要持续同步您的文件和文件夹,请允许MEGA在后台运行。 + 若要持续同步您的文件和文件夹,请允许MEGA在后台运行 %d个文件 @@ -103,7 +103,7 @@ 仅限Wi-Fi - 您需要在您的\n设备上设置一个本地文件夹,它将与\n您云盘的选定文件夹同步。 + 您需要在您的设备上设置一个本地文件夹,该文件夹将与您云盘上的选定文件夹同步 监控同步 @@ -179,7 +179,7 @@ 同步的一侧具有多个相同名称的项目,这些项目在同步的另一侧都将成为相同的单一项目 - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + 在MEGA中检测到移动或重命名操作,但无法在本地重现。 检测到本地发生的移动或重命名,但无法在MEGA中复制。 diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 579948df23..7506d6d607 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -9,9 +9,9 @@ 同步[A](%1$d)[/A] - 我們需要存取您的裝置儲存空間,以便同步您的本地資料夾。點選此處以授予存取權限。 + We need to access your device storage in order to sync your local folder. Tap here to allow access. - 若要持續同步您的檔案和資料夾,請允許MEGA在背景執行。 + To continuously sync your files and folders, allow MEGA to run in the background %d個檔案 @@ -103,7 +103,7 @@ 只在WiFi連線 - 您需要在\n裝置上設定一個本地資料夾,該資料夾將與\n您雲端硬碟上選定的資料夾同步。 + You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive 監控同步 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 786f0d8018..c0a254fc99 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -1,7 +1,7 @@ - No sync error + لا يوجد خطأ في المزامنة MEGA can’t sync or backup this folder because the file system on your device is not supported @@ -43,13 +43,13 @@ There’s already a synced folder at the same location - فشلت عملية إعادة التسمية. + Renaming failed Couldn’t create a .megaignore file for this sync تعذرت قراءة تكوين المزامنة. حاول مرة أخرى لاحقًا أو تحقق من أذونات المجلد. - مسار سواقة المزامنة غير معروف. + Sync location is unknown الفاصل الزمني للفحص غير صالح. تحقق من إعداد الفاصل الزمني للفحص وحاول مرة أخرى. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + حافظ على خصوصيتك على الإنترنت من خلال في بي إن VPN عالي السرعة. + + مكالمات واجتماعات غير مقيدة + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index de1ec3e906..e3a221af49 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -43,13 +43,13 @@ Es gibt bereits einen synchronisierten Ordner an demselben Ort - Die Umbenennung ist fehlgeschlagen. + Renaming failed Für diese Synchronisierung konnte keine .megaignore-Datei erstellt werden Synchronisierungskonfigurationen konnten nicht vom Laufwerk gelesen werden. - Laufwerkspfad der Synchronisierung ist unbekannt + Sync location is unknown Ungültiges Scan-Intervall @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Surfen Sie unerkannt mit unserem schnellen VPN. + + Keine Anruf- und Meeting-Beschränkungen + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index df38fa9646..1ccfe85c71 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -43,19 +43,19 @@ There’s already a synced folder at the same location - Error al cambiar el nombre. + Renaming failed Couldn’t create a .megaignore file for this sync Couldn’t read sync configuration. Try again later or check folder permissions. - Se desconoce la ruta de la unidad de sincronización. + Sync location is unknown Intervalo de escaneo no válido. Comprueba la configuración del intervalo de escaneo e inténtalo de nuevo. No se ha podido comunicar con la ubicación de la carpeta. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + No se puede añadir una vigilancia del sistema de archivos. Asegúrate de que haya suficiente espacio libre y suficiente memoria y de que los permisos para la ubicación de la carpeta estén concedidos. No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. @@ -65,7 +65,7 @@ No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - An unknown error occurred. Contact Support. + Se ha producido un error. Ponte en contacto con soporte. Something went wrong. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Protege tu seguridad en línea con nuestra VPN de alta velocidad. + + Llamadas y reuniones sin restricciones + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index d46cd915b4..df12180a89 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -1,9 +1,9 @@ - No sync error + Aucune erreur de synchronisation - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge Le dossier que vous avez choisi ne peut pas être synchronisé @@ -43,13 +43,13 @@ Un dossier synchronisé porte déjà ce nom dans le même chemin - Échec de renommage. + Échec de renommage Impossible de créer un fichier .megaignore pour cette synchronisation Impossible de lire la configuration de la synchronisation. Réessayez ultérieurement ou vérifiez les droits du dossier. - Le chemin du lecteur de la synchronisation est inconnu. + L’emplacement de la synchronisation est inconnu L’intervalle d’analyse est invalide. Vérifiez la configuration de l’intervalle d’analyse et réessayez. @@ -69,7 +69,7 @@ Un problème est survenu - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Le dossier ne peut ni être synchronisé ni sauvegardé, car le dossier MEGA est dans la Corbeille Impossible de trouver le dossier sur votre appareil. Réessayez plus tard. @@ -79,9 +79,25 @@ Problème de synchronisation ou de sauvegarde de ce dossier. Arrêtez la synchronisation ou la sauvegarde, puis tentez de la définir de nouveau dans l’appli pour ordinateur ou contactez l’assistance. - Folder can’t be synced as it’s already inside a synced folder + Le dossier ne peut pas être synchronisé, car il fait déjà partie d’un dossier synchronisé Les fichiers de ce dossier ne peuvent être ni synchronisés ni sauvegardés. Vous devez réactiver la synchronisation ou la sauvegarde dans l’appli pour ordinateur. - Syncing paused, battery level too low. Charge battery to resume syncing. + La synchronisation est en pause, car le niveau de batterie est trop faible. Chargez la batterie pour reprendre la synchronisation. + + Un partage de fichiers simple et sécurisé + + Partagez des fichiers volumineux grâce à un quota de transfert généreux et garantissez la sécurité avec des liens protégés par mot de passe. + + Ne plus jamais perdre de données + + Ayez l’esprit tranquille en sauvegardant et synchronisant vos données. De plus, le Retour en arrière vous permet de rétablir n’importe quelle version antérieure de vos dossiers, jusqu’à 180 jours. + + RPV MEGA VPN + + Protégez votre vie privée en ligne grâce à notre RPV à haut débit + + Appels et réunions sans restrictions + + Les réunions, les messages et les appels vidéo sont entièrement privés et protégés, avec un nombre illimité de participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 50ba41ccf9..dae2c40380 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -43,19 +43,19 @@ There’s already a synced folder at the same location - Mengganti nama gagal. + Renaming failed Couldn’t create a .megaignore file for this sync Couldn’t read sync configuration. Try again later or check folder permissions. - Jalur drive Sync tidak diketahui. + Sync location is unknown Interval pemindaian tidak valid. Periksa pengaturan interval pemindaian dan coba lagi. Tidak dapat berkomunikasi dengan lokasi folder. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Tidak dapat menambahkan pengawasan sistem file. Pastikan ada ruang kosong dan memori yang cukup, dan bahwa anda telah memberikan izin untuk lokasi folder. Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Tetap pribadi saat online dengan VPN berkecepatan tinggi kami. + + Panggilan dan rapat tanpa batas + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 6c74752e18..aceb4f5558 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -3,55 +3,55 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato La cartella che hai scelto non può essere sincronizzata Un file non può essere sincronizzato individualmente. Devi impostare la sincronizzazione di una cartella. - Scansione iniziale fallita. Dovrai riattivare la tua sincronizzazione o il tuo backup dall\’app per desktop. + Scansione iniziale fallita. Dovrai riattivare la tua sincronizzazione o il tuo backup dall’app per desktop. - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + La cartella in MEGA non può essere trovata perché è stata eliminata o spostata, o potresti non avere accesso ad essa - Unable to sync or back up this folder as your storage is full + Impossibile sincronizzare o effettuare il backup perché il tuo spazio di archiviazione è pieno - Unable to sync or back up this folder as your plan has expired + Impossibile sincronizzare o effettuare il backup perché il tuo piano è scaduto - Folder can’t be synced as the user who shared this folder has reached their storage limit + La cartella non può essere sincronizzata poiché l\’utente che ha condiviso questa cartella ha raggiunto il limite del suo spazio di archiviazione - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + La cartella in MEGA non può essere trovata perché è stata eliminata o spostata, o potresti non avere accesso ad essa - Folder can’t be synced as it’s a shared folder that you don’t have full access to + La cartella non può essere sincronizzata perché è una cartella condivisa a cui non hai pieno accesso - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. - Folder can’t be synced as it already contains synced folders + La cartella non può essere sincronizzata perché già contiene cartelle sincronizzate - MEGA can’t sync or back up VirtualBox folders + MEGA non è in grado di sincronizzare o eseguire il backup delle cartelle VirtualBox - Unable to sync or back up this folder as the account has been blocked + Impossibile sincronizzare o effettuare il backup di questa cartella perché l\’account è stato bloccato Problema nella sincronizzazione o nel backup di questa cartella. Riprova più tardi. Se il problema persiste, contatta il Supporto. Account ricaricato. Qualsiasi aggiornamento mancato ai tuoi backup o alle tue sincronizzazioni non è stato applicato. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + La sincronizzazione o il backup è stato fermato perché sembra che tu abbia effettuato il logout dall\’app per desktop. Effettua nuovamente l\’accesso tramite l\’app per desktop, e riprendi la sincronizzazione o il backup. N/A La cartella nel drive esterno non può essere trovata. - There’s already a synced folder at the same location + C\’è già una cartella sincronizzata nella stessa posizione - Rinominazione fallita. + Rinominazione fallita - Couldn’t create a .megaignore file for this sync + Impossibile creare un file .megaignore per questa sincronizzazione Impossibile leggere la configurazione della sincronizzazione. Riprova più tardi o controlla le autorizzazioni della cartella. - Il percorso della sincronizzazione è sconosciuto. + Sync location is unknown - Intervallo della scansione invalido. Controlla l\’impostazione dell\’intervallo della scansione e riprova. + Intervallo della scansione invalido. Controlla l’impostazione dell’intervallo della scansione e riprova. Impossibile comunicare con la cartella della posizione. Controlla che la posizione sia accessibile e i permessi per la cartella della posizione siano garantiti. @@ -61,27 +61,43 @@ Unable to open state cache database - Insufficient storage space on your device + Spazio di archiviazione insufficiente sul tuo dispositivo Impossibile leggere la posizione della sincronizzazione. Controlla che la posizione sia accessibile e i permessi per la cartella della posizione siano garantiti. - An unknown error occurred. Contact Support. + Si è verificato un errore sconosciuto. Contatta il supporto. Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino - Folder in your device can’t be located right now. Try again later. + La cartella nel tuo dispositivo non può essere trovata. Riprova più tardi. La cartella nel dispositivo non può essere localizzata - Problemi durante la sincronizzazione o il backup di questa cartella a causa di modifiche alla cartella MEGA. Interrompi la sincronizzazione o il backup e prova a configurarli nuovamente nell\’app desktop oppure contatta il Supporto. + Problemi durante la sincronizzazione o il backup di questa cartella a causa di modifiche alla cartella MEGA. Interrompi la sincronizzazione o il backup e prova a configurarli nuovamente nell’app desktop oppure contatta il Supporto. - Problemi nella sincronizzazione o nel backup di questa cartella. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente dall\’app per desktop, o contatta il Supporto. + Problemi nella sincronizzazione o nel backup di questa cartella. Ferma la sincronizzazione o il backup e prova ad impostarlo nuovamente dall’app per desktop, o contatta il Supporto. - Folder can’t be synced as it’s already inside a synced folder + La cartella non può essere sincronizzata in quanto è già dentro una cartella sincronizzata - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. - Syncing paused, battery level too low. Charge battery to resume syncing. + Sincronizzazione interrotta, livello della batteria troppo basso. Carica la batteria per riprendere la sincronizzazione. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Rimani nel privato anche quando sei online grazie alla nostra VPN ad alta velocità. + + Chiamate e meeting senza limiti + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 5296bffd0c..6c681e36b9 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -1,7 +1,7 @@ - No sync error + 同期エラーはありません デバイスのファイルシステムがサポートされていないため、MEGAはこのフォルダを同期またはバックアップできません @@ -43,13 +43,13 @@ 同じ場所に同期フォルダがすでに存在します - 名前の変更に失敗しました。 + 名前の変更に失敗しました この同期用の.megaignoreファイルを作成できませんでした 同期構成を読み取れませんでした。後でもう一度試すか、フォルダのアクセス許可を確認してください。 - 同期のドライブパスが不明です。 + 同期場所が不明です 無効なスキャン間隔です。スキャン間隔の設定を確認して、再試行してください。 @@ -79,9 +79,25 @@ このフォルダの同期またはバックアップ中に問題が発生しました。同期またはバックアップを停止し、デスクトップアプリでもう一度設定してみるか、サポートにお問い合わせください。 - パスの上にアクティブな同期 + フォルダは、すでに同期フォルダ内にあるため同期できません このフォルダ内のファイルは同期またはバックアップできません。デスクトップアプリから同期またはバックアップを再度有効にする必要があります。 同期が一時停止されました。バッテリー残量が少なすぎます。同期を再開するにはバッテリーを充電してください。 + + 簡単で安全なファイル共有 + + 十分な転送容量により大容量ファイルを共有し、パスワードで保護されたリンクによりセキュリティを確保できます。 + + 二度とデータを失わない + + データをバックアップして同期すると、完全に自信が持てます。さらに、巻き戻しを使用すると、フォルダを最大180日以内の任意の日付に復元できます。 + + MEGA VPN + + 当社の高速VPNでオンラインでのプライバシーを確​​保 + + 無制限の通話とミーティング + + メッセージ、ビデオ通話、完全プライバシーで無制限の参加者とミーティングができます。 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 4f6334b616..43df97828e 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -43,13 +43,13 @@ 같은 위치에 이미 동기화된 폴더가 있습니다. - 이름 변경 실패. + Renaming failed 이 동기화를 위한 .megaignore 파일을 만들 수 없습니다 동기화 설정을 읽을 수 없습니다. 나중에 다시 시도하거나 폴더 권한을 확인하세요. - 동기화 드라이브 경로를 알 수 없습니다. + Sync location is unknown 잘못된 탐색 간격. 탐색 간격 설정을 확인하고 다시 시도하세요. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + 우리의 고속 VPN으로 온라인에서 개인 정보를 지키세요. + + 제한 없는 통화와 회의 + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index f7e051244e..64b2476b72 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -1,7 +1,7 @@ - No sync error + Geen synchronisatiefout MEGA can’t sync or backup this folder because the file system on your device is not supported @@ -43,17 +43,17 @@ Er is al een gesynchroniseerde map op dezelfde lokatie - Hernoemen is mislukt. + Renaming failed Kon geen .megaignore bestand aanmaken voor deze synchronisatie Kon de synchronisatieconfiguratie niet lezen. Probeer het later opnieuw of controleer de mapmachtigingen. - Het schijfpad van Sync is onbekend. + Sync location is unknown Ongeldig scaninterval. Controleer de instellingen voor het scaninterval en probeer het opnieuw. - Did you mean: Couldn\’t communicate with the folder location. Check the location is accessible and permissions for the folder location are granted. Kan niet communiceren met de maplocatie. Controleer of de locatie toegankelijk is en of er machtigingen voor de maplocatie zijn verleend. + Did you mean: Couldn’t communicate with the folder location. Check the location is accessible and permissions for the folder location are granted. Kan niet communiceren met de maplocatie. Controleer of de locatie toegankelijk is en of er machtigingen voor de maplocatie zijn verleend. Kan geen bestandssysteembewaking toevoegen. Zorg ervoor dat er voldoende vrije ruimte en geheugen is en dat u machtigingen hebt verleend voor de maplocatie. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Blijf privé online met onze supersnelle VPN. + + Onbeperkt bellen en vergaderen + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 73935b3381..c6f14d58c0 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -43,17 +43,17 @@ W tej samej lokalizacji znajduje się już zsynchronizowany katalog - Zmiana nazwy nie powiodła się. + Renaming failed Nie można utworzyć pliku .megaignore dla tej synchronizacji Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. - Ścieżka dysku synchonizacji jest nieznana. + Sync location is unknown Nieprawidłowy interwał skanowania. Sprawdź ustawienia interwału skanowania i spróbuj ponownie. - Nie można nawiązać komunikacji z lokalizacją katalogu. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu.... + Nie można nawiązać komunikacji z lokalizacją katalogu. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu…. Nie można dodać obserwacji systemu plików. Upewnij się, że jest wystarczająco dużo wolnego miejsca i pamięci oraz że masz uprawnienia do lokalizacji katalogu. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Zachowaj prywatność online dzięki naszej szybkiej sieci VPN. + + Nieograniczone połączenia i spotkania + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index cd9e0b0c55..fe4379e5f6 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -1,7 +1,7 @@ - No sync error + Não há erros de sincronização O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado @@ -11,23 +11,23 @@ Falha no escaneio inicial. Você precisa reativar a sua sincronização ou o seu backup no aplicativo para desktop. - Não foi possível localizar a pasta no MEGA porque ela foi movida ou deletada, ou pode ser que você não tenha acesso a ela. + Não foi possível localizar a pasta no MEGA porque ela foi movida ou deletada, ou pode ser que você não tenha acesso a ela Não foi possível sincronizar ou fazer backup dessa pasta porque a sua conta está cheia - Não foi possível sincronizar ou fazer backup dessa pasta porque o seu plano expirou. + Não foi possível sincronizar ou fazer backup dessa pasta porque o seu plano expirou Não é possível sincronizar esta pasta porque a conta do usuário que a compartilhou alcançou o limite de armazenamento. Não foi possível localizar a pasta no MEGA porque ela foi movida ou deletada, ou pode ser que você não tenha acesso a ela. - Não é possível sincronizar esta pasta porque é uma pasta compartilhada à qual você não tem acesso total. + Não é possível sincronizar esta pasta porque é uma pasta compartilhada à qual você não tem acesso total Não foi possível sincronizar ou fazer backup dos arquivos nesta pasta. Você precisa reativar a sua sincronização ou o seu backup no aplicativo para desktop. - Não é possível sincronizar esta pasta porque ela contém pastas sincronizadas. + Não é possível sincronizar esta pasta porque ela contém pastas sincronizadas - O MEGA não pode sincronizar ou fazer backup das pastas do VirtualBox. + O MEGA não pode sincronizar ou fazer backup das pastas do VirtualBox Não foi possível sincronizar ou fazer backup dessa pasta porque a conta foi bloqueada @@ -41,15 +41,15 @@ Não é possível localizar a pasta na unidade externa. - Já existe uma pasta sincronizada no mesmo local. + Já existe uma pasta sincronizada no mesmo local - Não foi possível renomear. + Não foi possível renomear - Não foi possível criar um arquivo .megaignore para essa sincronização. + Não foi possível criar um arquivo .megaignore para essa sincronização Não foi possível ler a configuração da sincronização. Tente novamente mais tarde ou verifique as permissões da pasta. - O caminho da unidade de sincronização é desconhecido. + A localização da sincronização é desconhecida O intervalo de escaneado é inválido. Verifique a configuração do intervalo de escaneado e tente novamente. @@ -61,7 +61,7 @@ Não é possível abrir o banco de dados de cache de estado - Não há espaço de armazenamento suficiente no seu dispositivo. + Não há espaço de armazenamento suficiente no seu dispositivo Não foi possível ler a localização da sincronização. Verifique se o local está acessível e se as permissões para a localização da pasta foram concedidas. @@ -84,4 +84,20 @@ Não foi possível sincronizar ou fazer backup dos arquivos nesta pasta. Você precisa reativar a sua sincronização ou o seu backup no aplicativo para desktop. A sincronização foi pausada porque o nível da bateria está muito baixo. Carregue a bateria para retomar a sincronização. + + Compartilhamento de arquivos fácil e seguro + + Compartilhe arquivos grandes graças a uma ampla cota de transferência e garanta a segurança com links protegidos por senha. + + Nunca mais perca dados + + Faça backup e sincronize os seus dados para não correr riscos. Além disso, use a função Retroceder para fazer com que as suas pastas voltem ao estado que tinham em qualquer momento dos últimos 180 dias. + + MEGA VPN + + Mantenha a sua navegação online privada usando a nossa VPN de alta velocidade. + + Chamadas e reuniões sem restrições + + Envie mensagens, faça chamadas de vídeo e reuniões com privacidade total e um número ilimitado de participantes. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index d264079b35..e6d98a68c4 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat Folderul ales nu poate fi sincronizat @@ -11,45 +11,45 @@ Scanarea inițială a eșuat. Va trebui să reactivați sincronizarea sau backupul din aplicația desktop. - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + Folderul din MEGA nu poate fi localizat deoarece a fost mutat sau șters sau este posibil să nu aveți acces - Unable to sync or back up this folder as your storage is full + Nu se poate sincroniza sau backup pentru acest folder, deoarece spațiul de stocare este plin - Unable to sync or back up this folder as your plan has expired + Nu se poate sincroniza sau backup pentru acest folder, deoarece abonamentul dvs. a expirat - Folder can’t be synced as the user who shared this folder has reached their storage limit + Folderul nu poate fi sincronizat deoarece utilizatorul care a partajat acest folder a atins cotă de spațiu de stocare - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + Folderul din MEGA nu poate fi localizat deoarece a fost mutat sau șters sau este posibil să nu aveți acces - Folder can’t be synced as it’s a shared folder that you don’t have full access to + Folderul nu poate fi sincronizat deoarece este un folder partajat la care nu aveți acces complet - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + Fișierele din acest folder nu pot fi sincronizate sau backup-uite. Va trebui să reactivați sincronizarea sau backupul din aplicația desktop. - Folder can’t be synced as it already contains synced folders + Folderul nu poate fi sincronizat deoarece conține deja foldere sincronizate - MEGA can’t sync or back up VirtualBox folders + MEGA nu poate sincroniza sau face backup pentru folderele VirtualBox - Unable to sync or back up this folder as the account has been blocked + Nu se poate sincroniza sau face backup pentru acest folder, deoarece contul a fost blocat Problemă la sincronizarea sau backup a acestui folder. Încercați din nou mai târziu. Dacă problema persistă, contactați Asistența. Contul a fost reîncărcat. Toate actualizările ratate ale backupurilor sau ale sincronizărilor nu au fost aplicate. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Sincronizarea sau backupul au fost oprite pe măsură ce parcă v-ați deconectat de la aplicația desktop. Conectați-vă din nou prin aplicația desktop și reluați sincronizarea sau backup-ul. N/A Folderul din unitatea externă nu poate fi localizat. - There’s already a synced folder at the same location + Există deja un folder sincronizat în aceeași locație - Redenumirea a eșuat. + Redenumirea a eșuat - Couldn’t create a .megaignore file for this sync + Nu s-a putut crea un fişier .megaignore pentru această sincronizare Nu am putut citi configurația de sincronizare. Încercați din nou mai târziu sau verificați permisiunile folder. - Calea către unitatea de sincronizare este necunoscută. + Nu se cunoaște locația sincronizării Interval de analiză invalid. Verificați configurarea intervalului de analiză și încercați din nou. @@ -61,17 +61,17 @@ Unable to open state cache database - Insufficient storage space on your device + Spațiu de stocare insuficient pe dispozitiv Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. - An unknown error occurred. Contact Support. + A apărut o eroare necunoscută. Contactați asistența. Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folder in your device can’t be located right now. Try again later. + Folderul din dispozitiv nu poate fi localizat chiar acum. Încercați din nou mai târziu. Folderul din dispozitiv dvs. nu poate fi localizat @@ -79,9 +79,25 @@ Problemă la sincronizarea sau backup a acestui folder. Opriți sincronizarea sau backup-ul și încercați să o configurați din nou în aplicația Desktop sau contactați Asistența. - Folder can’t be synced as it’s already inside a synced folder + Folderul nu poate fi sincronizat, deoarece se află deja într-un folder sincronizat - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Fișierele din acest folder nu pot fi sincronizate sau backup-uite. Va trebui să reactivați sincronizarea sau backupul din aplicația desktop. - Syncing paused, battery level too low. Charge battery to resume syncing. + Sincronizarea întreruptă, nivelul bateriei prea scăzut. Încărcați bateria pentru a relua sincronizarea. + + Partajare de fișiere ușoară și sigură + + Partajați fișiere mari datorită unei cote generoase de transfer și asigurați securitatea cu link-uri protejate prin parolă. + + Nu pierdeți niciodată datele + + Fiți liniștit prin back-up și sincronizare a datelor. În plus, utilizați Derulează înapoi pentru a restabili folderele la orice dată de până la 180 de zile. + + MEGA VPN + + Rămâneți privat online cu VPN-ul nostru de mare viteză. + + Apeluri și întâlniri nerestricționate + + Întâlnirile, mesajele și apelurile video sunt complet private și protejate, cu un număr nelimitat de participanți. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index d1c97c70be..bbc07183c5 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -43,13 +43,13 @@ В том же расположении уже есть синхронизируемая папка - Не удалось переименовать. + Renaming failed Не удалось создать файл .megaignore для этой синхронизации Не удалось прочитать конфигурацию синхронизации. Повторите попытку позже или проверьте права доступа к папке. - Путь к диску синхронизации неизвестен. + Sync location is unknown Недействительный интервал сканирования. Проверьте настройку интервала сканирования и попробуйте ещё раз. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Онлайн-конфиденциальность со скоростным VPN. + + Неограниченные звонки и встречи + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 2e746e7857..cb4d146be4 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -43,13 +43,13 @@ There’s already a synced folder at the same location - การเปลี่ยนชื่อไม่สำเร็จ + Renaming failed Couldn’t create a .megaignore file for this sync ไม่สามารถอ่านการกำหนดค่าการซิงค์ได้ กรุณาลองใหม่ในภายหลังหรือตรวจสอบสิทธิ์ในโฟลเดอร์ของคุณอีกครั้ง - ไม่ทราบเส้นทางไดรฟ์ที่ใช้การซิงค์ได้ + Sync location is unknown ช่วงเวลาสแกนไม่ถูกต้อง กรุณาตรวจสอบการตั้งค่าช่วงเวลาสแกนและลองใหม่อีกครั้ง @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + ปกป้องความเป็นส่วนตัวของคุณบนโลกออนไลน์ด้วย VPN ความเร็วสูงของเรา + + โทรและประชุมได้ไม่จำกัด + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index ad4239e36d..13141df7a1 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -43,13 +43,13 @@ Đã có một thư mục được đồng bộ hóa với cùng vị trí - Đổi tên không thành công. + Renaming failed Không thể tạo tệp .megaignore cho việc đồng bộ này Không thể đọc cấu hình đồng bộ hóa. Thử lại sau hoặc kiểm tra quyền hạn của thư mục. - Không rõ đường dẫn ổ đĩa cho đồng bộ này. + Sync location is unknown Khoảng thời gian quét khởi đầu không hợp lệ. Kiểm tra thiết lập khoảng thời gian quét và thử lại. @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Giữ an ninh trực tuyến với VPN tốc độ cao của chúng tôi. + + Cuộc gọi và cuộc họp không hạn chế + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 037b32f649..f0f96196da 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -43,13 +43,13 @@ There’s already a synced folder at the same location - 重命名失败。 + Renaming failed Couldn’t create a .megaignore file for this sync 无法读取同步配置。稍后重试或检查文件夹权限。 - 同步的的驱动器路径未知。 + Sync location is unknown 扫描间隔无效。请检查扫描间隔设置,然后重试。 @@ -84,4 +84,20 @@ Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + 使用我们的高速VPN保持在线隐私。 + + 无限制的通话和会议 + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 966cec2af1..d1ffe86296 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA無法同步或備份此資料夾,因為尚不支援您裝置上的檔案系統 您選擇的資料夾無法同步 @@ -23,7 +23,7 @@ 資料夾無法同步,因為它是一個您沒有完全存取權限的共用資料夾 - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + 無法同步或備份此資料夾中的檔案。您需要從桌面應用程式重新啟用同步或備份。 資料夾無法同步,因為它已經包含同步的資料夾 @@ -35,7 +35,7 @@ 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + 由於您似乎已登出桌面應用程式,因此同步或備份已停止。使用桌面應用程式重新登入,然後恢復同步或備份。 N/A @@ -43,13 +43,13 @@ 在同一位置已有一個同步的資料夾 - 重新命名失敗。 + 重新命名失敗 無法為此同步建立.megaignore檔案 無法讀取同步設定。稍後再試或檢查資料夾權限。 - 同步的磁碟路徑未知。 + 同步位置未知 掃描間隔無效。檢查掃描間隔設定並且重試。 @@ -69,7 +69,7 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + 由於MEGA資料夾位於垃圾筒中,因此資料夾無法同步或備份 目前無法找到您裝置中的資料夾。稍後再試。 @@ -79,9 +79,25 @@ 同步或備份此資料夾時出現問題。停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 - Folder can’t be synced as it’s already inside a synced folder + 資料夾無法同步,因為它已經在同步資料夾中 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 此資料夾中的檔案無法同步或備份。您需要從桌面應用程式重新啟用同步或備份。 - Syncing paused, battery level too low. Charge battery to resume syncing. + 同步暫停,電池電量過低。 為電池充電以恢復同步。 + + 輕鬆、安全的檔案共享 + + 透過大量的傳輸配額共享大檔案,並使用受密碼保護的連結確保安全性。 + + 再也不會遺失資料 + + 讓您完全放心的備份和同步您的資料。此外,使用回溯功能可將資料夾恢復到任何日期,最長可達180天。 + + MEGA VPN + + 使用我們的高速VPN保持線上隱私。 + + 無限制的通話和會議 + + 訊息、視訊通話,以及無限制與會人數的完全私密會議。 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index d802820124..47d4b45610 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -3,13 +3,13 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported. + MEGA can’t sync or backup this folder because the file system on your device is not supported The folder you chose can’t be synced A file cannot be synced individually. You need to set up the sync from a folder. - Initial scan failed. You will need to re-enable your sync or backup from the Desktop app. + Initial scan failed. You will need to re-enable your sync or backup from the desktop app. Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access @@ -23,7 +23,7 @@ Folder can’t be synced as it’s a shared folder that you don’t have full access to - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. Folder can’t be synced as it already contains synced folders @@ -35,7 +35,7 @@ Account reloaded. Any missed updates to your backups or syncs haven’t been applied. - Sync or backup has been stopped as you appear to have logged out of the Desktop app. Log back in via the Desktop app, and resume the sync or backup. + Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. N/A @@ -43,19 +43,19 @@ There’s already a synced folder at the same location - Renaming failed. + Renaming failed Couldn’t create a .megaignore file for this sync Couldn’t read sync configuration. Try again later or check folder permissions. - Sync’s drive path is unknown. + Sync location is unknown Invalid scan interval. Check the scan interval setup and try again. Couldn’t communicate with the folder location. Check the location is accessible and permissions for the folder location are granted. - Unable to add a filesystem watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. + Unable to add a file system watch. Ensure there is sufficient free space and memory, and that you have granted permissions for the folder location. Couldn’t read sync location. Check the location is accessible and permissions for the folder location are granted. @@ -69,17 +69,35 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin. + Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin Folder in your device can’t be located right now. Try again later. Folder in your device can’t be located - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. - Problem syncing or backing up this folder. Stop the sync or backup and try setting it up again in the Desktop app, or contact Support. + Problem syncing or backing up this folder. Stop the sync or backup and try setting it up again in the desktop app, or contact Support. - Folder can’t be synced as it’s already inside a synced folder. + Folder can’t be synced as it’s already inside a synced folder - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the Desktop app. + Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + + Syncing paused, battery level too low. Charge battery to resume syncing. + + Easy, secure file sharing + + Share large files thanks to a generous transfer quota and ensure security with password-protected links. + + Never lose data again + + Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + + MEGA VPN + + Stay private online with our high-speed VPN. + + Unrestricted calls and meetings + + Message, video call, and meet in total privacy with unlimited participants. \ No newline at end of file From 4ec8aedd1cfd7ddea959343fd2bc810e57f88b28 Mon Sep 17 00:00:00 2001 From: Rohit Soni Date: Fri, 12 Apr 2024 00:44:17 +1200 Subject: [PATCH 089/261] SAO-53 Fixed T15672084 Some icons are not updated properly --- .../dialog/ImageBottomSheetDialogFragment.kt | 2 +- .../contactinfo/view/ContactInfoContent.kt | 3 +- .../fileinfo/view/FileVersionsView.kt | 3 +- .../view/ImagePreviewBottomSheet.kt | 6 +-- .../mediadiscovery/view/MediaDiscoveryView.kt | 2 +- .../model/StartScreenOptionMapper.kt | 2 +- .../res/drawable-hdpi/ic_camera_uploads.png | Bin 306 -> 0 bytes app/src/main/res/drawable-hdpi/ic_edit.png | Bin 380 -> 0 bytes .../main/res/drawable-hdpi/ic_file_edit.png | Bin 615 -> 0 bytes .../main/res/drawable-hdpi/ic_g_version.png | Bin 705 -> 0 bytes .../main/res/drawable-hdpi/ic_menu_copy.png | Bin 260 -> 0 bytes app/src/main/res/drawable-hdpi/ic_move.png | Bin 241 -> 0 bytes .../res/drawable-hdpi/ic_share_contact.png | Bin 333 -> 0 bytes .../main/res/drawable-hdpi/leave_share_ic.png | Bin 350 -> 0 bytes .../res/drawable-mdpi/ic_camera_uploads.png | Bin 194 -> 0 bytes app/src/main/res/drawable-mdpi/ic_edit.png | Bin 281 -> 0 bytes .../main/res/drawable-mdpi/ic_file_edit.png | Bin 414 -> 0 bytes .../main/res/drawable-mdpi/ic_g_version.png | Bin 439 -> 0 bytes .../main/res/drawable-mdpi/ic_menu_copy.png | Bin 170 -> 0 bytes app/src/main/res/drawable-mdpi/ic_move.png | Bin 164 -> 0 bytes .../res/drawable-mdpi/ic_share_contact.png | Bin 222 -> 0 bytes .../main/res/drawable-mdpi/leave_share_ic.png | Bin 245 -> 0 bytes .../res/drawable-xhdpi/ic_camera_uploads.png | Bin 354 -> 0 bytes app/src/main/res/drawable-xhdpi/ic_edit.png | Bin 402 -> 0 bytes .../main/res/drawable-xhdpi/ic_file_edit.png | Bin 737 -> 0 bytes .../main/res/drawable-xhdpi/ic_g_version.png | Bin 763 -> 0 bytes .../main/res/drawable-xhdpi/ic_menu_copy.png | Bin 252 -> 0 bytes app/src/main/res/drawable-xhdpi/ic_move.png | Bin 245 -> 0 bytes .../res/drawable-xhdpi/ic_share_contact.png | Bin 379 -> 0 bytes .../res/drawable-xhdpi/leave_share_ic.png | Bin 448 -> 0 bytes .../res/drawable-xxhdpi/ic_camera_uploads.png | Bin 528 -> 0 bytes app/src/main/res/drawable-xxhdpi/ic_edit.png | Bin 540 -> 0 bytes .../main/res/drawable-xxhdpi/ic_file_edit.png | Bin 1030 -> 0 bytes .../main/res/drawable-xxhdpi/ic_g_version.png | Bin 1175 -> 0 bytes .../main/res/drawable-xxhdpi/ic_menu_copy.png | Bin 336 -> 0 bytes app/src/main/res/drawable-xxhdpi/ic_move.png | Bin 326 -> 0 bytes .../res/drawable-xxhdpi/ic_share_contact.png | Bin 538 -> 0 bytes .../res/drawable-xxhdpi/leave_share_ic.png | Bin 659 -> 0 bytes .../drawable-xxxhdpi/ic_camera_uploads.png | Bin 700 -> 0 bytes app/src/main/res/drawable-xxxhdpi/ic_edit.png | Bin 655 -> 0 bytes .../res/drawable-xxxhdpi/ic_file_edit.png | Bin 1329 -> 0 bytes .../res/drawable-xxxhdpi/ic_g_version.png | Bin 1507 -> 0 bytes .../res/drawable-xxxhdpi/ic_menu_copy.png | Bin 446 -> 0 bytes app/src/main/res/drawable-xxxhdpi/ic_move.png | Bin 439 -> 0 bytes .../res/drawable-xxxhdpi/ic_share_contact.png | Bin 706 -> 0 bytes .../res/drawable-xxxhdpi/leave_share_ic.png | Bin 902 -> 0 bytes .../res/layout/activity_text_file_editor.xml | 2 +- .../layout/bottom_sheet_contact_detail.xml | 4 +- .../layout/bottom_sheet_contact_file_list.xml | 8 ++-- .../res/layout/bottom_sheet_image_options.xml | 4 +- .../res/layout/bottom_sheet_node_item.xml | 12 +++--- .../main/res/layout/fragment_meeting_info.xml | 2 +- app/src/main/res/layout/sort_by_header.xml | 2 +- .../res/drawable-hdpi/ic_grid_view_new.png | Bin 82 -> 0 bytes .../res/drawable-hdpi/ic_list_view_new.png | Bin 85 -> 0 bytes .../res/drawable-mdpi/ic_grid_view_new.png | Bin 78 -> 0 bytes .../res/drawable-mdpi/ic_list_view_new.png | Bin 81 -> 0 bytes .../res/drawable-xhdpi/ic_grid_view_new.png | Bin 89 -> 0 bytes .../res/drawable-xhdpi/ic_list_view_new.png | Bin 90 -> 0 bytes .../res/drawable-xxhdpi/ic_grid_view_new.png | Bin 109 -> 0 bytes .../res/drawable-xxhdpi/ic_list_view_new.png | Bin 109 -> 0 bytes .../res/drawable-xxxhdpi/ic_grid_view_new.png | Bin 108 -> 0 bytes .../res/drawable-xxxhdpi/ic_list_view_new.png | Bin 110 -> 0 bytes .../src/main/res/drawable/ic_help_circle.xml | 14 ------- .../main/res/drawable/ic_media_discovery.xml | 10 ----- .../model/status/DeviceCenterUINodeStatus.kt | 2 +- .../ic_grid_4_small_regular_outline.xml | 14 +++++++ .../ic_help_circle_medium_regular_outline.xml | 16 ++++++++ .../ic_image_01_small_regular_outline.xml | 18 +++++++++ .../ic_list_small_small_regular_outline.xml | 38 ++++++++++++++++++ .../ic_user_right_medium_regular_outline.xml | 16 ++++++++ .../core/ui/controls/lists/HeaderViewItem.kt | 10 +++-- 72 files changed, 137 insertions(+), 53 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/ic_camera_uploads.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_edit.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_file_edit.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_g_version.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_menu_copy.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_move.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_share_contact.png delete mode 100644 app/src/main/res/drawable-hdpi/leave_share_ic.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_camera_uploads.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_edit.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_file_edit.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_g_version.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_menu_copy.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_move.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_share_contact.png delete mode 100644 app/src/main/res/drawable-mdpi/leave_share_ic.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_camera_uploads.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_edit.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_file_edit.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_g_version.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_menu_copy.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_move.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_share_contact.png delete mode 100644 app/src/main/res/drawable-xhdpi/leave_share_ic.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_camera_uploads.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_edit.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_file_edit.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_g_version.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_menu_copy.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_move.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_share_contact.png delete mode 100644 app/src/main/res/drawable-xxhdpi/leave_share_ic.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_camera_uploads.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_edit.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_file_edit.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_g_version.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_menu_copy.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_move.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_share_contact.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/leave_share_ic.png delete mode 100644 core-ui/src/main/res/drawable-hdpi/ic_grid_view_new.png delete mode 100644 core-ui/src/main/res/drawable-hdpi/ic_list_view_new.png delete mode 100644 core-ui/src/main/res/drawable-mdpi/ic_grid_view_new.png delete mode 100644 core-ui/src/main/res/drawable-mdpi/ic_list_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xhdpi/ic_grid_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xhdpi/ic_list_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xxhdpi/ic_grid_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xxhdpi/ic_list_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xxxhdpi/ic_grid_view_new.png delete mode 100644 core-ui/src/main/res/drawable-xxxhdpi/ic_list_view_new.png delete mode 100644 core-ui/src/main/res/drawable/ic_help_circle.xml delete mode 100644 core-ui/src/main/res/drawable/ic_media_discovery.xml create mode 100644 icon-pack/src/main/res/drawable/ic_grid_4_small_regular_outline.xml create mode 100644 icon-pack/src/main/res/drawable/ic_help_circle_medium_regular_outline.xml create mode 100644 icon-pack/src/main/res/drawable/ic_image_01_small_regular_outline.xml create mode 100644 icon-pack/src/main/res/drawable/ic_list_small_small_regular_outline.xml create mode 100644 icon-pack/src/main/res/drawable/ic_user_right_medium_regular_outline.xml diff --git a/app/src/main/java/mega/privacy/android/app/imageviewer/dialog/ImageBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/imageviewer/dialog/ImageBottomSheetDialogFragment.kt index 946c284257..908c46a300 100644 --- a/app/src/main/java/mega/privacy/android/app/imageviewer/dialog/ImageBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/imageviewer/dialog/ImageBottomSheetDialogFragment.kt @@ -402,7 +402,7 @@ class ImageBottomSheetDialogFragment : BaseBottomSheetDialogFragment() { val copyAction = if (nodeItem?.isExternalNode == true) R.string.general_import else if (imageItem is ImageItem.ChatNode) R.string.add_to_cloud_node_chat else R.string.context_copy val copyDrawable = - if (nodeItem?.isExternalNode == true || imageItem is ImageItem.ChatNode) R.drawable.ic_cloud_upload_medium_regular_outline else R.drawable.ic_menu_copy + if (nodeItem?.isExternalNode == true || imageItem is ImageItem.ChatNode) R.drawable.ic_cloud_upload_medium_regular_outline else R.drawable.ic_icon_copy_medium_regular_outline optionCopy.setCompoundDrawablesWithIntrinsicBounds(copyDrawable, 0, 0, 0) optionCopy.text = getString(copyAction) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/contactinfo/view/ContactInfoContent.kt b/app/src/main/java/mega/privacy/android/app/presentation/contactinfo/view/ContactInfoContent.kt index ebf7218d49..6395882a9d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/contactinfo/view/ContactInfoContent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/contactinfo/view/ContactInfoContent.kt @@ -1,5 +1,6 @@ package mega.privacy.android.app.presentation.contactinfo.view +import mega.privacy.android.icon.pack.R as iconPackR import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.material.Divider @@ -76,7 +77,7 @@ internal fun ContactInfoContent( } MenuActionListTile( text = stringResource(id = R.string.title_properties_chat_share_contact), - icon = painterResource(id = R.drawable.ic_share_contact), + icon = painterResource(id = iconPackR.drawable.ic_user_right_medium_regular_outline), ) VerifyCredentialsView(isVerified = uiState.areCredentialsVerified) if (uiState.chatRoom != null) { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileVersionsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileVersionsView.kt index 45e3489b2a..967ced207b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileVersionsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileVersionsView.kt @@ -1,5 +1,6 @@ package mega.privacy.android.app.presentation.fileinfo.view +import mega.privacy.android.icon.pack.R as iconPackR import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme @@ -44,7 +45,7 @@ internal fun FileVersionsView( modifier = Modifier .sizeIn(minWidth = textStartPadding) .padding(start = 16.dp), - painter = painterResource(id = R.drawable.ic_g_version), + painter = painterResource(id = iconPackR.drawable.ic_clock_rotate_medium_regular_outline), alignment = Alignment.CenterStart, contentDescription = "versions icon" ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt index ec536d54bb..a56e29c98a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/view/ImagePreviewBottomSheet.kt @@ -430,7 +430,7 @@ internal fun ImagePreviewBottomSheet( ) } else { Icon( - painter = painterResource(id = RCore.drawable.ic_help_circle), + painter = painterResource(id = IconPackR.drawable.ic_help_circle_medium_regular_outline), contentDescription = null, modifier = Modifier .size(24.dp) @@ -454,7 +454,7 @@ internal fun ImagePreviewBottomSheet( if (isMoveMenuVisible) { MenuActionListTile( - icon = painterResource(id = R.drawable.ic_move), + icon = painterResource(id = IconPackR.drawable.ic_move_medium_regular_outline), text = stringResource(id = R.string.general_move), onActionClicked = onClickMove, dividerType = null, @@ -466,7 +466,7 @@ internal fun ImagePreviewBottomSheet( if (isCopyMenuVisible) { MenuActionListTile( - icon = painterResource(id = R.drawable.ic_menu_copy), + icon = painterResource(id = IconPackR.drawable.ic_copy_01_medium_regular_outline), text = stringResource(id = R.string.context_copy), onActionClicked = onClickCopy, dividerType = null, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt index 9cc69008e9..3e160ef708 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt @@ -272,7 +272,7 @@ fun MDBottomSheet( ) MenuItem( modifier = Modifier, - res = R.drawable.ic_camera_uploads, + res = iconPackR.drawable.ic_camera_medium_regular_outline, text = R.string.menu_take_picture, description = "Capture", onClick = onCapture, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/startscreen/model/StartScreenOptionMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/startscreen/model/StartScreenOptionMapper.kt index 2d94afe064..645a0f21d2 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/startscreen/model/StartScreenOptionMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/startscreen/model/StartScreenOptionMapper.kt @@ -27,7 +27,7 @@ internal fun mapStartScreenOption(screen: StartScreen) = when (screen) { StartScreenOption( startScreen = screen, title = R.string.settings_start_screen_photos_option, - icon = R.drawable.ic_camera_uploads, + icon = iconPackR.drawable.ic_camera_medium_regular_outline, ) } diff --git a/app/src/main/res/drawable-hdpi/ic_camera_uploads.png b/app/src/main/res/drawable-hdpi/ic_camera_uploads.png deleted file mode 100644 index 65840a9a3bfbc27a9d5766b5f85aa7fcb64214e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306 zcmV-20nPr2P)J2M}WgAmj}85FMOcOa~*hnATuIp^t#1m<@ipbP+Mgd_l&9TWo48=)S6&=(Z_I5lsZ?XCRY4&>Sux!XhDF0D-) zv4++fn*q8wH~#~=Iu9r2K{V%{(=u#A23qp{|KeZA6L7Dcr1G70`2YX_07*qoM6N<$ Ef^I%~nE(I) diff --git a/app/src/main/res/drawable-hdpi/ic_edit.png b/app/src/main/res/drawable-hdpi/ic_edit.png deleted file mode 100644 index ad100cedf495ddbfff48e8ee502128e03c93d799..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 380 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB7>k44ofy`glX(f`xTHpSruq6Z zXaU(A42G$TlC0TWzSWdSpS4N|DZ_xKNxdgkfk7!twx zcJe{a!v;LA&ib;tHy6b&Zr8hzE&kHavb5PrzYlNi;?yb3bS!FU) zkOP-Tqa9a^K-v$k`Y$gdUNUvC{%f3VtNrxtc85Y^q3z$oxz4UU)4IRs>$?Prb#Ipz z$X>W`?2Bv7Q?an-M?ccS@0pbta4fFW=*!Raez5OcT0wn-vY=c`*W==+yB}t5Uli2P z_UE(spBRnX6RO2O66 xcS8fug>y1xd>AuydU}0Vi%eh&dJr%2gVA=v1BufY$^$??_jL7hS?83{1OPWEggpQN diff --git a/app/src/main/res/drawable-hdpi/ic_file_edit.png b/app/src/main/res/drawable-hdpi/ic_file_edit.png deleted file mode 100644 index 5809e493e421fd6228784e40fad1bed3c4d196b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 615 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB7>k44ofy`glX(f`xTHpSruq6Z zXaU(A42G$TlC0TWzSWdSpS4N|DZ_xKM`*+owm$B+ol zw^Mg}u^5W9mG7C-RF<@qLrF}mD`LflA1vF@5#IHO}!Y z>FT>M!*Kpd&M#d_k7ge2UgkSvw$t}hY}U)}uz9ZbO7aQkc0H)&(_igvwqTi4VVchs zpAGBQt`WT}AJ9{3@H=azU}=DJ{j6Eyi`F$P-07s9_sOLDW? z*W?Qus5`uQ>2Rvrv$4fkXSLhMpg(DxC=m3VM?TLb{IFZ1U24ec|^+Uak{ftNr-6Uc9$jVtvK-=pkRb zhTK${TX%!R>NNhw$I1qTpS-m|e~Qt&UwUoYvLWszF$TvDvz@i+PQS2Xb;t2N7HqNm kV*BNG9-gw0Igqc0d2x?9zs$wGwV+7$boFyt=akR{0OJMhiU0rr diff --git a/app/src/main/res/drawable-hdpi/ic_g_version.png b/app/src/main/res/drawable-hdpi/ic_g_version.png deleted file mode 100644 index 0a50e5a5c5f38cdab66228c0b4f661dc02aa6716..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmV;y0zUnTP)lZ6l~{+wGh8Y8x|)+HF|IsqN2`$QjC=Ts$OkB#@f zV3FjpCZ|qhIJ*~{+}cQ&4;3Xh2&Wa^eH`mskKLb);InEHw`-~5Wy|%b7!&ft`623j z?7DL5nWiTKzf%w}Mus}z9XcmDxUw$?cy4MDzClq@84SE)B7VnMR?=g@o=#rYAc^N? z!0}b%>t-Ox9ui*=^C3cw6aPlm$8;A*=V*MV4brx+2tE!^q=g0f?UKn6B)>xm1Zv5D zG!F$0VV%`Pgv(**u?DH>YbZ$Z-q0LuYLd1-5aET9;dG4^BR9Zf{N}myvK=XD5|fDD zhOuj|-NUT~N>B<1rHi4SFBiMs%0^JofTyzCP&WoqTIMQBu)``sPG^G@uwj}f zJt&roksM~bX%&nAuLSs*mEh_Kqu%cJ_O#yz48X* zU_@*&?26oDr3ive3J|KLWE=VSl_ec|Hz8etno(k&tErz-2zy|_Qx&ZU9B<+NX8h*K zp@%u6x3(S`H!d!D8{!!4Sc*O!8Ac1_<9s8!M>1@d8|1*BdR&&h;BINBINbXplde(Dr~T8nG1n6ue|B4L{?7RT0000< KMNUMnLSTY_jAZ8k diff --git a/app/src/main/res/drawable-hdpi/ic_move.png b/app/src/main/res/drawable-hdpi/ic_move.png deleted file mode 100644 index 7d1294cbed34706505eea2c9f883dda612f7c5b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241 zcmVkhVp1KCSY>wXq82;NK=p4-c=yeW;Q7+8I!-rWZh39T;jxms$ z%hu67#pKoETb>^QH4u%dtS{6e=V_5!>ep^xrasPz$safoKfU|(jf8p^i?SH&5n4v+ zWKeoE+`Xhnqu!M;4$)H{TSqy@U4|I(OO6>Ym@yTxZQ6JNS&+j?0+JDo8p8%MbuLqj rpkAxJP>MHyM~re}{Li0?-ygdJqD0O|wB+l{00000NkvXXu0mjf&iG?) diff --git a/app/src/main/res/drawable-hdpi/ic_share_contact.png b/app/src/main/res/drawable-hdpi/ic_share_contact.png deleted file mode 100644 index 370c25d845199046e60ba1fa763379978bd88c6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333 zcmV-T0kZyyP)Kub~4_c70qdjuarJMFYexFVAx=f=G| zcbB!jnQmt8V|ST@B8te3COvvI??W0yNRkl^f9OLog0S&rD#RKTQ}KgZ8Y2iTKd7C7 z+Np_vh`S$0W zsjf0t{-bKQp%Pm)xTWL|!Bh=SRL$dRi>uv^)f@fC8{c;3kufLj@F&JRTur>#nL2Zh zxi4{KPF=0X&csw%bIwIBd1g)3_KVaw7?DdJY%ADxVg%vc4E3F%nHdV5p{W@v6Ebkf fP+No|iU9ZpcyJmwrGS6c00000NkvXXu0mjfMd*jy diff --git a/app/src/main/res/drawable-hdpi/leave_share_ic.png b/app/src/main/res/drawable-hdpi/leave_share_ic.png deleted file mode 100644 index ad38f21739097c9fc67e2d12000381f279f42def..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 350 zcmV-k0iphhP)r0003cNkle)LkGh*hW{Aw6T>71Vd9MmW_XLm5Ey*J z5J8L~j12V*|DakfFw`)ZGe|P9GpI6nF;p@^38-i z1#!(b27VkWL>P`jjf%h*#BZU-Fypa|gJBCatVD4s>4bWUpMdv88D4=^PQWhB1C8(? zBBCT5tnxG1N(qM5467OB5t1R$m?9N4fb~6KP=E<60t?iTY>*!`@Zm4N7!W)_MHf*mjHniCR7*$Xr|dNhYmiem)$$tg wxqmC6+)uUgh>9g770Ya@)gn}_*C?uK0b_R*6Wc;}bpQYW07*qoM6N<$g5NoYssI20 diff --git a/app/src/main/res/drawable-mdpi/ic_camera_uploads.png b/app/src/main/res/drawable-mdpi/ic_camera_uploads.png deleted file mode 100644 index 16d84a859169fc0cc83fc59b87f6676d91e8a1cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iPEQxdkcwMZCp&UACzGrR z*N5qx2p_dY1t)bHss#<) sjm&fRg?&E!)qOG3naf%K`0KB8Ztv57aV7Ao3eZsup00i_>zopr0ArL*X8-^I diff --git a/app/src/main/res/drawable-mdpi/ic_edit.png b/app/src/main/res/drawable-mdpi/ic_edit.png deleted file mode 100644 index 8c3eb7e173bddedd7b40d814b44e9129e35fa65b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlfUHG8@^hIsJ4 zop_M5!9alJa?AfM*}R$ugx(ww`m}Abg|-Y!pg_^1=VH_DWPi(>9Hb%jV{PNLsAHn% z=j$+598}vc&~aZ{Byb!8{+mAw3d|A?}!!5H~Fxtk=ZZepF@jCFUZ*pp00i_>zopr0F1m&y8r+H diff --git a/app/src/main/res/drawable-mdpi/ic_file_edit.png b/app/src/main/res/drawable-mdpi/ic_file_edit.png deleted file mode 100644 index 77054ae9476d444c5d16ef32b98d3c7fd6cbfc47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 414 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfjKkB#F~o!S zZLl@pAp;&??lUnAdDZSuk&SwaeyL^%Fr$-e(!hI+(8=;XQ9E?ig$9ezy2v`q`Ph>IWy7 zO1w*Lk`rGq@uxQBNJz8PoYYAcH#K-m9(ghE-EnNe(JJfZp@H^NU81ay9$X77lv*ai zpnQ~DNIh>`qe#B}DwV=69p(>v^~;l9JePJz=_`5o*CnIx&ViYAHP#CE?)A4-b=xSG zPwI)=*C_I|biU)sgYomaCGt6%XY7+aq)^qoal`&a^Az9TSS#^$+7Vu-dk+{~)D04T h@jepxF8_e9;$qsdkoN4+ptd_Cy#TGfHI6p&&g#mGNpnKschxOA2p>^_7RzvcQ)hG(QV$(Ce ztCU5h(uVa7$%BaBiBa1~D&l+dzCo=~2oOoz_32DlPob;P1iz`DrUHkEvKx1?2YBZ4j%y!>Mq4BiUV=qI4S2^l>{F4d^rx_6~hP;gS@NZNME?{YLq%$>fsD4bYNpwPvyyrwD4tq@wU?^G4> hw(l7A0VQA*006F4QjBRE8XW)t002ovPDHLkV1nni!7~5= diff --git a/app/src/main/res/drawable-mdpi/ic_menu_copy.png b/app/src/main/res/drawable-mdpi/ic_menu_copy.png deleted file mode 100644 index d37cb0b4de6a52639d315ac4855a7b3de4f4e967..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iLQfaRkP61FSB?v|8VE24OgyC& z6T9F0hSZKvKdlx?rbm0XvEN|1a`fPb-&2kYGTX$wJ|@a$vq0sm!i8xD99vX*Ebf=^ zdol`4;`HbfI`GMJ!3Gwe!v}3-bhy@tSVV}dVVbcoft&HLeuUT`Nfy5H6{opB@-Gu% TOx)`Pw4A}y)z4*}Q$iB}&ki|2 diff --git a/app/src/main/res/drawable-mdpi/ic_move.png b/app/src/main/res/drawable-mdpi/ic_move.png deleted file mode 100644 index 5c3bf65162e38265b06d42bff654c1b994734095..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+iY)==*kP615!Pl7@6a+q$z1}kBJ&%%HJ7b=6^zuZeW`7+)|uYU0T|9YUc N44$rjF6*2UngG%jLKXl3 diff --git a/app/src/main/res/drawable-mdpi/ic_share_contact.png b/app/src/main/res/drawable-mdpi/ic_share_contact.png deleted file mode 100644 index 33f0e6af7e7a0c40c1e973aa94b044007271aca6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+irJgR1Ar-gYUf#&tY#`A3a6jWl z_R?1=Q^tTE&oAA(EqP+V#ti`z zTN;IKuHs?d+GNGEg)2&ZZ*W9Hm_c^gqt=KgD<3>u5P*dxJ0002INklL*|j0Sr$-DwkIjimUxj4p1he5r7U& zK~6?SPJyO#0#2cTo|64rVecvFQ-rAD=&jrZRV0AK994Z7p<8$h#gf2N{kWTd6y zyg)RufZhh@fM$BpO=u1_P<TecN#sE57IocTlZ7Zq^2WT7n$qATjE_67c zFuKZHh?TJ_!U4I_wO&ALtnzR`W^|($FdD1u4+6wPB%WmPG8Jz$@lmnDuoEBGD_l4$ zT$y2)ek9=YwZ#b#UmeAlU-9)_`~kAbCjVQ$0TKkhbS`M;W&i*H07*qoM6N<$f~0_y A2LJ#7 diff --git a/app/src/main/res/drawable-xhdpi/ic_edit.png b/app/src/main/res/drawable-xhdpi/ic_edit.png deleted file mode 100644 index 5c07fcb11436f7b6e87d418bfe989b55915c775b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~ySip>6gB0F2&*1@5e>`0rLo!(3 zPBP?cHsEo6=~>ks*WKD^sO|pZrP0RkY+u+lr?y{OvaLtxi>~CQgCBqQ^D%d`Wi-Ih zgA(T3+k9V$?p=_-oH;^_$znmO?Z?Ia0t|CicUpWGWIDkA#k=A3D`I&5zecBJ#un>4&sc2ws$FgN*LFT&Tew$Z!OcH@dUAs4l1bOz70hOS zAXszmBj-b)%nl~Ic8RS(_5T|9^8{{nbFMc{pS!qnwc}fxv)N}OpJ&|5x?sfr+f-D? zIwoEF#qC!AG%m(lZTc)3^8ef$>>dO&i1A)vfTEZa2c%CgOqgmgS6mqs9-gj#F6*2U Fng9Ycik1KX diff --git a/app/src/main/res/drawable-xhdpi/ic_file_edit.png b/app/src/main/res/drawable-xhdpi/ic_file_edit.png deleted file mode 100644 index 042834ce15c89a023f70b602b232a89045b1c3b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~ySip>6gB0F2&*5QUVDk2KaSX{| zeH(eui`h`%?p9GpN5=qxs*l`N?=SXmVE?~zzQR0_dZ#a8{Y~>1d`-#kVqdy%KnvZeF9%E zSh2J6`CPvOUNQ9q=Y30sHz?n4Vu=29jOoouX)c9Nzgg>w#iud+d|)o|&u#jRqwHZ* zY_3h8@AXdZ>m9F#7Mr4FS%+$xTNxC8y01F>bH(3ftQjZD{Tdo-`sSoQ@3i49J^r)J ze#WWuQPU+jE^>R9PQ1K2r0MX_6}5aE@wyDv*CxGR!=U-o$zi^^&)vd(jm(F{=Qp&~ zJZH%`DbBR5@^FRoRXg^U{ohz76f+g?ZxH7Bc`-jIV!dvH_gbBO4|z`8sy}7_+--9{ zf9{O@S-+bm&1h}dv~Ehx%=p*k`>(D0uq;?7_RzZ%7k+Lp$Vy%Mjg!Uv(&1>$iK*2J zUrr|V?$FrEyg*-^XKT})JA0PND~j))S{csLvFq(?k8qYBJ35nM1t<79l*F`o{{POB zq;FKkIoBfge?+aR#p<(u=|MYgsP3EIB=N-7!?5|h+%8*&6T&`!?R7IhI^2`_s2F!d zzwxV=MFkV<0fC$51~2cMh!!k$HeE4o#vUR2rOWx20HH+51Myd7t6LYWmp=wdUY@Rg JF6*2UngA@rF4F)2 diff --git a/app/src/main/res/drawable-xhdpi/ic_g_version.png b/app/src/main/res/drawable-xhdpi/ic_g_version.png deleted file mode 100644 index d3bb373f44397fe6b93685fbe3b00030cb2c73e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 763 zcmV(y?!bG2U~2)5_HcT4T8J19vYLQ=o0Lx= zSiq4We-FsE!XdK~gpH$CK0v-*Ddbj=eUq{t4qF8wq}XN$K>myQlpAq8_p6j)!B&2F965agY@;g(k=$9` z7!3j0nK%pyk`Xp*0WxQa;xZC^76bxGA+ZDkNdWm^DPL$L^wUYOd0-n={(8*HL393R zdz3BFB_tXzXiex9w#{b#QgRodSwnRS;&~MjudsOo8VU8Dt`TPW1iHo&@EVy;w8iSp z3BfPNQLs1Rij@+a@as8_Yl0NE8g{NhHaVUM*eZ8*4WP(YODDGbwZmp59IOOKLGWf; z22jYH&}$UP&&Cslb0GLQIK+y2Y`_BYUTbv>7(;sWWtCcTvTE0W^E49R8etR$Ko83JKmz$^j5;8re3Tab#Q0ze7=emqvuHh!2`o)!su^-Jlww-$u#Fi>?t0eIwNG zK_6sdduDaB@ZSq=s_(rKUak@pWQ@G%DYbZcVFdC4-Y;_${2G?c?eUO@JWyumBFQiuLXse7nbk>JBZe5ls|`G~l#Rirdd%*GkYYZdzD zgZ@T>$j{An4%lWBII^{nYJrh)u|=?rHc@)DNLwLeQFysaIK-+cC8F+nopNGZHbB-H tkS|k3E!cf^B8&JBIDCA3e142v001}#kbJl`;D-PJ002ovPDHLkV1kV^R7C&) diff --git a/app/src/main/res/drawable-xhdpi/ic_menu_copy.png b/app/src/main/res/drawable-xhdpi/ic_menu_copy.png deleted file mode 100644 index af598503008437fe0d0a14d41dccc674582f9172..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0D!=5gVAr*{oubYcCIY_WPFw~yA z@z&wszv`d3a<<1L=Jq6CySaSB8Ivdd8XaLr4+bdOW%LSlpEs8mh<_nA`#i&9-jkgD zGp1Rr(dl4#!SJ;BV8frC2@d~a3>MVuNj&(-^!;#)T!It7!9w;K9tgu=vLgvR!Vd=au@p00000NkvXXu0mjfLQiL_ diff --git a/app/src/main/res/drawable-xhdpi/ic_share_contact.png b/app/src/main/res/drawable-xhdpi/ic_share_contact.png deleted file mode 100644 index f1046a97dcfacbeb2d2f7db507ea1be9c139dcf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379 zcmV->0fhdEP)%HneJ*M*FbpP)qEW`U;nx=dcHJ}G zbDZh_`I^TMrQ6e?$&B%Hh%}K0}Rof*f&6k&QUP z3aYRIw-n)s8>j*|JCh6FBf3z9uKR%SBN~`PCFW?vJAmjKDscsh_a~HK0F@XZ!M>e^ z_!A#v0aaLlTj$P0JidiH$k8oYsOkb=J|Ex42y19hYmCrFS$$uRPmy5@{m~W~QtWD2 z=i@t=;v1@2fhjt^KBs%wK%Q;TL+!mlfjp!3-l0I=PdZIAW@vf=JrFqbe!dVxpRg4mZXrdSYlQLTvMInzRx>Kh1q#w6z`G{Y(XfM2?O2^gY qrDF!gZwBRiCKnJ-qiQ(GuTa0S?&<(xGyI|e0000ey#eOT z{&Z&6{W1(Qv$KGfmX?;*Q%&F@MTzTxPl*&BCT%z-PJ^O|&k5$EcgDlHAvL_@jf!){ z6`l-~jt-Q{K;`H_r3^IW))xdYVIsgq`h7H@;Ahu>2aqYG8e*UvN4T(I!N3d_Y`8cg z9|tIcgK2BVpTa>j>?=#KdRd58NQMdO3j5C0agR#jpWgyHW35!M*EshHbjDJ-hgfz- zQUl(X85+DYO8s4d2uBaPcifDlxDRzoZF;PgdVZC^;R_LHf`u zg{&?nfg>HzRbbm@R>!7^3?iiMRn9grnhW=cSru+pLfGTuH8h^@Op2Q(uA zntkvqV;9sex6htkVq{l3D2nUXhqoW>8Z?G2EW0M3;W3EaL6PB6n&Gg4VjR;0(BB4D zJptWn+yUGBNYA*B^bRj;Rwp2Kb82>ze0Fyo>~4eD-Ip=EQPk4X($doUpZW%a7p=oX S0GKiW0000Kxi7f1i=Pt1>f64hm)57I_U}ts6-LkVyslRwOS%qq=3vXQcw?9Q~qOtPN zZqCHbi3$x2OdMEVCB3#!|hCB^HS$N81<4ueW0Kvshu71GKc-?%pTw?ATCY4LuJ_1W*wg;Wk_?hD^#d7y9^$4VQ&mX!4jORbL= z*8IEb`Es9M+=RQ8t+lpp?TUXZSU=dxTjtB}y!j$dYeVMQ*-2;DpId%yuXYjN;lMR7 zWpsD1&9+Pp5w$qDmX&>ugM!CJ%Lgn>j$P*%)de_$O86`q9VRR)KETP+Br;d{L4=pX zpN~B~EL+kfvbw+dPL5s}%zpgcCxrmrIgSgeESMck3&ohO9*txOkv`rafi0*w6apL` Ya6j@3*Lap`BL|8ZPgg&ebxsLQ0C3E^O8@`> diff --git a/app/src/main/res/drawable-xxhdpi/ic_file_edit.png b/app/src/main/res/drawable-xxhdpi/ic_file_edit.png deleted file mode 100644 index e1099ecbf4f650f4e0e1f3427f4cead7c55a6ca4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1030 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(<^v49!D1}U6i==L6{yuj1NF{Fa= z?d;uoR~-b}l0_66CNwYw9uA`^aE?x~Vq3TL{s)c!dOw%00MYvs5b7S<*q#P#4oK<<2#h8HuFGkw}xp0oqG zzoi`5r@i>HQ^onv&*Xv^({`_8Jo0g;f|zf?lcuWAizgK1am{(#Qt~5sPs^dZml`zW z#e}XsYj?ikq;+p2tHYFYQYvRs8;hIX&raU@Y3J)*t*2)^NcgYW^PBmD`L(hKpU?bU zv8|+YM&iO|xt~WB&+E*6oZa`%xFBPf$%6K}Pp%IFnA{j|HYAHokhNfAyxEk@Gr`uP zjp1fXGRuTm3suIzHw7ZUL*>*S$xr`f`u@4YZy}2hKcDlT3@|`|M(q7b_f49M;pvqzS0zp}4ar@IzCa;Q&yxASS?pUsK$hg9(!9HhSv!DL@ zo4@?o3%9+kI&rmURr7*H?_|PFw!C7RBJ6kHF?#iBu{RbSn{%5h{w-Y5tWY2+_M4;Y z^0KX-`RtGXL^4dRdi+6c-Ls2(RxZz(9n_F#SebqAV@U0Wu9NDyx4zb=m)Z$ek?*~c)|WDuRPZs@A8S%NzQihd-%`0t8)JOV znK~#>U#jNt=ypa&pl?IlE0OhASyq%z*ug8(x3<~s!Bv)wB_TJ9d>d{Vdt76-T0hIm z!@cRF-{17F4F8@hOU3`JzpRu#edeM&N0qlW-|JSMQXcYj9#_Wtnz@g7LUyX#{w$Qf zSb08i`_as4g*BZU%0FhYe=jgTe~DWM4f^EbZ{ diff --git a/app/src/main/res/drawable-xxhdpi/ic_g_version.png b/app/src/main/res/drawable-xxhdpi/ic_g_version.png deleted file mode 100644 index d8089a6ab6a7cf35d6c3e5e34333e6efc41058ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1175 zcmV;I1Zew-P)74AE&HwM0FS|2S zRbNJhG76Cih)5(7i9{liNF)+@`i`mKcpV5I3r8u0o`mDKA@nUA{|%uZi}fjlpDk8W ztTQ2_H-vLjj9^ioo)j+KrdtsH6^{OEc?tan;oIPnUGUc3lVe1nyDrHw5c)zNvTaNF zGvs_YoSOutW%1v`Z=squk*cMfVyJ;SDI%E9I*PaEj zUptqsfsQ3l4$>&p+{0+3;v0%}0$j2I9!VEQm1e9t^R8qrRB2@hZwtpqL+F8G{n?yQ z{5x{m4;_a~j&D+!hmrGccr=?5t>A8%0eP~QzDiA9Cr{4mB+EItiJg61bD1_>Z#xLR z(paPpu%s~w-ygQc=>PG_MN}Kr-YA((+?_t~U-e!$|31kj3&7&hY;FjDX^W$|PqGSp zQb{(}47{G>_8Z-VZz&d|k}ZY42;EfY#@<6ti()u%*&+~rvu+CDjhyx#bCG{*QKyGijU6y4|*%VGQJ0%%ev{8JMGJ)^l!P=Ute zN#;H3W_v-1S}Gj#bhBUrDZ&-w-fn}1zg@AjXN`6t1k$p^YP$L9Osa2j{QV#*>~A1+ zq(6b|+RZF*)eU$-=&GhfQ6Yt|K~7s~bsofm6rl%IUl6)hLwx&B zW%&wQq)yF)6ye(kxZt@^0*e$rlh&x9Rx^;()0`-vHTywcQS-EWz8ejr zgW^}DD^;BEryBK}`0p7`@K02DeeYJ>A?IQ?dAd`buHx5aI9c`2n2g%6q<7JkEncp( zc@L8x^`|@d8y$}+!E}d5Bw1Hm6m@5GgwD_`Jm`E-_}Rq9$I?2BSfU9t520W9-=>bI zbKYO`k&!*4Xv`ATecgJmpSx$N`DD$&bwEp7DSD2kz2uNnuKr6Aq3`0HbfaFd@Xc}3 zz7dXhh~H{7LK|s1ydeB){Mx5+<7?9~pC5cPgzv>}5AeNM0I^)Q!kDId3df>(jb`QD p2Lb$3$9{1bi9{liNF)-8{0~`$-6ScijrRZm002ovPDHLkV1ma)Hthfa diff --git a/app/src/main/res/drawable-xxhdpi/ic_menu_copy.png b/app/src/main/res/drawable-xxhdpi/ic_menu_copy.png deleted file mode 100644 index 42ba490b9dc9c1f46e57202e7f24d4dd41df2035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXoKNz$otN;uuoF`1aQJN@qhJ*N5Kh zmhC~&nOx_VoSJMgO~yTuVMocgK$aEXAKqd8*H`0s^I>?%)h!d&?%8?I>Dd?K`NxQQPSyVL~8PjDNn9f-+u+AxD;IeqkAX0FQ zQR7(;^Mu-4d&7D?4=O0JHgt$ECOn==FmA~K>!>%aykS`*PP5yJL*5Fq_43J7?27HqNLM-!`@W=4adR>>oGV8ms?Hn5u(5{^@PEd>s4d#g;pasVkSQ eT9hNPm-%GO%~y3Y>ym&W#o+1c=d#Wzp$P!c!iFjU diff --git a/app/src/main/res/drawable-xxhdpi/ic_move.png b/app/src/main/res/drawable-xxhdpi/ic_move.png deleted file mode 100644 index d51487769c74cf41a4c8de192c327e56eb04cbc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326 zcmV-M0lEH(P)uTV4ITI9FXD*&L8;j!OauZFG)J z0>>wTKZ6P+fkRML|14?10SKfqW-fw0o*8FuCrF?F3DRppQPsS-M-V2sC^DeEpP%-z;Q`T^Fq#(oFyzd@*=flfdywK8GZq1Jdk^1o>)kYirA{ YHz|=g`MB<1T>t<807*qoM6N<$g6V;ZEC2ui diff --git a/app/src/main/res/drawable-xxhdpi/ic_share_contact.png b/app/src/main/res/drawable-xxhdpi/ic_share_contact.png deleted file mode 100644 index ffffce9e45fddd3988aa3ab60f9d37e7996969f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 538 zcmV+#0_FXQP)fGACfFh-Ic5!iZ&*tLfqTuc#4y~!UxQLUW z)s(c@Qj>dc>OD;?-0!US9)9^}js#FqQBhG*QBgVjT%ZIU2G&@^fQ}L_{N!ku!#t`v zG`~1S>}?#Y_9*(nN#MRCKJ@Otu& zW~4wTlL9at+ZhP>1G1)Sr*=*gwdu`W1Wau0CXVYo;)F1@HJl>kdjAz(=r}=Cv2Z-b z1*!l1syxr zPs|QFQjBSufRjb%c2IRvwFmmJiU1C7Z+V>!^09JG`JZOK7fIgt4WC6yUDXC?>A5tC-fsjm$xDk>@} cDk^82cRksKVER9qS^xk507*qoM6N<$f&)JA@&Et; diff --git a/app/src/main/res/drawable-xxhdpi/leave_share_ic.png b/app/src/main/res/drawable-xxhdpi/leave_share_ic.png deleted file mode 100644 index 92529a3f0720dc42d065a00136b8b98bb8102ebc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 659 zcmV;E0&M+>P)m?cXxOBc#-6!yJoj`l<%#2 zsxCR}njP!z|FYcw$iZ}Mz!BWQGknH-+{S4f!X}JCJ0!OMQG~5{0?E)FY(du~4a`tn zfn?c9j7KfRvJ#wx`0N&XBQ~|i0Z71hqb(v`F`hv}@(z6w$tK|o#G~_Aj1eeC7t}*- zv_dZWV-=34@w2~U0U}d1tburN0khB^>DCN0aSr0aHdIBpc^sVE7=tRvMtyM!0++Q2 zwTTdi&scz(J{`Gp@fqT8uJ)XHwz=2+Jo8k<_;x$?z zunxdAIQ0;8jd2QMu?vAz;`&&He6!XBw;&dSf_Sz%={Oe4S=R5Q{O0TD>6_g(%+)NI9kO+*ZfqLlwli zM)(M+gaNtx-|;4J7UEtC;$Yw`2V&74l-MK4(;!WE+!Q9InUG8eX#=DZi;<*Erh{|@ zQi%~D9i*F(N)#iEYG4H(Ktf_bA3xTA|UvvRga+ctI34aNmF5=W>z(F)IiwntHA{YI!GLVJjx)nh;v+S|o tTIhDDK8R(yp^kJ*W&oRdZ^n63?@x1RP%W56v!MV0002ovPDHLkV1mn(ES~@X diff --git a/app/src/main/res/drawable-xxxhdpi/ic_camera_uploads.png b/app/src/main/res/drawable-xxxhdpi/ic_camera_uploads.png deleted file mode 100644 index 4a68f2155aacdf7c13d0d52baffa49ad16e4a87d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 700 zcmV;t0z>_YP)nFDAmp8oR2XkUH{ZBqbiDdx#s={)C-B+iAWE5p3l07I#7E7D5dlExXD0jNvv zvyB9>mE5Rq0$?x2`~ArAOkc_u_WA+F(yqIS46u=Q=dpf(rqIuel}UKQXifb9HKAWG z7C=uJt)?HKEcEkZ0r~R1k9x(Ff=j*> zT(j!C=r#zTqtw7SK+?q?cL7MU+~#Hg@BS~0*0_LCK)d} z_$Y4)zU$xX91|Gpa}skoKZx&9-+k^td^FRa&JTxDSpV%*JrMt4-kYog_MwN;ikK!p zW@7wzQK)bJ*?FA~>@})BF5x~_kNQ<>ejeTPsA%2m3)~O*ud7Pj(fz}q-+RcPwb_O` zjKeje7mB41o!+^x!oBu~ZomI>rU%;}>`%24Vc0La-hD3r#df-)olv{(`%WMUNya#xL91%y}vG_+1T{jhJ}?!NbRi>MTDEsOyM0HEb_ z$TLvIv`wJZRCD}lhLeh*Q-R*@phaT%UL`!^!hGWW{eg{YM+2xZ0U$R|R4`Bh00bKX z2o*z{9vl8QrLhtJ?VE?U?V~9GAg}v)x&@zwW^Qy8Z`-rAXGPu;u7HX!7trt+Y-M<3 zL2>W?Jl)FiCI#pXjg1@IaY+%pniV;XTW{HuQ_wY{jgi!Zk0= z^4hiPQ#l*e;-R@m&bGc}4J*i;jr@+eg$k?0v;)jNiZCwiDbb%G$wOoljq23GT?b;6 zuJQ<3J9pq~+dBKvbmX!&Hz#jKFp$*U56fL;wz5c(jbTKwTBp7~gTmpH$jvdUtaS8< zg_?!pxfb0ybv^IY-cL7cjWs4}J=VsU!ridufcX31n?(SP%Cw5aV?WZB_j!whFIkIco%%yqE&&uC zSL93=tT;k%8BuAM$2LZ`4cI-6IE-Z_Tf=3m9bUq_*}K~u2*c$I-Imq~ODt0#fT;^Y z8dj()-BFF6Z37QNpIkIKsVAFkSmH;cN1Ke0o!-$S5&n-ykM*EdZn$bEUa$A_zVZ;6 zY+8dQnJrD-pS~(NBWxHhN0y;#FIXJ{-^^pTkS&z%$TF+|K*ziF2+S-+KFSKgr$W7X zyQv^Qw?;|A{<)A<9_RA@weHeB8rMl-<~s|wSxBB_JhB&H4&MRunehsJy4;al?03(* z2qtz4E~USlc@m3zdJ^fldsP(W`NIse+yMRhuX4)0mWYy?8Ddqdl$vr^Ivx7M z-rImDhI37YZ^F&AF6%lZFdP-fGt6<|;^1f#s97xBvF^#tUQW9ATTKeXn6OZhjx@P4 z^|9zDimXrl67Ea8thqTq2l~v&PG9D;`PCr$zQAvRd6%V;7rIP`PjF)}EH9*9r${9( z2vD1ofu9;?#WNje2%O=!nQaMt!x-nD0kI20XLQQg?PS+WO&&8y?ZGyRBAIb>MnppJ z)=fNQ4H2e#U)08mLV@B}(ki_(fRF5J74tY5gC905ot7{k&0Qa^t#|daR$o0o%EX~3 z@h4DOFD!XNx+B6S?dljqEx5h-ocNOg5&3R%I~&%--;W7G5oxp_d$xqDtc({54Vu6i z=(NV2MJqwwcIwNp&jC4#-p6z)U5KcH5Q)vO4ApPm`1c1nYGQKxXtK`SixlBo&W2?@ z%Qh+zHy30$>7Z8*?X1>D?(#FwiZm+Y0 zeft8jPY>=nm>1BWZ^xuGWA5Qw1$NDm*z8*-ap7)t*xB>?B1$9uT+Kg~@V|ceERx_2 X(2Fu^wvjGsY}S>J7sa#1otFO>#?U}5 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_g_version.png b/app/src/main/res/drawable-xxxhdpi/ic_g_version.png deleted file mode 100644 index 33831d452a2d75de934bd0b4992c16989482f5c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1507 zcmV<91swW`P)ltchRAQf4G(Kp1e;4>&Fi`R)|9Y$qxQA3%KCUF9T|h5RB3K7 zod!1V%D@#OOrL<0vtiSD@h3_j%>g#oI0ml>W!#d>V(40Ae`dM@Y<`ge2_|fALY7X4 zuELsK!St;RKonAYmgG=8{P0NVXlyzum~NAoj#8K&fK8@FN5ZsHE+5H@MlEbUL$$IF zI*N=o2Adz7n3*qvje(^-VUuNRhPyAB9M+CnJ6b+)?F8sG)1#WK0H&S6=Db{9YC;KO zmv-%x!QY`lL;F0~9M+UG)t62Uo9qiVPd20oap+2oy!?<~oETZp(gjR}<-zn&_b8!C z8-VH8AuRhx!~-ta%N`EaYzj873{ep!+m6K3wB~Ei8UHglIU3fEh;|`%gK7Um zVwlSlJd^l~*WgR6r?Myl@n_8GQ}5GJ&?73-K|UU%_c>o8nsSl}O=e~S({tW_LNI5I z=_FaQ5?Pdo9_+a3`6B)3HRB-`9!|#rn|r;UT|DL>WXXL0*|#lSnaivYg!^wDTOyf$ zGyjIM5C(@5=sB;jMX1=3I7D^EiKz!!Iv29!43CHZFltv{R<@5#U~^Nb2Rvqwf&Ep) zdD^kGBqB!)v)Ac}X|W)&`-a{7%$$O_!Zy6@3)Kf&#+ zg~_bRDPYL6pALag5(Nn2F}o*La&{O))mVfvlW1jW6d+*>SL}%ClQ4;Xrbn9yEf0Vz zt3{&#M*z>gx-09)X{1~tvnxy1j#>eNE0iscX#hJgZ3{C{kHONq(JH_dQkS?_5G>u_ zbTw|NClpyJsX_y4Rw)A^Bx zA}R|FUO_;YLMXoy+`%~UL4v?^)-VfN#dyV{1o`uh3P%fUZgPZakA+ZXB}AK$5i)a* zLjiA#cN)JEqD@IU;GX3?3bIy*5WfwbG!KU_OL39WA?{g{ ztR1HkDsz^gFw32ql$UYrlds^VTStjZ2}hQwG|_>jo1?ne;8wzsB`eN#AlWeYD)_N> z{WLVP?Uc4W-R+dQ9{QuGJCoRS#;7l7IBdcA5*K%GMf9{@Q7Q`UiXZ4j?V_%kt7FPaG1JL%rB!^0kRRZnNGmk)Bbbh_l{?DT zQB#b0UE)pu{Rk8D*xw&vB6oN7BTOPdQ4~c{6h%=KMNt$*`5mdn*-0r#lHdRU002ov JPDHLkV1l&3(Sra0 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_menu_copy.png b/app/src/main/res/drawable-xxxhdpi/ic_menu_copy.png deleted file mode 100644 index 626983fdd1b0cd79559257e80aade64b08fd8819..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 446 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%&M7z}V{P;uuoF`1a1xQf5a9<^)zV zo?}|ugvuvOJG9~Lk5_!hbeAw3)-d=n;?IE$DU359x+M#HT!7!t~fc{eO^JokCvZ=@^s%B3e$a0#7oID z^B5dx_#v@i|DFSkzfN<@fEllV4269_kw-8_7Leg^?tSvcf+o8L;V+DH7Vtk{sbx@q z!EE6ue}MBBgWm;qn3Mv`gO*0S2HlEnTN(F+FJ*RH%KR*fVV>?UizAG;*;ts%csSVJ zND1()0MU{HJU7f0BnlE73?5u)NH{Q&@nAzTa}%RFP@$hVyN?&U3g>~Fj~aeoVl=(S z!tlJCxnWs}Lu;bNf}@Nz93Jux$2T0C!NPb;=EHf34G~sAUAus|3W$HbX7-uDY<2L| zBqs*X+K4G%3~W8Vw+9ptX-B?UtqXqZn8q5@&?;APN8=8Xcje&vD-_yl0q$2L^b;G>F20U$nCwDf8y^Y#be$sJC*!TTjjuk($6jz8ZMeY5QK-#PyZoJ* zQG@ow?OqMqi40CQ24TzZ%0Iqe_qd|8MeD4$@WS zGBr5NU{DY+vF`QodmYQFz~I8VCwXAaSW+oe0z)0Wlp`!@sC$z zt*-yyU!=*Pz}UdTI8m8_p)u8I1)uxGnRgiim~Mnf%P?>xltwE~Vkl7Bv`}u-ofo^! z*(C1T?!RCBci#N-v&9)|?4Miy;MG_MCV@Sa~Hn3gCx z^QduV3zN`{bWW}pO1&HSKj+BDE)#Uy*sMNdvHF_?ktKpvFL|E5;MtpU&&A*n=ByRBdSz zdHLgimaY1GNB07u%OBM*I552qY+_Tp(Era_d)edbA32J@aDTOv`5*0bT;7@enJ0Vl ziADcE+HTALXLDxr&z`<|smmXiZ=C(`@ts(o!|v+~#7=({FJO5+Sy|`6((9G>b%NeI zTJ}!x)>+tLlKcGQ57jk`c)4AqS8G`I2>khYdc{LAu@%u*0?H&5cRc1_+%|v1oF9!+ zZNWVPXFj%X=#h@_yPF{CTv%GhOIOjVv_n!Nm@16%c8|BoKqK^zy z%&^ERKl#9Gp7EFmT%iVIM-?~7@Rgj;oaGVi#7%;}k5LGZU26C&_<2crc*9+it*hs-IW5`F*TeIDkudk5 zYupxmErz9d-Ga$ctyJZy;O|1n! z^MdP*)PFv_Ov=yLxIo#ewFeMm!R7V23x43UqDmldy(JeBqCz#YMF^b&->)or0Lkr~ z*dwkNGX`i-Nhy0x%SA#r|785HhZZ?M7+g0se(4*P}+|AmR)&r(7P}3}MFgAfX)ok`{e$GXyt{R(*&KYl6QS zf?Gt1C=OswV*okQwg=$Yy@VXQH?d=P8g=YA$kKlB?W7XUR%C9{F8KD*X-6z*+-(Cb z1{XAr-6f@CcTw*ImsRc=xP%rA0S~OSOO_B^E?#kr#F`MM|U2wr+{S{L& zFZsUcx#WWeNpn+iu342O49hRNcR{Ox_01mG-)@8b4NutLaz=orzh<+W{x + app:drawableStartCompat="@drawable/ic_phone_01_medium_regular_outline" /> + app:drawableStartCompat="@drawable/ic_user_right_medium_regular_outline" /> + app:drawableStartCompat="@drawable/ic_edit_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_move_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_copy_01_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_log_out_02_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_move_medium_regular_outline" /> + app:drawableStartCompat="@drawable/ic_copy_01_medium_regular_outline" /> + app:drawableStartCompat="@drawable/ic_edit_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_clock_rotate_medium_regular_outline" /> @@ -416,13 +416,13 @@ android:id="@+id/move_option" style="@style/BottomSheetOption" android:text="@string/general_move_to" - app:drawableStartCompat="@drawable/ic_move"/> + app:drawableStartCompat="@drawable/ic_move_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_copy_01_medium_regular_outline"/> + app:drawableStartCompat="@drawable/ic_log_out_02_medium_regular_outline"/> 1PPS~_CiNgjrL6K fb31sVmx1PPS~_7X~)Co0NL i>1#WX!NDWJ!0_p1_EeM8yPAON7(8A5T-G@yGywp|G8HWV diff --git a/core-ui/src/main/res/drawable-mdpi/ic_grid_view_new.png b/core-ui/src/main/res/drawable-mdpi/ic_grid_view_new.png deleted file mode 100644 index 8df75720e76010f17c672a9aacfbbb58ad5777d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh0wlLOK8*rWqMj~}Ar-fh6Bh9NX?H3y(^YNX apUqhK#QtFUCeHal1q`09elF{r5}E*);S|0A diff --git a/core-ui/src/main/res/drawable-mdpi/ic_list_view_new.png b/core-ui/src/main/res/drawable-mdpi/ic_list_view_new.png deleted file mode 100644 index 843d96fa9fe1b4d22ab4830de966573010ed7c72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh0wlLOK8*rW5}q!OAr-fh6Bh9NN&msWJaK}> e$w2EuW`?Cd^)E)tv+e+@VeoYIb6Mw<&;$VJ(iQ*! diff --git a/core-ui/src/main/res/drawable-xhdpi/ic_grid_view_new.png b/core-ui/src/main/res/drawable-xhdpi/ic_grid_view_new.png deleted file mode 100644 index e84e96a64ee8e75a1d42ce36441c6ba7a2a1995c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s0wiy+h|2>h1y2{pkcwN$2@;+U?4?vx>{b;P lWXbrhUaXmJvX;+;fnmDSf5t}P=WIZ=44$rjF6*2UngAVO6;=QM diff --git a/core-ui/src/main/res/drawable-xhdpi/ic_list_view_new.png b/core-ui/src/main/res/drawable-xhdpi/ic_list_view_new.png deleted file mode 100644 index 6bbf87b3b77ec5149591fb7616a52b89c002b3cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s0wiy+h|2>hMNb#UkcwN$2@;+U>_rxRzW6ZU jnuS#V;*Vg$qnd%CBx}FpnN8*vK*bE6u6{1-oD!MaMoR!Gwg8_HS0D`pOVf9r2U3hBL4Lsu z4$p3+0Xd?cE{-7;jL8ae2LJ6p{AVs*xiHC^;ju-;%%sa-cY<_zy85}Sb4q9e0Js?( AJ^%m! diff --git a/core-ui/src/main/res/drawable-xxhdpi/ic_list_view_new.png b/core-ui/src/main/res/drawable-xxhdpi/ic_list_view_new.png deleted file mode 100644 index 2c88a2a5d6d18fead1a63f1ac13f702878d01961..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^S|H5G3?%>aMoR!Gwg8_HS0D`pOVf9r2U3hBL4Lsu z4$p3+0Xd?cE{-7;jL8ae2K5{M|8JDY`Z1G}A^5RH@a9-&DUdEtS3j3^P6G diff --git a/core-ui/src/main/res/drawable-xxxhdpi/ic_grid_view_new.png b/core-ui/src/main/res/drawable-xxxhdpi/ic_grid_view_new.png deleted file mode 100644 index 27668adb8036ceab383f4919cbac8c4c78897046..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^79h;X3?wIctc(RxYymzYu0R?HmZtAK52P4Ng8YIR y9G=}s19C(>T^vIy7?T%B{Q1xC!tB;x@|~GshGTtWcV59;kS0%8KbLh*2~7a95gSYZ diff --git a/core-ui/src/main/res/drawable-xxxhdpi/ic_list_view_new.png b/core-ui/src/main/res/drawable-xxxhdpi/ic_list_view_new.png deleted file mode 100644 index fc755faeab9e0d9d3b84b1960b13d70b4a1e1607..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^79h;X3?wIctc(RxYymzYu0R?HmZtAK52P4Ng8YIR z9G=}s19HSXT^vIy7?T%B{7L`u|G)iBlhlMObquq%#xGoVV3rz4o2RRv%Q~loCIB}q B9>f3u diff --git a/core-ui/src/main/res/drawable/ic_help_circle.xml b/core-ui/src/main/res/drawable/ic_help_circle.xml deleted file mode 100644 index b038071f45..0000000000 --- a/core-ui/src/main/res/drawable/ic_help_circle.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/core-ui/src/main/res/drawable/ic_media_discovery.xml b/core-ui/src/main/res/drawable/ic_media_discovery.xml deleted file mode 100644 index 2da1887aa9..0000000000 --- a/core-ui/src/main/res/drawable/ic_media_discovery.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/status/DeviceCenterUINodeStatus.kt b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/status/DeviceCenterUINodeStatus.kt index 33aeef5dc8..d34ff5e6aa 100644 --- a/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/status/DeviceCenterUINodeStatus.kt +++ b/feature/devicecenter/src/main/java/mega/privacy/android/feature/devicecenter/ui/model/status/DeviceCenterUINodeStatus.kt @@ -30,7 +30,7 @@ sealed class DeviceCenterUINodeStatus( data object Unknown : DeviceCenterUINodeStatus( name = R.string.device_center_list_view_item_status_unknown_status, localizedErrorMessage = null, - icon = CoreR.drawable.ic_help_circle, + icon =iconPackR.drawable.ic_help_circle_medium_regular_outline, color = null, ) diff --git a/icon-pack/src/main/res/drawable/ic_grid_4_small_regular_outline.xml b/icon-pack/src/main/res/drawable/ic_grid_4_small_regular_outline.xml new file mode 100644 index 0000000000..b1255d2201 --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_grid_4_small_regular_outline.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/icon-pack/src/main/res/drawable/ic_help_circle_medium_regular_outline.xml b/icon-pack/src/main/res/drawable/ic_help_circle_medium_regular_outline.xml new file mode 100644 index 0000000000..e31104581d --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_help_circle_medium_regular_outline.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/icon-pack/src/main/res/drawable/ic_image_01_small_regular_outline.xml b/icon-pack/src/main/res/drawable/ic_image_01_small_regular_outline.xml new file mode 100644 index 0000000000..39bfab4ca6 --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_image_01_small_regular_outline.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/icon-pack/src/main/res/drawable/ic_list_small_small_regular_outline.xml b/icon-pack/src/main/res/drawable/ic_list_small_small_regular_outline.xml new file mode 100644 index 0000000000..c11cba2c1a --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_list_small_small_regular_outline.xml @@ -0,0 +1,38 @@ + + + + + + + + + + diff --git a/icon-pack/src/main/res/drawable/ic_user_right_medium_regular_outline.xml b/icon-pack/src/main/res/drawable/ic_user_right_medium_regular_outline.xml new file mode 100644 index 0000000000..60f00905a2 --- /dev/null +++ b/icon-pack/src/main/res/drawable/ic_user_right_medium_regular_outline.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/lists/HeaderViewItem.kt b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/lists/HeaderViewItem.kt index 19d297400d..ad3e897e13 100644 --- a/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/lists/HeaderViewItem.kt +++ b/legacy-core-ui/src/main/java/mega/privacy/android/legacy/core/ui/controls/lists/HeaderViewItem.kt @@ -1,5 +1,6 @@ package mega.privacy.android.legacy.core.ui.controls.lists +import mega.privacy.android.icon.pack.R as iconPackR import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme @@ -7,6 +8,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -75,9 +77,10 @@ fun HeaderViewItem( modifier = Modifier .align(CenterVertically) .padding(end = 16.dp) + .size(16.dp) .clickable { onEnterMediaDiscoveryClick() } .testTag(MEDIA_DISCOVERY_TAG), - painter = painterResource(id = R.drawable.ic_media_discovery), + painter = painterResource(id = iconPackR.drawable.ic_image_01_small_regular_outline), colorFilter = ColorFilter.tint(color = MaterialTheme.colors.textColorSecondary), contentDescription = "Enter media discovery" ) @@ -86,13 +89,14 @@ fun HeaderViewItem( Image( modifier = Modifier .align(CenterVertically) + .size(16.dp) .clickable { onChangeViewTypeClick() }, painter = if (isListView) { - painterResource(id = R.drawable.ic_grid_view_new) + painterResource(id = iconPackR.drawable.ic_grid_4_small_regular_outline) } else { - painterResource(id = R.drawable.ic_list_view_new) + painterResource(id = iconPackR.drawable.ic_list_small_small_regular_outline) }, colorFilter = ColorFilter.tint(color = MaterialTheme.colors.textColorSecondary), contentDescription = "Toggle grid list" From 3dd92b4c037f906c095a7a611d84a7529e07c6b9 Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Fri, 12 Apr 2024 09:02:07 +0530 Subject: [PATCH 090/261] SAO-53: (T15672084) Icons from bottom sheet should be updated based on new design --- .../NodeOptionsBottomSheetDialogFragment.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsBottomSheetDialogFragment.kt index c0b81fc265..fbe1a777ff 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsBottomSheetDialogFragment.kt @@ -444,9 +444,21 @@ class NodeOptionsBottomSheetDialogFragment : BaseBottomSheetDialogFragment() { optionShareFolder.visibility = View.VISIBLE if (isOutShare(node)) { optionShareFolder.setText(R.string.manage_share) + optionShareFolder.setCompoundDrawablesWithIntrinsicBounds( + RPack.drawable.ic_gear_six_medium_regular_outline, + 0, + 0, + 0 + ) optionClearShares.visibility = View.VISIBLE } else { optionShareFolder.setText(R.string.context_share_folder) + optionShareFolder.setCompoundDrawablesWithIntrinsicBounds( + RPack.drawable.ic_folder_users_medium_regular_outline, + 0, + 0, + 0 + ) counterShares-- optionClearShares.visibility = View.GONE } From a8f8f5084dc2941dbb95ef61ce766457daeddaf0 Mon Sep 17 00:00:00 2001 From: Kevin Ham Date: Fri, 12 Apr 2024 23:48:48 +1200 Subject: [PATCH 091/261] CU-752 : Remove setNextScheduleTimeOverride --- .../privacy/android/app/facade/WorkManagerGatewayImplTest.kt | 2 ++ .../mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/test/mega/privacy/android/app/facade/WorkManagerGatewayImplTest.kt b/app/src/test/java/test/mega/privacy/android/app/facade/WorkManagerGatewayImplTest.kt index 0673b2cc1a..8f92a056c3 100644 --- a/app/src/test/java/test/mega/privacy/android/app/facade/WorkManagerGatewayImplTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/facade/WorkManagerGatewayImplTest.kt @@ -207,8 +207,10 @@ class WorkManagerGatewayImplTest { val info = awaitItem() assertThat(info[0].state).isEqualTo(WorkInfo.State.ENQUEUED) WorkManagerTestInitHelper.getTestDriver(context)?.apply { + setInitialDelayMet(info[0].id) setPeriodDelayMet(info[0].id) } + assertThat(awaitItem()[0].state).isEqualTo(WorkInfo.State.ENQUEUED) assertThat(awaitItem()[0].state).isEqualTo(WorkInfo.State.RUNNING) } } diff --git a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt index 038be8cb85..4122869c79 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/WorkManagerGatewayImpl.kt @@ -197,8 +197,8 @@ class WorkManagerGatewayImpl @Inject constructor( SCHEDULER_FLEX_INTERVAL, TimeUnit.MINUTES ) - .setNextScheduleTimeOverride(TimeUnit.MINUTES.toMillis(CU_SCHEDULER_INTERVAL)) .addTag(CAMERA_UPLOAD_TAG) + .setInitialDelay(CU_SCHEDULER_INTERVAL, TimeUnit.MINUTES) .build() workManager .enqueueUniquePeriodicWork( From 787f4dfd44509baf2ba2b0ed23672bb877488034 Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Tue, 16 Apr 2024 09:19:40 +0700 Subject: [PATCH 092/261] CC-6954: Catch Potential GetContentConsumptionPreferences Exception --- .../hidenode/HiddenNodesOnboardingViewModel.kt | 7 ++++++- .../data/repository/photos/DefaultPhotosRepository.kt | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/hidenode/HiddenNodesOnboardingViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/hidenode/HiddenNodesOnboardingViewModel.kt index 15aa059eb6..8f7ad1d302 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/hidenode/HiddenNodesOnboardingViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/hidenode/HiddenNodesOnboardingViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import mega.privacy.android.domain.usecase.SetHiddenNodesOnboardedUseCase +import timber.log.Timber import javax.inject.Inject @HiltViewModel @@ -12,6 +13,10 @@ internal class HiddenNodesOnboardingViewModel @Inject constructor( private val setHiddenNodesOnboardedUseCase: SetHiddenNodesOnboardedUseCase, ) : ViewModel() { fun setHiddenNodesOnboarded() = viewModelScope.launch { - setHiddenNodesOnboardedUseCase() + runCatching { + setHiddenNodesOnboardedUseCase() + }.onFailure { + Timber.e(it) + } } } diff --git a/data/src/main/java/mega/privacy/android/data/repository/photos/DefaultPhotosRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/photos/DefaultPhotosRepository.kt index 3b4bfe35aa..581122dddb 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/photos/DefaultPhotosRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/photos/DefaultPhotosRepository.kt @@ -935,7 +935,12 @@ internal class DefaultPhotosRepository @Inject constructor( } override suspend fun isHiddenNodesOnboarded(): Boolean = withContext(ioDispatcher) { - sensitivesRetriever(prefs = getContentConsumptionPreferences()) + try { + val prefs = getContentConsumptionPreferences() + sensitivesRetriever(prefs) + } catch (t: Throwable) { + false + } } override suspend fun setHiddenNodesOnboarded() = withContext(ioDispatcher) { From af65996f9bf35e314b3154f2de7f4a6b77f394a8 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Wed, 17 Apr 2024 06:50:46 +0700 Subject: [PATCH 093/261] Pre-release v12.0 (cherry picked from commit bf2e9d1d16fd86c3a7b933b63cf862f0141898ad) --- app/src/main/res/values-ar/strings.xml | 14 +- app/src/main/res/values-de/strings.xml | 14 +- app/src/main/res/values-es/strings.xml | 35 ++--- app/src/main/res/values-fr/strings.xml | 14 +- app/src/main/res/values-in/strings.xml | 14 +- app/src/main/res/values-it/strings.xml | 14 +- app/src/main/res/values-ja/strings.xml | 16 +- app/src/main/res/values-ko/strings.xml | 14 +- app/src/main/res/values-nl/strings.xml | 52 +++---- app/src/main/res/values-pl/strings.xml | 58 ++++--- app/src/main/res/values-pt/strings.xml | 14 +- app/src/main/res/values-ro/strings.xml | 16 +- app/src/main/res/values-ru/strings.xml | 14 +- app/src/main/res/values-th/strings.xml | 14 +- app/src/main/res/values-vi/strings.xml | 29 ++-- app/src/main/res/values-zh-rCN/strings.xml | 68 ++++----- app/src/main/res/values-zh-rTW/strings.xml | 35 ++--- .../strings_device_center_feature.xml | 24 +-- .../strings_device_center_feature.xml | 26 ++-- .../strings_device_center_feature.xml | 4 +- .../res/values-nl/strings_sync_feature.xml | 8 +- .../res/values-pl/strings_sync_feature.xml | 8 +- .../res/values-vi/strings_sync_feature.xml | 8 +- .../src/main/res/values-ar/strings_shared.xml | 114 ++++++++++++++ .../src/main/res/values-de/strings_shared.xml | 110 +++++++++++++ .../src/main/res/values-es/strings_shared.xml | 111 ++++++++++++++ .../src/main/res/values-fr/strings_shared.xml | 111 ++++++++++++++ .../src/main/res/values-in/strings_shared.xml | 109 +++++++++++++ .../src/main/res/values-it/strings_shared.xml | 123 ++++++++++++++- .../src/main/res/values-ja/strings_shared.xml | 109 +++++++++++++ .../src/main/res/values-ko/strings_shared.xml | 109 +++++++++++++ .../src/main/res/values-nl/strings_shared.xml | 142 +++++++++++++++-- .../src/main/res/values-pl/strings_shared.xml | 144 ++++++++++++++++-- .../src/main/res/values-pt/strings_shared.xml | 111 ++++++++++++++ .../src/main/res/values-ro/strings_shared.xml | 111 ++++++++++++++ .../src/main/res/values-ru/strings_shared.xml | 112 ++++++++++++++ .../src/main/res/values-th/strings_shared.xml | 109 +++++++++++++ .../src/main/res/values-vi/strings_shared.xml | 109 +++++++++++++ .../main/res/values-zh-rCN/strings_shared.xml | 121 ++++++++++++++- .../main/res/values-zh-rTW/strings_shared.xml | 109 +++++++++++++ 40 files changed, 2142 insertions(+), 335 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index ea0559768b..9698027c1c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6031,21 +6031,13 @@ احصل على المزيد مع باقة برو Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - مشاركة تراسل المعطيات - - يمكن للأشخاص الذين تشارك البيانات معهم استخدام حجم تراسل المعطيات المتاح لك لتنزيل وبث العناصر التي شاركتها. - - أمان إضافي عند المشاركة - - قم بتعيين كلمات المرور وتواريخ انتهاء الصلاحية لروابط الملفات والمجلدات. Upgrade to Pro today @@ -6345,8 +6337,12 @@ All hidden items will be visible, but blurred to indicate their “hidden” status Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 36ede9dbf7..a43786ba4b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5107,21 +5107,13 @@ Mit einem Pro-Paket bekommen Sie mehr - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - Transfervolumen teilen - - Die Personen, für die Sie Daten freigeben, können Ihr Transfervolumen nutzen, um die von Ihnen freigegebenen Inhalte herunterzuladen und zu streamen. - - Mehr Sicherheit beim Teilen - - Schützen Sie Datei- und Ordnerlinks mit Passwort und Ablaufdatum. Upgrade to Pro today @@ -5397,8 +5389,12 @@ All hidden items will be visible, but blurred to indicate their “hidden” status Foto + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1d4f53fbec..4bcb227db7 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -764,7 +764,7 @@ Confirma el correo electrónico - Check your email inbox to proceed. + Ve a la bandeja de entrada de tu correo electrónico para continuar. Se ha producido un error, por favor inténtalo de nuevo. @@ -808,7 +808,7 @@ Esta es tu dirección de correo electrónico actual. - This is the last step to change your email address. Enter your password below. + Este es el último paso para cambiar tu correo electrónico. Introduce tu contraseña. Cambiar correo electrónico @@ -2101,8 +2101,9 @@ Más - Choose file - Choose files + Elegir archivo + Elegir archivos + Elegir archivos Elige carpeta @@ -5337,23 +5338,15 @@ Obtén más con un plan Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Amplía a un plan Pro y obtén más almacenamiento y acceso a todas las características Pro. Los planes comienzan desde tan solo %1$s al mes. - MEGA Pro plans include: + Los planes MEGA Pro incluyen: - Ultimate storage flexibility + Máxima flexibilidad de almacenamiento - Starting from %1$s, find the perfect fit for your storage needs. - - Transferencia compartida - - Las personas con las que compartes datos pueden usar tu cuota de transferencia para descargar y hacer streaming de lo que has compartido. - - Seguridad adicional al compartir - - Establece contraseñas y fechas de caducidad para los enlaces a carpetas y archivos. + A partir de %1$s, encuentra la solución perfecta para tus necesidades de almacenamiento. - Upgrade to Pro today + Amplía a Pro hoy mismo %1$s está presentando @@ -5634,8 +5627,12 @@ Todos los elementos ocultos estarán visibles, pero desenfocados para indicar su estado “oculto” Foto + Modo flash activado - Flash mode off - Flash mode auto + + Modo flash desactivado + + Modo flash automático + Enviar a %1$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 96c3114686..deb8188d39 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -2990,7 +2990,7 @@ Le lien et le mot de passe ont été envoyés - Passer à un compte Pro + Souscrire un abonnement Pro Les utilisateurs de MEGA Pro ont l’accès exclusif à des fonctions supplémentaires de sécurité des liens qui rendent votre compte encore plus sûr. @@ -5345,14 +5345,6 @@ La plus grande flexibilité en matière d’espace de stockage À partir de %1$s, trouvez la réponse idéale à vos besoins de stockage. - - Partage des transferts - - Les personnes avec qui vous partagez des données peuvent utiliser votre quota de transfert pour télécharger ou diffuser en continu les éléments que vous avez partagés. - - Sécurité supplémentaire lors de partages - - Définissez des mots de passe et des dates d’expiration pour les liens de fichier et de dossier. Passer à un abonnement Pro @@ -5635,8 +5627,12 @@ Tous les éléments cachés seront visibles, mais flous pour indiquer leur état « caché » Photo + Flash activé + Flash désactivé + Flash automatique + Envoyer vers %1$s \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index b89dc74c39..262baece73 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4877,21 +4877,13 @@ Dapatkan lebih banyak dengan paket Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - Berbagi transfer - - Orang yang anda bagikan datanya dapat menggunakan kuota transfer anda untuk mengunduh dan melakukan streaming item yang anda bagikan. - - Keamanan tambahan saat berbagi - - Tetapkan kata sandi dan tanggal kedaluwarsa untuk tautan file dan folder. Upgrade to Pro today @@ -5160,8 +5152,12 @@ All hidden items will be visible, but blurred to indicate their “hidden” status Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 010a5ca457..aaff2b829e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5337,21 +5337,13 @@ Ottieni di più con un piano Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - Condivisione della banda di trasferimento - - Le persone con cui condividi dati possono utilizzare la tua banda di trasferimento per scaricare ed effettuare lo streaming degli oggetti che hai condiviso. - - Sicurezza addizionale nella condivisione - - Imposta password e date di scadenza per i link di file e cartelle. Upgrade to Pro today @@ -5634,8 +5626,12 @@ Tutti gli oggetti nascosti saranno visibili, ma sfocati per indicare il loro status “nascosto” Foto + Flash attivo + Flash mode off + Flash mode auto + Invia a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 390a4b89c0..a2d29f1e9d 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4876,21 +4876,13 @@ Proプランでさらに充実 - Proプランにアップグレードしていただくと、ストレージが増え、各種Pro機能をご利用いただけるようになります。プランは月額%1$sからご利用いただけます + Proプランにアップグレードしていただくと、ストレージが増え、各種Pro機能をご利用いただけるようになります。プランは月額%1$sからご利用いただけます。 - MEGA Pro plans include: + MEGA Proプランには次のものが含まれます: 究極のストレージの柔軟性 %1$sから始めて、お客様のストレージのニーズに最適なものを見つけてください。 - - 転送共有 - - データを共有する相手は、お客様の転送容量を使用して、お客様が共有した項目をダウンロードしてストリーミングできます。 - - 共有時のセキュリティの強化 - - ファイルとフォルダのリンクのパスワードと有効期限を設定できます。 今すぐProにアップグレード @@ -5159,8 +5151,12 @@ 非表示の項目はすべて表示されますが、「非表示」ステータスを示すためにぼかされます 写真 + フラッシュモードオン + フラッシュモードオフ + フラッシュモード自動 + %1$sに送信 \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index bd13ee1cc2..e9cea52b40 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4877,21 +4877,13 @@ Pro 요금제로 더 받기 - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - 전송 공유 - - 당신이 데이터를 공유해준 사람들이 당신이 공유해준 것을 다운로드 하거나 스트림 하기 위해 당신의 전송 할당량을 이용할 수 있습니다. - - 공유할 때 추가 보안 - - 파일과 폴더 링크에 암호와 만료일을 설정 Upgrade to Pro today @@ -5160,8 +5152,12 @@ All hidden items will be visible, but blurred to indicate their “hidden” status 사진 + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index d788f91705..3a572544bc 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -755,7 +755,7 @@ E-mail adres verificatie - Check your email inbox to proceed. + Controleer uw e-mailinbox om verder te gaan. Er is een fout opgetreden, probeer nogmaals. @@ -799,7 +799,7 @@ Dit is uw bestaande e-mailadres. - This is the last step to change your email address. Enter your password below. + Dit is de laatste stap om uw e-mailadres te wijzigen. Voer hieronder uw wachtwoord in. E-mailadres wijzigen @@ -815,7 +815,7 @@ Wachten op informatie… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + Uw nieuwe e-mailadres moet worden gevalideerd. Controleer de inbox van het nieuwe e-mailadres om verder te gaan. Uw profielfoto verwijderen? @@ -844,7 +844,7 @@ Teveel mislukte pogingen om in te loggen, alstublieft wacht voor een uur. - This account has not been validated yet. Check your email inbox. + Dit account is nog niet gevalideerd. Controleer uw e-mailinbox. Link naar map is niet beschikbaar @@ -858,7 +858,7 @@ In afwachting op e-mail bevestiging - Check your email inbox and follow the link to confirm your account. + Controleer uw e-mailinbox en volg de link om uw account te bevestigen. %1$d item @@ -2056,8 +2056,8 @@ Meer - Choose file - Choose files + Kies een bestand + Kies bestanden Kies map @@ -2324,7 +2324,7 @@ Oproepen inschakelen - Allow access to your address book + Geef toegang tot uw adresboek Ontdek gemakkelijk contacten uit uw adresboek op MEGA. @@ -3390,7 +3390,7 @@ U heeft al een abonnement. Koopt u er nog één, dan betaalt u twee keer. Om dit te voorkomen, zegt u uw huidige abonnement op door naar MEGA te gaan in een desktop- of mobiele webbrowser. Bezoek ons ​​Helpcentrum voor meer informatie. - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + Ga naar Instellingen om MEGA-toestemming te geven om via Bluetooth toegang te krijgen tot uw apparaten in de buurt. We kunnen de facturering niet voortzetten. Als u een dubbele applicatie gebruikt, overweeg dan om zonder in te loggen op MEGA. Als dit niet het geval is, probeer dan te upgraden via uw webbrowser. @@ -3748,7 +3748,7 @@ Dit is waar uw back-upbestanden en mappen worden opgeslagen. Uw back-upitems zijn “alleen-lezen” om te voorkomen dat ze per ongeluk worden gewijzigd in uw clouddrive.\nU kunt een back-up maken van items op uw computer naar MEGA met behulp van onze desktop-applicatie. - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + Uw MEGA-account is opgeschort vanwege herhaalde beschuldigingen van schendingen van auteursrechten. Dit betekent dat u geen toegang hebt tot uw account of de gegevens die erin staan.\nKijk in uw e-mailinbox voor meer informatie over hoe u een tegenmelding kunt indienen. Uw account is beëindigd vanwege een schending van MEGA\’s Algemene Voorwaarden.\nU kunt geen toegang meer krijgen tot uw opgeslagen gegevens of worden geautoriseerd om een ​​nieuw MEGA-account te registreren. @@ -3879,7 +3879,7 @@ Verwijderen van album? - To enable camera uploads, allow MEGA access to your photos and other media on your device. + Om camera-uploads mogelijk te maken, moet u MEGA toegang geven tot uw foto\’s en andere media op uw apparaat. Toegang Toestaan @@ -5107,23 +5107,15 @@ Krijg meer met een Pro abonnement - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade naar een Pro-abonnement en krijg meer opslag en toegang tot Pro-kenmerken. Abonnementen beginnen zo laag als %1$s een maand. - MEGA Pro plans include: + MEGA   Pro-abonnementen omvatten: - Ultimate storage flexibility + Ultieme opslagflexibiliteit - Starting from %1$s, find the perfect fit for your storage needs. - - Overdracht deling - - De mensen met wie u gegevens deelt, kunnen uw overdrachtstegoed gebruiken om de items die u hebt gedeeld te downloaden en te streamen. - - Extra veiligheid bij het delen - - Stel wachtwoorden en vervaldata in voor bestands- en mapkoppelingen. + Vanaf %1$s, vind de perfecte oplossing voor uw opslagbehoeften. - Upgrade to Pro today + Upgrade vandaag nog naar Pro %1$s is aan het presenteren @@ -5222,7 +5214,7 @@ Abonnementen worden automatisch verlengd voor opeenvolgende abonnementsperioden van dezelfde duur en tegen dezelfde prijs als de gekozen initiële periode. U kunt de automatische verlenging van uw MEGA   Pro-abonnement uiterlijk 24 uur voordat uw volgende abonnementsbetaling verschuldigd is, uitschakelen via Abonnementen in [A]Google Play[/A]. - Allow access to your Gallery + Geef toegang tot uw galerij Toegang Toestaan @@ -5397,8 +5389,12 @@ Alle verborgen items zijn zichtbaar, maar wazig om hun “verborgen” status aan te geven Foto - Flash mode on - Flash mode off - Flash mode auto + + Flitsmodus aan + + Flitsmodus uit + + Flitsmodus automatisch + Verzenden naar %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b053e8d11d..9b5e25b069 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -773,7 +773,7 @@ Weryfikacja adresu e-mail - Check your email inbox to proceed. + Sprawdź swoją skrzynkę email, aby kontynuować. Wystąpił błąd, spróbuj ponownie. @@ -817,7 +817,7 @@ Jest to Twój dotychczasowy adres e-mail. - This is the last step to change your email address. Enter your password below. + To ostatni krok do zmiany adres email. Wpisz swoje hasło poniżej. Zmień e-mail @@ -833,7 +833,7 @@ Pobieranie danych… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + Twój nowy adres email musi zostać zweryfikowany. Sprawdź skrzynkę odbiorczą nowego adres email aby kontynuować. Usunąć zdjęcia profilowe? @@ -864,7 +864,7 @@ Zbyt wiele nieudanych prób logowania. Zaczekaj godzinę. - This account has not been validated yet. Check your email inbox. + To konto nie zostało jeszcze zweryfikowane. Sprawdź swoją skrzynkę email. Link do katalogu jest niedostępny @@ -878,7 +878,7 @@ Oczekiwanie na potwierdzenia konta - Check your email inbox and follow the link to confirm your account. + Sprawdź swoją skrzynkę email i kliknij link, aby potwierdź swoje konto. %1$d element @@ -2146,8 +2146,10 @@ Więcej - Choose file - Choose files + Wybierz plik + Wybierz pliki + Wybierz pliki + Wybierz pliki Wybierz katalog @@ -2430,7 +2432,7 @@ Włącz połączenia - Allow access to your address book + Zezwalaj na dostęp do książki adresowej Łatwo odkrywaj kontakty z książki adresowej na MEGA. @@ -3572,7 +3574,7 @@ Masz już wykupioną subskrypcję. Jeśli kupisz kolejną, zostaniesz obciążony podwójną opłatą. Aby tego uniknąć, anuluj swoją obecną subskrypcję, wchodząc na stronę MEGA w przeglądarce internetowej na komputerze lub w telefonie komórkowym. Odwiedź nasze Centrum Pomocy, aby uzyskać więcej informacji. - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + Przejdź do Ustawienia, aby zezwolić MEGA na dostęp do pobliskich urządzeń za pomocą Bluetooth. Nie możemy kontynuować rozliczenia. Jeśli używasz podwójnej aplikacji, rozważ możliwość zalogowania się do MEGA bez niej. Jeśli nie, spróbuj dokonać aktualizacji przez przeglądarkę internetową. @@ -3942,7 +3944,7 @@ W tym miejscu są przechowywane pliki i foldery, których kopie zapasowe zostały utworzone. Kopie zapasowe są dostępne „tylko do odczytu”, co chroni je przed przypadkową modyfikacją na dysku w chmurze.Kopię zapasową elementów z komputera możesz utworzyć na MEGA za pomocą naszej aplikacji desktopowej. - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + Twoje konto MEGA zostało zawieszone z powodu powtarzających się zarzutów naruszenia praw autorskich. Oznacza to, że nie możesz uzyskać dostępu do swojego konto ani danych na nim.\nSprawdź swoją skrzynkę email, aby uzyskać więcej informacji o tym, jak złożyć zawiadomienie. Twoje konto zostało zamknięte z powodu naruszenia Warunków świadczenia usług MEGA. \nNie będziesz w stanie odzyskać dostępu do przechowywanych danych ani uzyskać autoryzacji do rejestracji nowego konta MEGA. @@ -4083,7 +4085,7 @@ Usunąć z albumu? - To enable camera uploads, allow MEGA access to your photos and other media on your device. + Aby włączyć przesyłanie z kamery, zezwól firmie MEGA na dostęp do zdjęć i innych nośników na urządzeniu. Udostępnik @@ -5567,23 +5569,15 @@ Zyskaj więcej dzięki planowi Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Uaktualnij do planu Pro i uzyskaj pojemność miejsca i dostęp do funkcji Pro. Plany zaczynają się od %1$s Miesiąc. - MEGA Pro plans include: + Plany MEGA   Pro obejmują: - Ultimate storage flexibility + Najwyższa elastyczność pojemność masowej - Starting from %1$s, find the perfect fit for your storage needs. - - Współdzielenie transferu - - Osoby, którym udostępniasz dane, mogą korzystać z limitu transferu, aby pobierać i przesyłać strumieniowo udostępnione elementy. - - Dodatkowe zabezpieczenia podczas udostępniania - - Ustawianie haseł i dat wygaśnięcia dla łączy do plików i katalogów. + Zaczynając od %1$s, znajdź idealne dopasowanie do swoich potrzeb pojemność. - Upgrade to Pro today + Uaktualnij do Pro już dziś %1$s prezentuje @@ -5688,7 +5682,7 @@ Subskrypcje są odnawiane automatycznie na kolejne okresy subskrypcji o tym samym czasie trwania i w tej samej cenie, co wybrany okres początkowy. Użytkownik może wyłączyć automatyczne odnawianie subskrypcji MEGA Pro nie później niż 24 godziny przed terminem płatności kolejnej subskrypcji za pośrednictwem Subskrypcji w [A]Google Play[/A]. - Allow access to your Gallery + Zezwalaj na dostęp do swojej galerii Udostępnik @@ -5868,11 +5862,15 @@ Pokaż ukryte elementy - All hidden items will be visible, but blurred to indicate their “hidden” status + Wszystkie ukryte elementy będą widoczne, ale rozmyte, aby wskazać ich status „ukryty” Zdjęcie - Flash mode on - Flash mode off - Flash mode auto - Send to %1$s + + Tryb Flash włączony + + Tryb Flash wyłączony + + Tryb Flash automatyczny + + Wyślij do %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 6c00cc17b7..c91b0499a3 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5338,21 +5338,13 @@ Obtenha mais com um plano Pro - Faça o upgrade a um plano Pro para obter mais armazenamento e acessar recursos exclusivos. O nossos planos são a partir de %1$s por mês + Faça o upgrade a um plano Pro para obter mais armazenamento e acessar recursos exclusivos. O nossos planos são a partir de %1$s por mês. Os planos Pro do MEGA incluem: Flexibilidade de armazenamento máxima Encontre o melhor opção para as suas necessidades de armazenamento a partir de %1$s. - - Compartilhamento de transferência - - As pessoas com as quais você compartilhar dados podem usar a sua cota de transferência para fazer download e streaming dos itens que você compartilhou. - - Segurança adicional ao compartilhar - - Adicione senhas e datas de validade para links de arquivos e de pastas. Fazer o upgrade a um plano Pro @@ -5635,8 +5627,12 @@ Todos os itens ocultos ficarão visíveis, mas desfocados para indicar o seu status “oculto” Foto + Flash ativo + Flash desativado + Flash automático + Enviar a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index f4ae3ae843..a650016cd3 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5338,21 +5338,13 @@ Obțineți mai mult cu un abonament Pro - Treceți la un abonament Pro și obțineți mai mult spațiu de stocare și acces la funcțiile Pro. Planurile încep de la %1$s o lună + Treceți la un abonament Pro și obțineți mai mult spațiu de stocare și acces la funcțiile Pro. Planurile încep de la %1$s o lună. - MEGA Pro plans include: + Abonamentele MEGA Pro includ: Flexibilitate maximă în spațiu de stocare Începând de la %1$s, găsiți potrivirea perfectă pentru nevoile dvs. de stocare. - - Partajarea transferurilor - - Persoanele cu care partajați date pot folosi cota de transfer pentru a descărca și transmite în flux elementele pe care le-ați partajat. - - Securitate suplimentară la partajare - - Setați parolele și datele de expirare pentru linkurile de fișiere și folder. Upgradeați la un abonament Pro @@ -5635,8 +5627,12 @@ Toate elementele ascunse vor fi vizibile, dar încețoșate pentru a indica starea lor „ascunse” Fotografie + Flash activat + Flash dezactivat + Flash automat + Trimiteți la %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 41850f8601..5d4687ff8e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5567,21 +5567,13 @@ Получите больше с планом Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - Обмен объёмами передач - - Люди, с которыми вы делитесь данными, могут использовать ваш объём передачи данных для скачивания и трансляции элементов, которыми вы поделились. - - Дополнительная безопасность при обмене - - Устанавливайте пароли и сроки действия для ссылок на файлы и папки. Upgrade to Pro today @@ -5871,8 +5863,12 @@ Все скрытые элементы будут видны, но размыты, чтобы указать на их «скрытый» статус Фото + Flash mode on + Flash mode off + Flash mode auto + Отправить в «%1$s» \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 62570fa017..b2c5242a92 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4877,21 +4877,13 @@ รับสิทธิประโยชน์เพิ่มเติมด้วยการอัปเกรดเป็นแผน Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. MEGA Pro plans include: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - แชร์การถ่ายโอนของคุณให้คนอื่นได้ - - คนที่คุณแชร์ข้อมูลด้วย สามารถใช้โควต้าการถ่ายโอนของคุณเพื่อดาวน์โหลดและสตรีมรายการที่คุณแชร์ได้ - - เพิ่มความปลอดภัยเมื่อแชร์ข้อมูล - - ลิงก์ไฟล์และโฟลเดอร์สามารถตั้งรหัสผ่านและวันหมดอายุได้ Upgrade to Pro today @@ -5160,8 +5152,12 @@ All hidden items will be visible, but blurred to indicate their “hidden” status Photo + Flash mode on + Flash mode off + Flash mode auto + Send to %1$s \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 28baf4115b..1e9244487f 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -2011,8 +2011,7 @@ Thêm nữa - Choose file - Choose files + Chọn tệp tin Chọn thư mục @@ -4877,23 +4876,15 @@ Nhận được nhiều hơn với gói Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. - MEGA Pro plans include: + Các gói MEGA Pro có bao gồm: Ultimate storage flexibility Starting from %1$s, find the perfect fit for your storage needs. - - Chia sẻ lượng truyền tải - - Những người bạn chia sẻ dữ liệu có thể sử dụng băng thông truyền tải của bạn để tải xuống và truyền trực tuyến các mục bạn đã chia sẻ. - - Lớp bảo mật bổ sung khi chia sẻ - - Đặt mật khẩu và ngày hết hạn cho các đường liên kết tệp tin và thư mục. - Upgrade to Pro today + Nâng cấp lên Pro ngay hôm nay %1$s hiện đang trình bày @@ -4989,7 +4980,7 @@ Các gói đăng ký được tự động gia hạn cho khoảng thời gian đăng ký kế tiếp có cùng thời lượng và ở cùng mức giá như khoảng thời gian ban đầu đã chọn. Bạn có thể tắt tự động gia hạn gói đăng ký MEGA Pro của mình không được ít hơn 24 giờ trước khi đến kỳ hạn thanh toán cho gói đăng ký tiếp theo thông qua trang Gói thuê bao trong [A]Google Play[/A]. - Allow access to your Gallery + Cho phép truy cập vào Thư viện Hình ảnh của bạn Cho phép quyền truy cập @@ -5160,8 +5151,12 @@ Tất cả các mục ẩn sẽ hiển thị, nhưng bị làm mờ để cho biết trạng thái là bị “ẩn” Ảnh - Flash mode on - Flash mode off - Flash mode auto + + Bật đèn flash + + Tắt đèn flash + + Đèn flash tự động + Gửi đến %1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 5223ac4375..2163b57560 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -746,7 +746,7 @@ 电子邮件地址验证 - Check your email inbox to proceed. + 检查您的电子邮件收件箱以继续。 发生错误,请再试一次。 @@ -790,7 +790,7 @@ 这是您当前的电子邮件地址。 - This is the last step to change your email address. Enter your password below. + 这是更改您的电子邮件地址的最后一步。在下方输入您的密码。 更改电子邮件地址 @@ -806,7 +806,7 @@ 正在获取信息… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + 您的新电子邮件地址需要验证。检查新电子邮件地址的收件箱以继续。 是否删除您的头像? @@ -834,7 +834,7 @@ 尝试登录次数过多,请一小时后再试。 - This account has not been validated yet. Check your email inbox. + 此帐户尚未通过验证。检查您的电子邮件收件箱。 文件夹链接不可用 @@ -2011,8 +2011,7 @@ 更多 - Choose file - Choose files + 选择文件 选择文件夹 @@ -2271,7 +2270,7 @@ 启用通话 - Allow access to your address book + 允许访问您的通讯录 从您的MEGA通讯录中轻松发现联系人。 @@ -3299,7 +3298,7 @@ 您当前已经有一个订阅。若购买另一个,您将被收取两次费用。为避免重复订阅,请在电脑或手机网页浏览器中登录MEGA以取消您当前的订阅。访问我们的帮助中心了解更多信息。 - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + 前往设置以授予MEGA使用蓝牙访问附近设备的权限。 我们无法处理您的购买。如果您正在使用双应用程序,请尝试退出一个后登录MEGA。否则,请尝试通过网络浏览器进行升级。 @@ -3651,7 +3650,7 @@ 这是存储您备份的文件和文件夹的地方。您备份的项目是“只读”以保护它们不会在您的云驱动器中被意外修改。您可以使用我们的桌面应用程序将计算机中的项目备份到MEGA。 - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + 由于多次被指控侵犯版权,您的MEGA帐户已被停用。这意味着您无法访问您的帐户或其中的数据。\n检查您的电子邮件收件箱,了解有关如何提交抗辩通知的更多信息。 由于违反MEGA的服务条款,您的帐户已被终止。\n您将无法重新获得对存储数据的访问权限,也无法被授权注册新的MEGA账户。 @@ -3777,7 +3776,7 @@ 要从相册中移除吗? - To enable camera uploads, allow MEGA access to your photos and other media on your device. + 若要启用相机上传,请授予MEGA访问您设备上照片和其它媒体的权限。 允许访问 @@ -4761,7 +4760,7 @@ 应用程序已更新 - Relaunch the app + 重新启动应用程序 允许访问音频文件 @@ -4877,23 +4876,15 @@ 通过Pro方案获得更多权益 - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + 升级到Pro方案,获得更多存储空间和使用Pro功能的权限。方案起价低至%1$s一个月。 - MEGA Pro plans include: + MEGA Pro方案包括: - Ultimate storage flexibility + 极致的存储灵活性 - Starting from %1$s, find the perfect fit for your storage needs. - - 传输流量共享 - - 与您共享数据的人可以使用您的传输流量来下载和串流播放您共享的项目。 - - 共享时的额外安全性 - - 为文件和文件夹链接设置密码和到期日期。 + 从%1$s起,找到最适合您存储需求的方案。 - Upgrade to Pro today + 今天升级到Pro %1$s正在展示 @@ -4989,7 +4980,7 @@ 订阅将自动续订,续订周期与初始选择的周期相同,并且以相同的价格进行续订。您可以在下一次订阅付款到期前24小时以内,通过[A]Google Play[/A]订阅界面关闭MEGA Pro订阅的自动续订功能。 - Allow access to your Gallery + 允许访问您的图库 允许访问 @@ -5079,7 +5070,7 @@ %1$s%2$s到期 - Only 100 participants can join the call. Any additional participants will only be able to send and receive messages. The organiser can upgrade to Pro to remove these restrictions. + 只有100位参与者可以加入通话。任何其他参与者只能发送和接收消息。组织者可以升级到Pro版以移除这些限制。 只有100位 参与者可以加入通话。任何其他参与者将只能发送和阅读聊天记录。请求组织者取消此限制。 @@ -5114,11 +5105,10 @@ 您可以决定何时显示隐藏的文件。有一个新的设置可以暂时显示隐藏的项目。 - %1$d item hidden - %1$d items hidden + 已隐藏%1$d个项目 - • Priority support + •  优先支持 升级到Pro版即可获得无限通话 @@ -5152,17 +5142,21 @@ 较旧的 - Trouble logging in? + 登录时遇到问题? - Report your issue + 报告您的问题 显示隐藏的项目 - All hidden items will be visible, but blurred to indicate their “hidden” status + 所有隐藏的项目都将可见,但会模糊显示以表示其“隐藏”状态 - Photo - Flash mode on - Flash mode off - Flash mode auto - Send to %1$s + 拍照 + + 闪光灯模式开启 + + 闪光模式关闭 + + 闪光模式自动 + + 发送至%1$s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6080b46c57..1792b13e04 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -746,7 +746,7 @@ 電子郵件地址驗證 - Check your email inbox to proceed. + 檢查您的電子郵件收件匣以繼續。 發生錯誤,請再試一次。 @@ -790,7 +790,7 @@ 這是您目前的電子郵件地址。 - This is the last step to change your email address. Enter your password below. + 這是更改您電子郵件地址的最後一步。在下方輸入您的密碼。 更改電子信箱 @@ -806,7 +806,7 @@ 正在取得資訊⋯ - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + 您的新電子郵件地址需要驗證。檢查新電子郵件地址的收件匣以繼續。 要刪除您的個人資料相片嗎? @@ -2011,8 +2011,7 @@ 更多 - Choose file - Choose files + 選擇檔案 選擇資料夾 @@ -4877,23 +4876,15 @@ 透過Pro方案獲得更多功能 - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month + 升級到Pro方案可獲得更多儲存空間和使用Pro功能的權限。方案一個月%1$s起。 - MEGA Pro plans include: + MEGA Pro方案包括: - Ultimate storage flexibility + 終極的儲存彈性 - Starting from %1$s, find the perfect fit for your storage needs. - - 傳輸流量共享 - - 與您共享資料的人可以使用您的傳輸配額來下載和串流播放您所共享的項目。 - - 共享時的額外安全性 - - 為檔案和資料夾連結設定密碼和到期日期。 + 從%1$s起,找到最適合您儲存需求的方案。 - Upgrade to Pro today + 立即升級到Pro %1$s正在展示 @@ -5160,8 +5151,12 @@ 可看到所有隱藏的項目,但會模糊顯示以表示其「隱藏」狀態 拍照 + 閃光模式開啟 - Flash mode off - Flash mode auto + + 閃光燈模式關閉 + + 閃光燈模式自動 + 發送至%1$s \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml index 6404d33699..f8af303c99 100644 --- a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml @@ -59,7 +59,7 @@ Geen synchronisatiefout - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA kan deze map niet synchroniseren of backuppen omdat het bestandssysteem op uw apparaat niet wordt ondersteund De map die u heeft gekozen, kan niet worden gesynchroniseerd @@ -73,25 +73,25 @@ U kunt deze map niet synchroniseren of er een back-up van maken omdat uw abonnement is verlopen - Folder can’t be synced as the user who shared this folder has reached their storage quota + De map kan niet worden gesynchroniseerd omdat de gebruiker die deze map heeft gedeeld zijn of haar opslagtegoed heeft bereikt De map in MEGA kan niet worden gevonden omdat deze is verplaatst of verwijderd, of u heeft mogelijk geen toegang. - Folder can’t be synced as it’s a shared folder without full access + De map kan niet worden gesynchroniseerd omdat het een gedeelde map is zonder volledige toegang - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet het synchroniseren of backuppen opnieuw inschakelen via de desktop applicatie. De map kan niet worden gesynchroniseerd omdat deze al gesynchroniseerde mappen bevat MEGA kan VirtualBox-mappen niet synchroniseren of er een back-up van maken - Unable to sync or back up this folder as the account has been blocked + Kan deze map niet synchroniseren of er een back-up van maken omdat het account is geblokkeerd - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + Probleem bij het synchroniseren of maken van een reservekopie van deze map. Probeer het later nog eens. Als het probleem zich blijft voordoen, neem contact op met de klantenservice. Account opnieuw geladen. Eventuele gemiste updates voor uw back-ups of synchronisaties zijn niet toegepast. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Synchronisatie of backup is gestopt omdat het lijkt alsof u bent uitgelogd bij de desktop applicatie. Meld u opnieuw aan via de desktop applicatie en ga verder met synchroniseren of backuppen. N/A @@ -105,7 +105,7 @@ Kon de synchronisatieconfiguratie niet lezen. Probeer het later opnieuw of controleer de mapmachtigingen. - Sync folder location is unknown + De lokatie van de synchronisatiemap is onbekend Ongeldig scaninterval. Controleer de instellingen voor het scaninterval en probeer het opnieuw. @@ -125,17 +125,17 @@ Er is iets misgegaan. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + De map kan niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt omdat de MEGA-map zich in de Prullenbak bevindt De map op uw apparaat kan nu niet worden gevonden. Probeer het later opnieuw. De map op uw apparaat kan niet worden gevonden - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + Probleem bij het synchroniseren of maken van een reservekopie van deze map vanwege wijzigingen in de MEGA-map. Stop het synchroniseren of de backup en probeer het opnieuw in te stellen in de desktop applicatie, of neem contact op met de klantenservice. Probleem bij het synchroniseren of back-uppen van deze map. Stop de synchronisatie of back-up en probeer deze opnieuw in te stellen in de Desktop-applicatie, of neem contact op met de ondersteuning. - Folder can’t be synced as it’s already inside a synced folder + De map kan niet worden gesynchroniseerd omdat deze zich al in een gesynchroniseerde map bevindt Camera uploads uitgeschakeld @@ -157,7 +157,7 @@ Geen internet verbinding - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet het synchroniseren of backuppen opnieuw inschakelen via de desktop applicatie. Nog niets ingesteld diff --git a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml index c70c3decdf..46935e6ce0 100644 --- a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA nie może zsynchronizować ani wykonać kopii zapasowej tego katalogu, ponieważ system plików na urządzeniu nie jest obsługiwany Nie można zsynchronizować wybranego katalogu @@ -73,31 +73,31 @@ Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ plan wygasł - Folder can’t be synced as the user who shared this folder has reached their storage quota + Nie można zsynchronizować folderu, ponieważ użytkownik, który udostępnił ten katalog, osiągnął swoją pojemność Katalog w MEGA nie może zostać zlokalizowany, ponieważ został przeniesiony lub usunięty, lub możesz nie mieć do niego dostępu. - Folder can’t be synced as it’s a shared folder without full access + Nie można zsynchronizować katalogu, ponieważ jest to katalog udostępniony bez pełnego dostępu - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacji desktopowej. Nie można zsynchronizować katalogu, ponieważ zawiera już zsynchronizowane katalogi MEGA nie może synchronizować ani tworzyć kopii zapasowych katalogu VirtualBox - Unable to sync or back up this folder as the account has been blocked + Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ konto zostało zablokowane - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu. Spróbuj ponownie później. Jeśli problem będzie się powtarzał, kontakt wsparcie. Konto zostało przeładowane. Wszelkie pominięte aktualizacje kopii zapasowych lub synchronizacji nie zostały zastosowane. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Synchronizacja lub tworzenie kopii zapasowych zostało zatrzymane, ponieważ wydaje się, że wylogowałeś się z aplikacji desktopowej. Zaloguj się ponownie za pomocą aplikacji desktopowerj aby wznowić synchronizację lub tworzenie kopii zapasowych. N/A Nie można zlokalizować katalogu na dysku zewnętrznym. - There’s already a synced folder at the same path + Istnieje już zsynchronizowany katalog na tej samej ścieżce Zmiana nazwy nie powiodła się. @@ -105,7 +105,7 @@ Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. - Sync folder location is unknown + Lokalizacja katalogu synchronizacji jest nieznana Nieprawidłowy interwał skanowania. Sprawdź ustawienia interwału skanowania i spróbuj ponownie. @@ -125,17 +125,17 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Nie można synchronizować ani utworzyć kopii zapasowej katalogu, ponieważ katalog MEGA znajduje się w koszu Nie można teraz zlokalizować katalogu w urządzeniu, spróbuj ponownie później. Nie można zlokalizować katalogu w urządzeniu - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + Problem z synchronizacją lub tworzeniem kopii zapasowej tego katalogu z powodu zmian w katalogu MEGA. Zatrzymaj synchronizację lub kopię zapasową i spróbuj ponownie skonfigurować ją w aplikacji desktopowej lub skontaktuj się z nami. Problem z synchronizacją lub kopią zapasową tego katalogu. Zatrzymaj synchronizację lub tworzenie kopii zapasowej i spróbuj skonfigurować je ponownie w aplikacji Desktop lub skontaktuj się z pomocą techniczną. - Folder can’t be synced as it’s already inside a synced folder + Nie można zsynchronizować katalogu, ponieważ znajduje się on już w zsynchronizowanym katalogu Przesyłanie z kamery wyłączone @@ -157,7 +157,7 @@ Brak połączenia z internetem - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacji desktopowej. Nic nie zostało jeszcze skonfigurowane diff --git a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml index fe50f9c970..f5410fcfbf 100644 --- a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA无法同步或备份此文件夹,因为不支持您设备上的文件系统 您选择的文件夹无法同步 @@ -71,7 +71,7 @@ 已达到存储配额限制。 - Unable to sync or back up this folder as your plan has expired + 由于您的方案已过期,因此无法同步或备份此文件夹 Folder can’t be synced as the user who shared this folder has reached their storage quota diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index 228c862502..bb096c1087 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronisaties [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + We hebben toegang tot de opslag van uw apparaat nodig om uw lokale map te kunnen synchroniseren. Tik hier om toegang toe te staan. - To continuously sync your files and folders, allow MEGA to run in the background + Als u uw bestanden en mappen continu wilt synchroniseren, moet u MEGA op de achtergrond laten draaien %d bestand @@ -107,7 +107,7 @@ Alleen Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + U moet een lokale map op uw apparaat instellen die wordt gesynchroniseerd met een gekozen map op uw Cloud-schijf Synchronisaties toezien @@ -183,7 +183,7 @@ Er zijn meerdere items met dezelfde naam aan één kant van uw synchronisatie die allemaal één dezelfde bestand worden aan de andere kant van uw synchronisatie - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + Er is een actie voor het verplaatsen of hernoemen van de naam gedetecteerd in MEGA, maar deze kon niet lokaal worden gerepliceerd. Verplaatsen of hernoemen werd lokaal gedetecteerd, maar kon niet worden gerepliceerd in MEGA. diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index bbb0ea586b..db772e3c2e 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -9,9 +9,9 @@ Synchronizacja [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + Musimy uzyskać dostęp do pamięci tego urządzenia, aby zsynchronizować katalog lokalny. Kliknij tutaj, aby zezwolić na dostęp. - To continuously sync your files and folders, allow MEGA to run in the background + Aby stale synchronizować pliki i katalogi, pozwól MEGA działać w tle %d plik @@ -115,7 +115,7 @@ Tylko Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + Musisz skonfigurować katalog lokalny na urządzeniu, który będzie synchronizowany z wybranym katalogiem na Dysku w chmurze Monitorowanie synchronizacji @@ -191,7 +191,7 @@ Istnieje wiele elementów o tej samej nazwie po jednej stronie synchronizacji, które stały się tym samym pojedynczym elementem po drugiej stronie synchronizacji - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + Akcja przeniesienia lub zmiany nazwy została wykryta w MEGA, ale nie można jej powielić lokalnie. Przeniesienie lub zmiana nazwy zostały wykryte lokalnie, ale nie mogły zostać odtworzone w MEGA. diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index deac2dc0d9..6533b281ef 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -9,9 +9,9 @@ Đồng bộ [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + Chúng tôi cần truy cập bộ nhớ thiết bị để đồng bộ hóa thư mục cục bộ của bạn. Chạm vào đây để cho phép quyền truy cập. - To continuously sync your files and folders, allow MEGA to run in the background + Để liên tục đồng bộ hóa các tệp tin và thư mục của bạn, cho phép MEGA chạy trong nền %d tệp tin @@ -103,7 +103,7 @@ Chỉ lúc dùng Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + Bạn sẽ cần thiết lập một thư mục cục bộ trên thiết bị của mình sẽ đồng bộ hóa với một thư mục chọn ra trên Ổ Mây của bạn Đang giám sát các đồng bộ @@ -179,7 +179,7 @@ Có nhiều mục có cùng tên tại một bên của quá trình đồng bộ hóa của bạn và tất cả sẽ trở thành cùng một mục duy nhất ở phía bên kia của quá trình đồng bộ hóa của bạn - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + Một việc di chuyển hoặc đổi tên đã được phát hiện trên MEGA, nhưng không thể phỏng y theo trong cục bộ. Một việc di chuyển hoặc đổi tên đã được phát hiện trong cục bộ, nhưng không thể phỏng y theo trên MEGA. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index c0a254fc99..45333ff32e 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -100,4 +100,118 @@ مكالمات واجتماعات غير مقيدة Message, video call, and meet in total privacy with unlimited participants. + + النوع + + صور + + فيديو + + صوتي + + مستندات + + PDFs + + ملف جداول إلكترونية Spreadsheet + + العروض التقديمية + + مجلدات + + Others + + تاريخ الإضافة + + آخر تعديل + + اليوم + + اخر 7 أيام + + أخر 30 أيام + + هذا العام + + السنة الماضية + + أقدم + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index e3a221af49..73fd22d45f 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -100,4 +100,114 @@ Keine Anruf- und Meeting-Beschränkungen Message, video call, and meet in total privacy with unlimited participants. + + Typ + + Bilder + + Video + + Sprache + + Dokumente + + PDFs + + Tabellenkalkulationen + + Präsentationen + + Ordner + + Others + + Hinzugefügt + + Zuletzt bearbeitet am + + Heute + + Letzte 7 Tage + + Letzte 30 Tage + + Dieses Jahr + + Letztes Jahr + + Älter + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 1ccfe85c71..f486d9ba39 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -100,4 +100,115 @@ Llamadas y reuniones sin restricciones Message, video call, and meet in total privacy with unlimited participants. + + Tipo + + Imágenes + + Vídeo + + Audio + + Documentos + + PDF + + Hojas de cálculo + + Presentaciones + + Carpetas + + Others + + Fecha de subida + + Última modificación + + Hoy + + Últimos 7 días + + Últimos 30 días + + Este año + + Último año + + Anterior + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index df12180a89..97c35eee72 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -100,4 +100,115 @@ Appels et réunions sans restrictions Les réunions, les messages et les appels vidéo sont entièrement privés et protégés, avec un nombre illimité de participants. + + Type + + Images + + Vidéos + + Sons + + Documents + + PDF + + Feuilles de calcul + + Présentations + + Dossiers + + Others + + Date d’ajout + + Dernière modification + + Aujourd’hui + + 7 derniers jours + + 30 derniers jours + + Cette année + + L’année dernière + + Plus ancien + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index dae2c40380..bdde4c164e 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -100,4 +100,113 @@ Panggilan dan rapat tanpa batas Message, video call, and meet in total privacy with unlimited participants. + + Tipe + + Gambar-gambar + + Video + + Audio + + Document + + PDF + + Spreadsheet + + Presentasi + + Folder + + Others + + Tanggal ditambahkan + + Terakhir dimodifikasi + + Hari ini + + 7 hari terakhir + + 30 hari terakhir + + Tahun ini + + Tahun lalu + + Lama + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index aceb4f5558..5d9e188482 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -17,31 +17,31 @@ Impossibile sincronizzare o effettuare il backup perché il tuo piano è scaduto - La cartella non può essere sincronizzata poiché l\’utente che ha condiviso questa cartella ha raggiunto il limite del suo spazio di archiviazione + La cartella non può essere sincronizzata poiché l’utente che ha condiviso questa cartella ha raggiunto il limite del suo spazio di archiviazione La cartella in MEGA non può essere trovata perché è stata eliminata o spostata, o potresti non avere accesso ad essa La cartella non può essere sincronizzata perché è una cartella condivisa a cui non hai pieno accesso - I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. + I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall’app per desktop. La cartella non può essere sincronizzata perché già contiene cartelle sincronizzate MEGA non è in grado di sincronizzare o eseguire il backup delle cartelle VirtualBox - Impossibile sincronizzare o effettuare il backup di questa cartella perché l\’account è stato bloccato + Impossibile sincronizzare o effettuare il backup di questa cartella perché l’account è stato bloccato Problema nella sincronizzazione o nel backup di questa cartella. Riprova più tardi. Se il problema persiste, contatta il Supporto. Account ricaricato. Qualsiasi aggiornamento mancato ai tuoi backup o alle tue sincronizzazioni non è stato applicato. - La sincronizzazione o il backup è stato fermato perché sembra che tu abbia effettuato il logout dall\’app per desktop. Effettua nuovamente l\’accesso tramite l\’app per desktop, e riprendi la sincronizzazione o il backup. + La sincronizzazione o il backup è stato fermato perché sembra che tu abbia effettuato il logout dall’app per desktop. Effettua nuovamente l’accesso tramite l’app per desktop, e riprendi la sincronizzazione o il backup. N/A La cartella nel drive esterno non può essere trovata. - C\’è già una cartella sincronizzata nella stessa posizione + C’è già una cartella sincronizzata nella stessa posizione Rinominazione fallita @@ -81,7 +81,7 @@ La cartella non può essere sincronizzata in quanto è già dentro una cartella sincronizzata - I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall\’app per desktop. + I file in questa cartella non possono essere sincronizzati o effettuare il backup. Dovrai riattivare la sincronizzazione o il backup dall’app per desktop. Sincronizzazione interrotta, livello della batteria troppo basso. Carica la batteria per riprendere la sincronizzazione. @@ -100,4 +100,115 @@ Chiamate e meeting senza limiti Message, video call, and meet in total privacy with unlimited participants. + + Tipo + + Immagini + + Video + + Audio + + Documenti + + PDF + + Fogli di calcolo + + Presentazioni + + Cartelle + + Others + + Data aggiunta + + Ultima modifica + + Oggi + + Ultimi 7 giorni + + Ultimi 30 giorni + + Quest’anno + + Ultimo anno + + Vecchio + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 6c681e36b9..d034597035 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -100,4 +100,113 @@ 無制限の通話とミーティング メッセージ、ビデオ通話、完全プライバシーで無制限の参加者とミーティングができます。 + + 種類 + + 画像 + + 動画 + + 音声 + + 文書 + + PDF + + スプレッドシート + + プレゼンテーション + + フォルダ + + その他 + + 追加日 + + 最終更新 + + 今日 + + 過去7日間 + + 過去30日間 + + 今年 + + 去年 + + それ以前 + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 43df97828e..72d8922fd6 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -100,4 +100,113 @@ 제한 없는 통화와 회의 Message, video call, and meet in total privacy with unlimited participants. + + 형식 + + 이미지 + + 동영상 + + 음성 + + 문서 + + PDF + + 스프레드시트 + + 프레젠테이션 + + 폴더 + + Others + + 추가된 날짜 + + 최종 수정일 + + 오늘 + + 최근 7일 + + 최근 30일 + + 올해 + + 지난 해 + + 더 오래됨 + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 64b2476b72..c79c139bc8 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -3,7 +3,7 @@ Geen synchronisatiefout - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA kan deze map niet synchroniseren of backuppen omdat het bestandssysteem op uw apparaat niet wordt ondersteund De map die u heeft gekozen, kan niet worden gesynchroniseerd @@ -13,7 +13,7 @@ De map in MEGA kan niet worden gevonden omdat deze is verplaatst of verwijderd, of u heeft misschien geen toegang - Unable to sync or back up this folder as your storage is full + Kan deze map niet synchroniseren of er een back-up van maken omdat uw opslag vol is U kunt deze map niet synchroniseren of er een back-up van maken omdat uw abonnement is verlopen @@ -23,19 +23,19 @@ De map kan niet worden gesynchroniseerd omdat het een gedeelde map is waar u geen volledige toegang tot heeft - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet het synchroniseren of backuppen opnieuw inschakelen via de desktop applicatie. De map kan niet worden gesynchroniseerd omdat deze al gesynchroniseerde mappen bevat MEGA kan VirtualBox-mappen niet synchroniseren of er een back-up van maken - Unable to sync or back up this folder as the account has been blocked + Kan deze map niet synchroniseren of er een back-up van maken omdat het account is geblokkeerd Probleem bij het synchroniseren of back-uppen van deze map. Probeer het later nog eens. Neem contact op met de ondersteuning als het probleem zich blijft voordoen. Account opnieuw geladen. Eventuele gemiste updates voor uw back-ups of synchronisaties zijn niet toegepast. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Synchronisatie of backup is gestopt omdat het lijkt alsof u bent uitgelogd bij de desktop applicatie. Meld u opnieuw aan via de desktop applicatie en ga verder met synchroniseren of backuppen. N/A @@ -43,13 +43,13 @@ Er is al een gesynchroniseerde map op dezelfde lokatie - Renaming failed + Hernoemen is mislukt Kon geen .megaignore bestand aanmaken voor deze synchronisatie Kon de synchronisatieconfiguratie niet lezen. Probeer het later opnieuw of controleer de mapmachtigingen. - Sync location is unknown + De synchronisatielokatie is onbekend Ongeldig scaninterval. Controleer de instellingen voor het scaninterval en probeer het opnieuw. @@ -69,7 +69,7 @@ Er is iets misgegaan. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + De map kan niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt omdat de MEGA-map zich in de Prullenbak bevindt De map op uw apparaat kan op dit moment niet worden gevonden. Probeer het later nog eens. @@ -79,19 +79,19 @@ Probleem bij het synchroniseren of back-uppen van deze map. Stop de synchronisatie of back-up en probeer deze opnieuw in te stellen in de Desktop-applicatie, of neem contact op met de ondersteuning. - Folder can’t be synced as it’s already inside a synced folder + De map kan niet worden gesynchroniseerd omdat deze zich al in een gesynchroniseerde map bevindt - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Bestanden in deze map kunnen niet worden gesynchroniseerd of er kan geen back-up van worden gemaakt. U moet het synchroniseren of backuppen opnieuw inschakelen via de desktop applicatie. - Syncing paused, battery level too low. Charge battery to resume syncing. + Synchronisatie is gepauzeerd, het batterijniveau is te laag. Laad de batterij op om de synchronisatie te hervatten. - Easy, secure file sharing + Eenvoudig en veilig bestanden delen - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Deel grote bestanden dankzij een royaal overdrachtstegoed en zorg voor beveiliging met links die met een wachtwoord zijn beveiligd. - Never lose data again + Verlies nooit meer gegevens - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Maak een back-up van je gegevens en synchroniseer ze in alle vertrouwen. Bovendien kunt u Terugspoelen gebruiken om mappen te herstellen naar een willekeurige datum tot 180 dagen. MEGA VPN @@ -99,5 +99,115 @@ Onbeperkt bellen en vergaderen - Message, video call, and meet in total privacy with unlimited participants. + Berichten sturen, videogesprekken voeren en vergaderen in volledige privacy met ongelimiteerde deelnemers. + + Type + + Afbeeldingen + + Video + + Audio + + Documenten + + PDFs + + Spreadsheets + + Presentaties + + Mappen + + Andere + + Datum toegevoegd + + Laatst gewijzigd + + Vandaag + + Laatste 7 dagen + + Laatste 30 dagen + + Dit jaar + + Laatste jaar + + Ouder + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index c6f14d58c0..83753defe1 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA nie może zsynchronizować ani wykonać kopii zapasowej tego katalogu, ponieważ system plików na urządzeniu nie jest obsługiwany Nie można zsynchronizować wybranego katalogu @@ -13,7 +13,7 @@ Katalog w MEGA nie może być zlokalizowany, ponieważ został przeniesiony lub usunięty, lub możesz nie mieć dostępu - Unable to sync or back up this folder as your storage is full + Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ pamięć jest pełna Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ plan wygasł @@ -23,19 +23,19 @@ Nie można zsynchronizować katalogu, ponieważ jest to katalog udostępniony, do którego nie masz pełny dostęp - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacja desktopowej. Nie można zsynchronizować katalogu, ponieważ zawiera już zsynchronizowane katalogi MEGA nie może synchronizować ani tworzyć kopii zapasowych katalogu VirtualBox - Unable to sync or back up this folder as the account has been blocked + Nie można zsynchronizować ani utworzyć kopii zapasowej tego katalogu, ponieważ konto zostało zablokowane Problem z synchronizacją lub kopią zapasową tego katalogu. Spróbuj ponownie później. Jeśli problem będzie się powtarzał, skontaktuj się z pomocą techniczną. Konto zostało przeładowane. Wszelkie pominięte aktualizacje kopii zapasowych lub synchronizacji nie zostały zastosowane. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Synchronizacja lub tworzenie kopii zapasowych zostało zatrzymane, ponieważ wydaje się, że wylogowałeś się z aplikacji desktopowej. Zaloguj się ponownie za pomocą aplikacji desktopowerj aby wznowić synchronizację lub tworzenie kopii zapasowych. N/A @@ -43,13 +43,13 @@ W tej samej lokalizacji znajduje się już zsynchronizowany katalog - Renaming failed + Zmiana nazwy nie powiodła się Nie można utworzyć pliku .megaignore dla tej synchronizacji Nie można odczytać konfiguracji synchronizacji. Spróbuj ponownie później lub sprawdź uprawnienia katalogu. - Sync location is unknown + Lokalizacja synchronizacji jest nieznana Nieprawidłowy interwał skanowania. Sprawdź ustawienia interwału skanowania i spróbuj ponownie. @@ -69,7 +69,7 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Nie można synchronizować ani utworzyć kopii zapasowej katalogu, ponieważ katalog MEGA znajduje się w koszu Katalog w urządzeniu nie może być teraz zlokalizowany. Spróbuj ponownie później. @@ -79,19 +79,19 @@ Problem z synchronizacją lub kopią zapasową tego katalogu. Zatrzymaj synchronizację lub tworzenie kopii zapasowej i spróbuj skonfigurować je ponownie w aplikacji Desktop lub skontaktuj się z pomocą techniczną. - Folder can’t be synced as it’s already inside a synced folder + Nie można zsynchronizować katalogu, ponieważ znajduje się on już w zsynchronizowanym katalogu - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Pliki w tym katalogu nie można synchronizować ani tworzyć kopii zapasowych. Będziesz musiał ponownie włączyć synchronizację lub kopię zapasową z aplikacji desktopowej. - Syncing paused, battery level too low. Charge battery to resume syncing. + Synchronizacja wstrzymana, poziom naładowania baterii za niski. Naładuj baterię, aby wznowić synchronizację. - Easy, secure file sharing + Łatwe i bezpieczne udostępnianie plików - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Udostępniaj duże pliki dzięki dużemu limitowi transferu i zapewniaj bezpieczeństwo dzięki linkom chronionym hasłem. - Never lose data again + Nigdy więcej nie utrać danych - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Utwórz kopię zapasową i synchronizuj dane, aby uzyskać pełną pewność. Ponadto użyj Przewiń do tyłu, aby przywróć katalog do dowolnej daty do 180 dni. MEGA VPN @@ -99,5 +99,117 @@ Nieograniczone połączenia i spotkania - Message, video call, and meet in total privacy with unlimited participants. + Wiadomości, połączenie wideo, i spotkania w całkowitej prywatności z nieograniczoną liczbą uczestników. + + Rodzaj + + Obrazy + + Film + + Dzwięk + + Dokumenty + + PDFy + + Arkusze kalkulacyjne + + Prezentacje + + Katalogi + + Pozostałe + + Data dodania + + Ostatnia zmiana + + Dzisiaj + + Ostatnie 7 dni + + Ostatnie 30 dni + + W tym roku + + Ostatni rok + + Starsze + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index fe4379e5f6..3a229a92b4 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -100,4 +100,115 @@ Chamadas e reuniões sem restrições Envie mensagens, faça chamadas de vídeo e reuniões com privacidade total e um número ilimitado de participantes. + + Tipo + + Imagens + + Vídeo + + Áudio + + Documentos + + PDFs + + Planilhas + + Apresentações + + Pastas + + Outros + + Data de inclusão + + Última alteração + + Hoje + + Últimos 7 dias + + Últimos 30 dias + + Este ano + + Último ano + + Mais antigo + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index e6d98a68c4..a1955c0ee1 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -100,4 +100,115 @@ Apeluri și întâlniri nerestricționate Întâlnirile, mesajele și apelurile video sunt complet private și protejate, cu un număr nelimitat de participanți. + + Tip + + Imagini + + Video + + Audio + + Documente + + PDF-uri + + Foi de calcul + + Prezentări + + Foldere + + Alte + + Data adăugării + + Ultima modificare + + Astăzi + + Ultimele 7 zile + + Ultimele 30 zile + + Anul acesta + + Ultimul an + + Mai vechi + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index bbc07183c5..4912206b91 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -100,4 +100,116 @@ Неограниченные звонки и встречи Message, video call, and meet in total privacy with unlimited participants. + + Тип + + Изображения + + Видео + + Аудио + + Документы + + PDF + + Таблицы + + Презентации + + Папки + + Others + + Дата добавления + + Последнее изменение + + Сегодня + + Последние 7 дней + + Последние 30 дней + + Текущий год + + Последний год + + Старше + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index cb4d146be4..be963b4659 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -100,4 +100,113 @@ โทรและประชุมได้ไม่จำกัด Message, video call, and meet in total privacy with unlimited participants. + + ประเภท + + รูปภาพ + + วิดีโอ + + เสียง + + เอกสาร + + ไฟล์ PDF + + สเปรดชีต + + ไฟล์นำเสนอ + + โฟลเดอร์ + + Others + + วันที่เพิ่ม + + วันที่แก้ไข + + วันนี้ + + 7 วันที่ผ่านมา + + 30 วันที่ผ่านมา + + ปีนี้ + + ปีที่แล้ว + + เก่ากว่า + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 13141df7a1..5cc98b4107 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -100,4 +100,113 @@ Cuộc gọi và cuộc họp không hạn chế Message, video call, and meet in total privacy with unlimited participants. + + Dạng + + Hình + + Video + + Thoại + + Tài Liệu + + PDF + + Bảng tính + + Trình chiếu + + Thư mục + + Others + + Ngày đã thêm + + Lần sửa cuối + + Hôm nay + + 7 ngày qua + + 30 ngày qua + + Năm này + + Năm vừa qua + + Cũ hơn + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index f0f96196da..70955d4479 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA无法同步或备份此文件夹,因为不支持您设备上的文件系统 您选择的文件夹无法同步 @@ -11,15 +11,15 @@ 初始扫描失败。您需要从桌面应用程序重新启用同步或备份。 - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + 无法找到MEGA中的文件夹,因为它已被移动或删除,或者您可能没有访问权限 - Unable to sync or back up this folder as your storage is full + 由于您的存储空间已满,无法同步或备份此文件夹 - Unable to sync or back up this folder as your plan has expired + 由于您的方案已过期,因此无法同步或备份此文件夹 Folder can’t be synced as the user who shared this folder has reached their storage limit - Folder in MEGA can’t be located as it’s been moved or deleted, or you might not have access + 无法找到MEGA中的文件夹,因为它已被移动或删除,或者您可能没有访问权限 Folder can’t be synced as it’s a shared folder that you don’t have full access to @@ -31,7 +31,7 @@ Unable to sync or back up this folder as the account has been blocked - 同步或备份此文件夹时出现问题。请稍后再试。如果问题仍然存在,请联系支持部门。 + 同步或备份此文件夹时出现问题。请稍后再试。如果问题仍然存在,请联系客服部门。 帐户已重新加载。对备份或同步的任何更新尚未应用。 @@ -100,4 +100,113 @@ 无限制的通话和会议 Message, video call, and meet in total privacy with unlimited participants. + + 类型 + + 图片 + + 视频 + + 语音 + + 文档 + + PDF + + 电子表格 + + 演示文稿 + + 文件夹 + + Others + + 添加日期 + + 上次修改 + + 今天 + + 最近7天 + + 最近30天 + + 今年 + + 去年 + + 较旧的 + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index d1ffe86296..a7d73bbcb3 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -100,4 +100,113 @@ 無限制的通話和會議 訊息、視訊通話,以及無限制與會人數的完全私密會議。 + + 類型 + + 圖片 + + 影片 + + 音訊 + + 文件 + + PDF + + 試算表 + + 簡報 + + 資料夾 + + 其它 + + 新增日期 + + 上次修改 + + 今天 + + 過去7天 + + 過去30天 + + 今年 + + 去年 + + 較舊的 + + Videos + + Playlists + + Location + + All locations + + Cloud drive + + Camera uploads + + Shared items + + Duration + + All durations + + Less than 10 seconds + + Between 10 and 60 seconds + + Between 1 and 4 minutes + + Between 4 and 20 minutes + + More than 20 minutes + + Enter playlist name + + Rename + + A playlist with this name already exists. Enter a different name. + + Delete playlist\? + + Delete + + No playlists found + + Delete playlist + + Remove from playlist\? + + Remove + + Play all + + No videos + + Choose files + + + + + + + Added %1$d item to “%2$s” + Added %1$d items to “%2$s” + + + + Removed %1$d item from “%2$s” + Removed %1$d items from “%2$s” + + + + %1$d video + %1$d videos + + + You may not have any apps installed which can open this website \ No newline at end of file From 2d0fdbbfce5412300701d98e9517bc57ed09f693 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Wed, 17 Apr 2024 17:10:52 +1200 Subject: [PATCH 094/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index e6d795c0c8..3bf5ace74d 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -71,7 +71,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240415.102740" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From bca79aaeb80838559627fb7dccd2cd5cd718b14c Mon Sep 17 00:00:00 2001 From: rohitsoni Date: Wed, 17 Apr 2024 14:39:33 +0530 Subject: [PATCH 095/261] AND-18561 Org file is not opening from cloud drive --- .../java/mega/privacy/android/data/mapper/FileTypeInfoMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/src/main/java/mega/privacy/android/data/mapper/FileTypeInfoMapper.kt b/data/src/main/java/mega/privacy/android/data/mapper/FileTypeInfoMapper.kt index 90fdab321e..1e1f18effc 100644 --- a/data/src/main/java/mega/privacy/android/data/mapper/FileTypeInfoMapper.kt +++ b/data/src/main/java/mega/privacy/android/data/mapper/FileTypeInfoMapper.kt @@ -164,5 +164,5 @@ private val textExtensions = listOf( "shtml", "inc", "cpp", "dhtml", "asp", "h", "js", "pl", "cs", - "sh", "vb", "swift", + "sh", "vb", "swift", "org" ) From 2026cda9a9878bb1131f318427ef88f76604234a Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Wed, 17 Apr 2024 17:37:09 +1200 Subject: [PATCH 096/261] SAO-933: (R2225) scroll position retained in gridview search screen --- .../android/app/presentation/search/view/SearchComposeView.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index ae054a8951..6ffd08b44f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -94,6 +94,8 @@ fun SearchComposeView( LaunchedEffect(key1 = state.resetScroll) { listState.scrollToItem(0) + } + LaunchedEffect(key1 = state.resetScroll) { gridState.scrollToItem(0) } From ff59c17c66a378a96804bceb18e93607064f1bbe Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Wed, 17 Apr 2024 21:41:58 +1200 Subject: [PATCH 097/261] SAO-877 (t15832897) other option is displayed as others --- .../app/presentation/search/SearchActivityViewModel.kt | 7 ++++++- .../app/presentation/search/view/SearchComposeView.kt | 5 ++--- shared/resources/src/main/res/values/strings_shared.xml | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index 5d28174120..93592c92fe 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -538,7 +538,12 @@ class SearchActivityViewModel @Inject constructor( val list = _state.value.navigationLevel.toMutableList() list.add(Pair(folderHandle, name)) _state.update { state -> - state.copy(navigationLevel = list) + state.copy( + navigationLevel = list, + typeSelectedFilterOption = null, + dateModifiedSelectedFilterOption = null, + dateAddedSelectedFilterOption = null + ) } performSearch() } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index 6ffd08b44f..7eff79efb9 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -109,8 +109,7 @@ fun SearchComposeView( }, ) - topBarPadding = - if (state.navigationLevel.isNotEmpty() && state.nodeSourceType != NodeSourceType.CLOUD_DRIVE && state.nodeSourceType != NodeSourceType.HOME) 8.dp else 0.dp + topBarPadding = if (state.navigationLevel.isNotEmpty()) 8.dp else 0.dp state.errorMessageId?.let { val errorMessage = stringResource(id = it) @@ -150,7 +149,7 @@ fun SearchComposeView( } ) { padding -> Column(modifier = Modifier.padding(top = topBarPadding)) { - if (state.nodeSourceType == NodeSourceType.CLOUD_DRIVE || state.nodeSourceType == NodeSourceType.HOME) { + if ((state.nodeSourceType == NodeSourceType.CLOUD_DRIVE || state.nodeSourceType == NodeSourceType.HOME) && state.navigationLevel.isEmpty()) { FilterChipsView( state = state, onFilterClicked = onFilterClicked, diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index a133314fc4..ee763ec55a 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -119,7 +119,7 @@ Folders - Others + Other Date added From 8aab941431515ce966da6c32f34f7b96873995e5 Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Wed, 17 Apr 2024 21:52:02 +1200 Subject: [PATCH 098/261] CC-6902: Fix image cannot open from share items search issue --- .../node/action/HandleNodeAction.kt | 68 ++++++++++++----- .../app/presentation/search/SearchActivity.kt | 75 ++++++++++++------- 2 files changed, 98 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/node/action/HandleNodeAction.kt b/app/src/main/java/mega/privacy/android/app/presentation/node/action/HandleNodeAction.kt index 16c2768f55..967597c96b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/node/action/HandleNodeAction.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/node/action/HandleNodeAction.kt @@ -14,6 +14,7 @@ import mega.privacy.android.app.mediaplayer.VideoPlayerActivity import mega.privacy.android.app.presentation.imagepreview.ImagePreviewActivity import mega.privacy.android.app.presentation.imagepreview.fetcher.CloudDriveImageNodeFetcher import mega.privacy.android.app.presentation.imagepreview.fetcher.RubbishBinImageNodeFetcher +import mega.privacy.android.app.presentation.imagepreview.fetcher.SharedItemsImageNodeFetcher import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewFetcherSource import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewMenuSource import mega.privacy.android.app.presentation.node.FileNodeContent @@ -176,31 +177,58 @@ private fun openImageViewerActivity( currentFileNode: TypedFileNode, nodeSourceType: Int?, ) { - when (nodeSourceType) { - Constants.FILE_BROWSER_ADAPTER -> { - val intent = ImagePreviewActivity.createIntent( - context = context, - imageSource = ImagePreviewFetcherSource.CLOUD_DRIVE, - menuOptionsSource = ImagePreviewMenuSource.CLOUD_DRIVE, - anchorImageNodeId = currentFileNode.id, - params = mapOf(CloudDriveImageNodeFetcher.PARENT_ID to currentFileNode.parentId.longValue), - showScreenLabel = false, + val currentFileNodeParentId = currentFileNode.parentId.longValue + + val (imageSource, menuOptionsSource, paramKey) = when (nodeSourceType) { + Constants.FILE_BROWSER_ADAPTER -> + Triple( + ImagePreviewFetcherSource.CLOUD_DRIVE, + ImagePreviewMenuSource.CLOUD_DRIVE, + CloudDriveImageNodeFetcher.PARENT_ID + ) + + Constants.RUBBISH_BIN_ADAPTER -> + Triple( + ImagePreviewFetcherSource.RUBBISH_BIN, + ImagePreviewMenuSource.RUBBISH_BIN, + RubbishBinImageNodeFetcher.PARENT_ID + ) + + Constants.INCOMING_SHARES_ADAPTER, Constants.OUTGOING_SHARES_ADAPTER -> + Triple( + ImagePreviewFetcherSource.SHARED_ITEMS, + ImagePreviewMenuSource.SHARED_ITEMS, + SharedItemsImageNodeFetcher.PARENT_ID + ) + + Constants.LINKS_ADAPTER -> + Triple( + ImagePreviewFetcherSource.SHARED_ITEMS, + ImagePreviewMenuSource.LINKS, + SharedItemsImageNodeFetcher.PARENT_ID ) - context.startActivity(intent) - } - Constants.RUBBISH_BIN_ADAPTER -> { - val intent = ImagePreviewActivity.createIntent( - context = context, - imageSource = ImagePreviewFetcherSource.RUBBISH_BIN, - menuOptionsSource = ImagePreviewMenuSource.RUBBISH_BIN, - anchorImageNodeId = currentFileNode.id, - params = mapOf(RubbishBinImageNodeFetcher.PARENT_ID to currentFileNode.parentId.longValue), - showScreenLabel = false, + Constants.BACKUPS_ADAPTER -> + Triple( + ImagePreviewFetcherSource.CLOUD_DRIVE, + ImagePreviewMenuSource.CLOUD_DRIVE, + CloudDriveImageNodeFetcher.PARENT_ID ) - context.startActivity(intent) + + else -> { + Timber.e("Unknown node source type: $nodeSourceType") + return } } + val intent = ImagePreviewActivity.createIntent( + context = context, + imageSource = imageSource, + menuOptionsSource = menuOptionsSource, + anchorImageNodeId = currentFileNode.id, + params = mapOf(paramKey to currentFileNodeParentId), + showScreenLabel = false + ) + context.startActivity(intent) } private suspend fun openVideoOrAudioFile( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt index 6b0c429524..e3dadb3d43 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivity.kt @@ -59,8 +59,10 @@ import mega.privacy.android.app.presentation.extensions.isDarkMode import mega.privacy.android.app.presentation.filelink.view.animationScale import mega.privacy.android.app.presentation.filelink.view.animationSpecs import mega.privacy.android.app.presentation.imagepreview.ImagePreviewActivity +import mega.privacy.android.app.presentation.imagepreview.fetcher.BackupsImageNodeFetcher import mega.privacy.android.app.presentation.imagepreview.fetcher.CloudDriveImageNodeFetcher import mega.privacy.android.app.presentation.imagepreview.fetcher.RubbishBinImageNodeFetcher +import mega.privacy.android.app.presentation.imagepreview.fetcher.SharedItemsImageNodeFetcher import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewFetcherSource import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewMenuSource import mega.privacy.android.app.presentation.manager.model.TransfersTab @@ -85,6 +87,7 @@ import mega.privacy.android.app.textEditor.TextEditorViewModel import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.zippreview.ui.ZipBrowserActivity import mega.privacy.android.core.ui.controls.layouts.MegaScaffold +import mega.privacy.android.core.ui.mapper.FileTypeIconMapper import mega.privacy.android.domain.entity.AudioFileTypeInfo import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.entity.VideoFileTypeInfo @@ -99,7 +102,6 @@ import mega.privacy.android.domain.entity.node.TypedFolderNode import mega.privacy.android.domain.entity.search.SearchCategory import mega.privacy.android.domain.usecase.GetThemeMode import mega.privacy.android.feature.sync.data.mapper.ListToStringWithDelimitersMapper -import mega.privacy.android.core.ui.mapper.FileTypeIconMapper import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.mobile.analytics.event.SearchAudioFilterPressedEvent import mega.privacy.mobile.analytics.event.SearchDocsFilterPressedEvent @@ -537,41 +539,64 @@ class SearchActivity : AppCompatActivity(), MegaSnackbarShower { startActivity(pdfIntent) } - private fun openImageViewerActivity( - currentFileNode: TypedFileNode, - ) { + private fun openImageViewerActivity(currentFileNode: TypedFileNode) { val nodeSourceType = viewModel.state.value.nodeSourceType - when (nodeSourceType) { - NodeSourceType.CLOUD_DRIVE, NodeSourceType.HOME -> { - val intent = ImagePreviewActivity.createIntent( - context = this, - imageSource = ImagePreviewFetcherSource.CLOUD_DRIVE, - menuOptionsSource = ImagePreviewMenuSource.CLOUD_DRIVE, - anchorImageNodeId = currentFileNode.id, - params = mapOf(CloudDriveImageNodeFetcher.PARENT_ID to currentFileNode.parentId.longValue), - showScreenLabel = false, + val currentFileNodeParentId = currentFileNode.parentId.longValue + + val (imageSource, menuOptionsSource, paramKey) = when (nodeSourceType) { + NodeSourceType.CLOUD_DRIVE, NodeSourceType.HOME -> + Triple( + ImagePreviewFetcherSource.CLOUD_DRIVE, + ImagePreviewMenuSource.CLOUD_DRIVE, + CloudDriveImageNodeFetcher.PARENT_ID ) - startActivity(intent) - } - NodeSourceType.RUBBISH_BIN -> { - val intent = ImagePreviewActivity.createIntent( - context = this, - imageSource = ImagePreviewFetcherSource.RUBBISH_BIN, - menuOptionsSource = ImagePreviewMenuSource.RUBBISH_BIN, - anchorImageNodeId = currentFileNode.id, - params = mapOf(RubbishBinImageNodeFetcher.PARENT_ID to currentFileNode.parentId.longValue), - showScreenLabel = false, + NodeSourceType.RUBBISH_BIN -> + Triple( + ImagePreviewFetcherSource.RUBBISH_BIN, + ImagePreviewMenuSource.RUBBISH_BIN, + RubbishBinImageNodeFetcher.PARENT_ID + ) + + NodeSourceType.INCOMING_SHARES, NodeSourceType.OUTGOING_SHARES -> + Triple( + ImagePreviewFetcherSource.SHARED_ITEMS, + ImagePreviewMenuSource.SHARED_ITEMS, + SharedItemsImageNodeFetcher.PARENT_ID + ) + + NodeSourceType.LINKS -> + Triple( + ImagePreviewFetcherSource.SHARED_ITEMS, + ImagePreviewMenuSource.LINKS, + SharedItemsImageNodeFetcher.PARENT_ID + ) + + NodeSourceType.BACKUPS -> + Triple( + ImagePreviewFetcherSource.BACKUPS, + ImagePreviewMenuSource.BACKUPS, + BackupsImageNodeFetcher.PARENT_ID ) - startActivity(intent) - } else -> { Timber.e("Unsupported node source type") + return } } + + val intent = ImagePreviewActivity.createIntent( + context = this, + imageSource = imageSource, + menuOptionsSource = menuOptionsSource, + anchorImageNodeId = currentFileNode.id, + params = mapOf(paramKey to currentFileNodeParentId), + showScreenLabel = false + ) + startActivity(intent) } + private fun openVideoOrAudioFile( fileNode: TypedFileNode, content: NodeContentUri, From 2e04225178017830e35c0c1d9856ba74831a3395 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 18 Apr 2024 13:54:36 +0200 Subject: [PATCH 099/261] MEET-3749: AND - Chat stuck in shimmering loading status. --- .../chat/list/ChatListBottomSheetDialogFragment.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt index 0b706f7fda..af26f03ec1 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/chat/list/ChatListBottomSheetDialogFragment.kt @@ -32,11 +32,11 @@ import mega.privacy.android.app.utils.ChatUtil import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.permission.PermissionUtils.checkMandatoryCallPermissions import mega.privacy.android.app.utils.permission.PermissionUtils.requestCallPermissions -import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.android.domain.entity.ThemeMode import mega.privacy.android.domain.entity.chat.ChatRoomItem import mega.privacy.android.domain.entity.chat.ChatRoomItem.MeetingChatRoomItem import mega.privacy.android.domain.usecase.GetThemeMode +import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.mobile.analytics.event.ScheduledMeetingCancelMenuItemEvent import mega.privacy.mobile.analytics.event.ScheduledMeetingEditMenuItemEvent import javax.inject.Inject @@ -234,4 +234,12 @@ class ChatListBottomSheetDialogFragment : BottomSheetDialogFragment() { fun show(manager: FragmentManager) { if (manager.findFragmentByTag(TAG) == null) super.show(manager, TAG) } + + /** + * On destroy view event + */ + override fun onDestroyView() { + super.onDestroyView() + scheduledMeetingManagementViewModel.stopMonitoringLoadMessages() + } } From 37e2bfeb10e8dd5892314cf0add5b5628874382f Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Fri, 19 Apr 2024 13:21:43 +1200 Subject: [PATCH 100/261] T15864930/AND-17974: Toggle capture mode issue (cherry picked from commit 230fb5c220dcc59050a6fa2a1d414cade9f4048f) --- .../ui/controls/camera/CameraBottomAppBar.kt | 4 +-- .../controls/camera/CameraBottomAppBarTest.kt | 35 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core-ui/src/main/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBar.kt b/core-ui/src/main/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBar.kt index 5cd74324a9..b301dcf237 100644 --- a/core-ui/src/main/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBar.kt +++ b/core-ui/src/main/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBar.kt @@ -114,7 +114,7 @@ fun CameraBottomAppBar( contentDescription = stringResource(id = R.string.video_button), selected = true, shape = CircleShape, - onClick = onToggleCaptureMode + onClick = {} ) { Text( text = stringResource(id = R.string.video_button), @@ -149,7 +149,7 @@ fun CameraBottomAppBar( contentDescription = stringResource(id = R.string.camera_photo_button), selected = true, shape = CircleShape, - onClick = onToggleCaptureMode + onClick = {} ) { Text(text = stringResource(id = R.string.camera_photo_button)) } diff --git a/core-ui/src/test/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBarTest.kt b/core-ui/src/test/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBarTest.kt index 780a9e7e8a..15d627466b 100644 --- a/core-ui/src/test/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBarTest.kt +++ b/core-ui/src/test/java/mega/privacy/android/core/ui/controls/camera/CameraBottomAppBarTest.kt @@ -10,6 +10,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.kotlin.mock import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoInteractions @RunWith(AndroidJUnit4::class) class CameraBottomAppBarTest { @@ -69,7 +70,7 @@ class CameraBottomAppBarTest { val onToggleCaptureMode = mock<() -> Unit>() composeTestRule.setContent { CameraBottomAppBar( - isCaptureVideo = false, + isCaptureVideo = true, isRecording = false, onToggleCaptureMode = onToggleCaptureMode ) @@ -79,12 +80,27 @@ class CameraBottomAppBarTest { verify(onToggleCaptureMode).invoke() } + @Test + fun `test that onToggleCaptureMode doesn't trigger when photo button is clicked and the mode is capturing photo`() { + val onToggleCaptureMode = mock<() -> Unit>() + composeTestRule.setContent { + CameraBottomAppBar( + isCaptureVideo = false, + isRecording = false, + onToggleCaptureMode = onToggleCaptureMode + ) + } + + composeTestRule.onNodeWithTag(TEST_TAG_CAMERA_BOTTOM_APP_BAR_PHOTO).performClick() + verifyNoInteractions(onToggleCaptureMode) + } + @Test fun `test that onToggleCaptureMode triggers when video button is clicked`() { val onToggleCaptureMode = mock<() -> Unit>() composeTestRule.setContent { CameraBottomAppBar( - isCaptureVideo = true, + isCaptureVideo = false, isRecording = false, onToggleCaptureMode = onToggleCaptureMode ) @@ -94,6 +110,21 @@ class CameraBottomAppBarTest { verify(onToggleCaptureMode).invoke() } + @Test + fun `test that onToggleCaptureMode doesn't trigger when video button is clicked and the mode is capturing video`() { + val onToggleCaptureMode = mock<() -> Unit>() + composeTestRule.setContent { + CameraBottomAppBar( + isCaptureVideo = true, + isRecording = false, + onToggleCaptureMode = onToggleCaptureMode + ) + } + + composeTestRule.onNodeWithTag(TEST_TAG_CAMERA_BOTTOM_APP_BAR_VIDEO).performClick() + verifyNoInteractions(onToggleCaptureMode) + } + @Test fun `test that onOpenGallery triggers when gallery button is clicked`() { val onOpenGallery = mock<() -> Unit>() From 373939d05e1678d2230e821f29b9707af6f2d3f8 Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Fri, 19 Apr 2024 09:44:33 +0530 Subject: [PATCH 101/261] SAO-877: (T15832949) fix issue with list not scrollable --- .../search/view/BottomSheetContentLayout.kt | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/BottomSheetContentLayout.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/BottomSheetContentLayout.kt index 7d1e4f752b..5df1c89a6c 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/BottomSheetContentLayout.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/BottomSheetContentLayout.kt @@ -10,6 +10,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.material.Icon import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable @@ -29,10 +31,10 @@ import mega.privacy.android.shared.theme.MegaAppTheme @Composable internal fun BottomSheetContentLayout( - modifier: Modifier = Modifier, title: String, options: List, onItemSelected: (FilterOptionEntity) -> Unit, + modifier: Modifier = Modifier, ) { Column { MegaText( @@ -41,32 +43,32 @@ internal fun BottomSheetContentLayout( textColor = TextColor.Secondary, style = MaterialTheme.typography.subtitle1, ) - - options.map { option -> - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = modifier - .fillMaxWidth() - .height(48.dp) - .clickable( - onClick = { onItemSelected(option) }) - .padding(horizontal = 16.dp), - horizontalArrangement = Arrangement.SpaceBetween - ) { - MegaText( - text = stringResource(id = option.title), - textColor = TextColor.Primary, - style = MaterialTheme.typography.subtitle2, - ) - - if (option.isSelected) { - Icon( - painter = painterResource(id = iconPackR.drawable.ic_check_medium_regular_outline), - tint = colorResource(id = R.color.teal_300), - contentDescription = null, - modifier = Modifier - .size(24.dp) + LazyColumn { + items(options) { option -> + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = modifier + .fillMaxWidth() + .height(48.dp) + .clickable( + onClick = { onItemSelected(option) }) + .padding(horizontal = 16.dp), + horizontalArrangement = Arrangement.SpaceBetween + ) { + MegaText( + text = stringResource(id = option.title), + textColor = TextColor.Primary, + style = MaterialTheme.typography.subtitle2, ) + + if (option.isSelected) { + Icon( + painter = painterResource(id = iconPackR.drawable.ic_check_medium_regular_outline), + tint = colorResource(id = R.color.teal_300), + contentDescription = null, + modifier = Modifier.size(24.dp) + ) + } } } } From 4156635f81c7fbfeb68bab3426e0905a871c6b07 Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Mon, 22 Apr 2024 09:30:37 +1200 Subject: [PATCH 102/261] Pre-release 13.0 --- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-it/strings.xml | 35 +++--- app/src/main/res/values-ko/strings.xml | 45 ++++--- app/src/main/res/values-pt/strings.xml | 4 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 6 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 26 ++-- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 30 ++--- .../strings_device_center_feature.xml | 12 +- .../res/values-ar/strings_sync_feature.xml | 6 +- .../res/values-de/strings_sync_feature.xml | 6 +- .../res/values-es/strings_sync_feature.xml | 114 ++++++++--------- .../res/values-fr/strings_sync_feature.xml | 4 +- .../res/values-in/strings_sync_feature.xml | 6 +- .../res/values-it/strings_sync_feature.xml | 6 +- .../res/values-ja/strings_sync_feature.xml | 6 +- .../res/values-ko/strings_sync_feature.xml | 10 +- .../res/values-nl/strings_sync_feature.xml | 6 +- .../res/values-pl/strings_sync_feature.xml | 6 +- .../res/values-pt/strings_sync_feature.xml | 6 +- .../res/values-ro/strings_sync_feature.xml | 6 +- .../res/values-ru/strings_sync_feature.xml | 6 +- .../res/values-th/strings_sync_feature.xml | 6 +- .../res/values-vi/strings_sync_feature.xml | 6 +- .../values-zh-rCN/strings_sync_feature.xml | 6 +- .../values-zh-rTW/strings_sync_feature.xml | 12 +- .../main/res/values/strings_sync_feature.xml | 6 +- .../src/main/res/values-ar/strings_shared.xml | 82 ++++++------ .../src/main/res/values-de/strings_shared.xml | 34 ++--- .../src/main/res/values-es/strings_shared.xml | 50 ++++---- .../src/main/res/values-fr/strings_shared.xml | 81 ++++++------ .../src/main/res/values-in/strings_shared.xml | 34 ++--- .../src/main/res/values-it/strings_shared.xml | 91 +++++++------- .../src/main/res/values-ja/strings_shared.xml | 73 +++++------ .../src/main/res/values-ko/strings_shared.xml | 105 ++++++++-------- .../src/main/res/values-nl/strings_shared.xml | 72 ++++++----- .../src/main/res/values-pl/strings_shared.xml | 38 +++--- .../src/main/res/values-pt/strings_shared.xml | 79 ++++++------ .../src/main/res/values-ro/strings_shared.xml | 81 ++++++------ .../src/main/res/values-ru/strings_shared.xml | 52 ++++---- .../src/main/res/values-th/strings_shared.xml | 36 +++--- .../src/main/res/values-vi/strings_shared.xml | 36 +++--- .../main/res/values-zh-rCN/strings_shared.xml | 119 +++++++++--------- .../main/res/values-zh-rTW/strings_shared.xml | 77 ++++++------ .../src/main/res/values/strings_shared.xml | 4 + 48 files changed, 806 insertions(+), 732 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index deb8188d39..eb701ecf74 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -305,7 +305,7 @@ Aucune appli n’est proposée sur votre appareil pour ouvrir cette position - Il semble qu’aucune appli n’est installée qui prenne ce type de fichier en charge + Il semble qu’aucune appli installée ne prend ce type de fichier en charge Partager le lien @@ -2582,7 +2582,7 @@ Pour vous joindre à cet appel, vous devez mettre fin à l’appel en cours ou le mettre en attente. - D’autres peuvent se joindre à votre groupe en utilisant ce lien. + D’autres peuvent se joindre à votre groupe grâce à ce lien. Saisissez le nom du groupe diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index aaff2b829e..a8ad69aeef 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -824,7 +824,7 @@ Acquisizione delle informazioni in corso… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + Il tuo nuovo indirizzo email deve essere verificato. Controlla la casella di posta elettronica del nuovo indirizzo email per procedere. Cancellare l’immagine del profilo? @@ -2101,8 +2101,9 @@ Altro - Choose file - Choose files + Scegli il file + Scegli i file + Scegli i file Scegli cartella @@ -2365,7 +2366,7 @@ Imposta MEGA - MEGA needs your permission to access your media and files for sharing. Other access permissions may be needed to use features and services that this app provides. + MEGA ha bisogno del tuo permesso per accedere ai tuoi contenuti multimediali e ai tuoi file per la condivisione. Potrebbero essere necessarie altre autorizzazioni di accesso per utilizzare le funzionalità e i servizi forniti da questa app. Permetti l’accesso a foto, media e file @@ -3983,7 +3984,7 @@ Per attivare i Caricamenti da fotocamera, permetti a MEGA l\’accesso alle tue foto e agli altri media sul tuo dispositivo. - Permetti accesso + Permetti l\’accesso Non permettere @@ -4583,9 +4584,9 @@ Inizia - Questo file è stato rimosso seguendo la nostra [A]Politica sulla chiusura[/A]. + Questo file è stato rimosso seguendo la nostra [A]Politica sulla rimozione[/A]. - Questa cartella è stata rimossa seguendo la nostra [A]Politica sulla chiusura[/A]. + Questa cartella è stata rimossa seguendo la nostra [A]Politica sulla rimozione[/A]. Unisciti @@ -4869,9 +4870,9 @@ Impossibile aprire il file - This folder has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Questa cartella è stata rimossa in conformità con la nostra [A]Politica sulla rimozione[/A]. Puoi contestare questa rimozione se ritieni che abbiamo commesso un errore. - This file has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Questo file è stato rimosso in conformità con la nostra [A]Politica sulla rimozione[/A]. Puoi contestare questa rimozione se ritieni che abbiamo commesso un errore. Solo Pro @@ -5337,15 +5338,15 @@ Ottieni di più con un piano Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. + Effettua l\’upgrade ad un piano Pro ed ottieni più spazio di archiviazione e accesso alle funzionalità Pro. I piani partono da un minimo di %1$s al mese. - MEGA Pro plans include: + I piani MEGA Pro includono: - Ultimate storage flexibility + Massima flessibilità di archiviazione - Starting from %1$s, find the perfect fit for your storage needs. + A partire da %1$s, trova la soluzione perfetta per le tue esigenze di archiviazione. - Upgrade to Pro today + Effettua oggi l\’upgrade a Pro %1$s sta presentando @@ -5449,7 +5450,7 @@ Permetti l\’accesso alla tua Galleria - Permetti accesso + Permetti l\’accesso Aggiornamento necessario @@ -5629,9 +5630,9 @@ Flash attivo - Flash mode off + Flash non attivo - Flash mode auto + Flash automatico Invia a %1$s \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index e9cea52b40..f906237c00 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -746,7 +746,7 @@ 이메일 주소 인증 - Check your email inbox to proceed. + 진행하려면 이메일 수신함을 확인하세요 오류가 발생했습니다, 다시 시도하세요. @@ -790,7 +790,7 @@ 이것은 현재 당신의 이메일 주소입니다. - This is the last step to change your email address. Enter your password below. + 이메일 주소를 변경하는 마지막 단계입니다. 아래에 암호를 입력하세요. 이메일 변경 @@ -806,7 +806,7 @@ 정보 받는 중… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + 새 이메일 주소를 확인해야 합니다. 진행하려면 새 이메일 주소의 수신함을 확인하세요. 프로필 사진을 삭제할까요? @@ -834,7 +834,7 @@ 로그인 시도 실패가 너무 많습니다, 1시간 동안 기다려주세요. - This account has not been validated yet. Check your email inbox. + 이 계정은 아직 확인되지 않았습니다. 이메일 수신함을 확인하세요. 폴더 링크가 사용불가입니다 @@ -848,7 +848,7 @@ 이메일 인증 대기중 - Check your email inbox and follow the link to confirm your account. + 계정을 확인하려면 이메일 수신함을 확인하고 링크를 따라가세요. %1$d개의 항목 @@ -2011,8 +2011,7 @@ 더 보기 - Choose file - Choose files + 파일 선택 폴더 선택 @@ -2271,7 +2270,7 @@ 통화 활성화 - Allow access to your address book + 주소록에 대한 접근 허용 MEGA에서 당신의 주소록에 있는 지인들을 쉽게 찾으세요. @@ -3299,7 +3298,7 @@ 당신에게 이미 구독이 있습니다. 만약 다른 것을 구매하면 두번 결제됩니다. 이것을 피하려면, MEGA를 데스크톱 또는 모바일 웹 브라우저에서 접속하여 현재 구독을 취소하세요. 자세한 정보는 우리의 도움 센터를 방문하세요. - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + 설정에 가서 MEGA가 Bluetooth를 이용하여 주변 기기에 접근할 수 있도록 허용해주세요. 결제를 처리할 수 없습니다. 만약 이중 앱을 사용하고 있다면, 사용하지 않은 상태에서 MEGA에 로그인 하세요. 만약 아니라면 웹 브라우저를 통해 업그레이드 하세요. @@ -3651,7 +3650,7 @@ 이곳은 백업된 파일과 폴더가 보관되는 곳입니다. 백업된 항목은 실수로 클라우드 드라이브에서 수정되는 것을 방지하지 위해 “읽기 전용”이 됩니다.\n데스크톱 앱을 이용하여 컴퓨터에서 MEGA로 항목들을 백업할 수 있습니다. - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + 당신의 MEGA 계정이 반복된 저작권 침해 혐의로 인해 정지 되었습니다. 이것은 당신의 계정이나 그 안의 데이터에 접근할 수 없다는 뜻입니다.\n이의 제기를 제출하는 방법에 대한 자세한 정보는 이메일 수신함을 확인하세요. 당신의 계정이 MEGA의 이용 약관 위반으로 삭제되었습니다.\n저장된 데이터에 대한 접근 또는 새 MEGA 계정을 등록하는 것이 금지됩니다. @@ -3777,7 +3776,7 @@ 사진첩에서 제거할까요? - To enable camera uploads, allow MEGA access to your photos and other media on your device. + 카메라 업로드를 활성화 하려면, MEGA가 당신의 장치의 사진과 다른 미디어에 접근할 수 있도록 허용해주세요. 접근 허용 @@ -4761,7 +4760,7 @@ 앱이 업데이트 되었습니다 - Relaunch the app + 앱 재실행 오디오 파일에 접근 허용 @@ -4877,15 +4876,15 @@ Pro 요금제로 더 받기 - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. + 더 많은 저장소와 Pro 기능에 접근하기 위해 Pro 요금제로 업그레이드 하세요. 요금제는 월 %1$s의 저렴한 가격으로 시작합니다. - MEGA Pro plans include: + MEGA Pro 요금제는 다음이 포함됩니다: - Ultimate storage flexibility + 엄청난 저장소 유연성 - Starting from %1$s, find the perfect fit for your storage needs. + %1$s부터 시작하여, 당신의 저장소 수요에 완벽하게 맞는 크기를 찾으세요. - Upgrade to Pro today + 오늘 Pro로 업그레이드 %1$s 님이 발표 중입니다 @@ -4981,7 +4980,7 @@ 구독은 처음 선택한 기간과 같은 기간 그리고 같은 가격으로 연속적으로 자동 갱신 됩니다. MEGA Pro 구독 자동 갱신을 [A]Google Play[/A]의 구독을 통해 다음 구독의 결제 24시간 전에 취소할 수 있습니다. - Allow access to your Gallery + 갤러리에 접근 허용 접근 허용 @@ -5149,15 +5148,15 @@ 숨겨진 항목 보기 - All hidden items will be visible, but blurred to indicate their “hidden” status + 모든 숨겨진 항목이 보여지게 되지만, “숨김” 상태를 나타내기 위해 흐리게 나타납니다 사진 - Flash mode on + 플래시 모드 켜짐 - Flash mode off + 플래시 모드 꺼짐 - Flash mode auto + 플래시 모드 자동 - Send to %1$s + %1$s에 보내기 \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c91b0499a3..7c06e88f4a 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -868,7 +868,7 @@ Esperando confirmação por e-mail - Acesse o seu email e clique no link para confirmar a sua conta. + Acesse o seu email e use o link para confirmar a sua conta. %1$d item @@ -5344,7 +5344,7 @@ Flexibilidade de armazenamento máxima - Encontre o melhor opção para as suas necessidades de armazenamento a partir de %1$s. + Encontre a melhor opção para as suas necessidades de armazenamento a partir de %1$s. Fazer o upgrade a um plano Pro diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index a650016cd3..4df08ee410 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -2582,7 +2582,7 @@ Pentru a te alătura acestui apel, trebuie să închei sau să pui în așteptare apelul actual. - Oamenii se pot alătura grupului folosind acest link. + Oamenii se pot alătura grupului dvs. folosind acest link. Introduceți numele grupului diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5d4687ff8e..1381a81799 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -878,7 +878,7 @@ Ожидание подтверждения по электронной почте - Check your email inbox and follow the link to confirm your account. + Подтвердите регистрацию, перейдя по ссылке в письме, которое вам придёт. %1$d элемент @@ -5571,11 +5571,11 @@ MEGA Pro plans include: - Ultimate storage flexibility + Максимально гибкое хранилище Starting from %1$s, find the perfect fit for your storage needs. - Upgrade to Pro today + Перейти на Pro %1$s выступает diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1792b13e04..6e0586f7c7 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -5112,7 +5112,7 @@ 升級到Pro方案可獲得無限的通話 - 您的通話時間已達60分鐘的限制並已結束。Pro使用者的通話時間不受限制,最多可邀請1000位與會者。 + 您的通話時間已達60分鐘的限制並已結束。Pro使用者的通話時間不受限制,而且最多可邀請1000位與會者。 立即升級 diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index d7c793a0e5..5a3f9cd1d7 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -169,7 +169,7 @@ Contiene - Dimensione Totale + Dimensione totale %1$d file diff --git a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml index 2e108755d3..c4214c3332 100644 --- a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + 이 폴더는 당신의 기기의 파일 시스템이 지원하지 않기 때문에 MEGA에서 동기화 하거나 백업할 수 없습니다 선택한 폴더는 동기화할 수 없습니다 @@ -73,31 +73,31 @@ 요금제가 만료되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 - Folder can’t be synced as the user who shared this folder has reached their storage quota + 이 폴더를 공유한 사람의 저장소 할당량에 도달하여 폴더를 동기화할 수 없습니다 MEGA의 폴더가 이동 되었거나, 삭제 되었거나, 접근 권한이 없어서 찾을 수 없습니다. - Folder can’t be synced as it’s a shared folder without full access + 전체 권한 없이 공유된 폴더이기 때문에 폴더를 동기화할 수 없습니다 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. 동기화된 폴더가 포함되어 있는 폴더이기 때문에 동기화할 수 없습니다 MEGA는 VirtualBox 폴더를 동기화 또는 백업할 수 없습니다 - Unable to sync or back up this folder as the account has been blocked + 계정이 차단되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 나중에 다시 시도하세요. 만약 문제가 계속되면, 지원에 연락주세요. 계정을 다시 불러왔습니다. 백업 또는 동기화에 누락된 변경사항이 적용되지 않습니다. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + 데스크톱 앱에서 로그아웃한 것으로 나타나서 동기화 또는 백업이 멈추었습니다. 데스크톱 앱에서 다시 로그인하고, 동기화 또는 백업을 재개하세요. N/A 외부 드라이브에 있는 폴더를 찾을 수 없습니다. - There’s already a synced folder at the same path + 같은 경로에 이미 동기화된 폴더가 있습니다 이름 변경 실패. @@ -105,7 +105,7 @@ 동기화 설정을 읽을 수 없습니다. 나중에 다시 시도하거나 폴더 권한을 확인하세요. - Sync folder location is unknown + 동기화 폴더 위치를 알 수 없습니다 잘못된 탐색 간격. 탐색 간격 설정을 확인하고 다시 시도하세요. @@ -125,17 +125,17 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + MEGA 폴더가 휴지통에 있어서 폴더를 동기화 또는 백업할 수 없습니다 장치의 폴더를 찾을 수 없습니다, 나중에 다시 시도하세요. 장치의 폴더를 찾을 수 없습니다 - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + 이 폴더를 동기화 또는 백업하던 중 MEGA 폴더의 변경으로 인해 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. - Folder can’t be synced as it’s already inside a synced folder + 동기화된 폴더 안에 위치한 폴더이기 때문에 동기화할 수 없습니다 카메라 업로드 비활성화됨 @@ -157,7 +157,7 @@ 인터넷 연결이 없습니다 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. 아직 아무 것도 설정되지 않았습니다 diff --git a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml index bfbda1d8f4..c6299331db 100644 --- a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml @@ -135,7 +135,7 @@ Não foi possível sincronizar ou fazer o backup desta pasta. Cancele a sincronização ou o backup e tente configurá-lo novamente no aplicativo para desktop, ou entre em contato com a nossa equipe de Suporte. - Não é possível sincronizar esta pasta porque está dentro de uma pasta sincronizada + Não é possível sincronizar esta pasta porque ela está dentro de uma pasta sincronizada Uploads da câmera desativados diff --git a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml index f5410fcfbf..ca4958238d 100644 --- a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml @@ -73,39 +73,39 @@ 由于您的方案已过期,因此无法同步或备份此文件夹 - Folder can’t be synced as the user who shared this folder has reached their storage quota + 无法同步文件夹,因为共享此文件夹的用户已达到其存储容量上限 MEGA中的文件夹已被移动或删除,因此无法定位,或者您可能没有访问权限。 - Folder can’t be synced as it’s a shared folder without full access + 无法同步文件夹,因为它是没有完全访问权限的共享文件夹 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 此文件夹中的文件无法同步或备份。您需要从桌面应用程序重新启用同步或备份。 - Folder can’t be synced as it already contains synced folders + 文件夹无法同步,因为它已经包含在已经同步的文件夹中 - MEGA can’t sync or back up VirtualBox folders + MEGA无法同步或备份VirtualBox文件夹 - Unable to sync or back up this folder as the account has been blocked + 由于该帐户已被封锁,无法同步或备份此文件夹 - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + 同步或备份此文件夹时出现问题。请稍后再试。如果问题仍然存在,请联系客服。 帐户已重新加载。对备份或同步的任何更新尚未应用。 - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + 由于您似乎已登出桌面应用程序,因此同步或备份已停止。通过桌面应用程序重新登录,然后恢复同步或备份。 N/A 无法定位外部驱动器中的文件夹。 - There’s already a synced folder at the same path + 同一路径下已经有一个同步文件夹 重命名失败。 - Couldn’t create a .megaignore file for this sync + 无法为此同步创建.megaignore文件 无法读取同步配置。稍后重试或检查文件夹权限。 - Sync folder location is unknown + 同步文件夹位置未知 扫描间隔无效。请检查扫描间隔设置,然后重试。 @@ -125,17 +125,17 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + 由于MEGA文件夹位于回收站中,文件夹无法同步或备份 现在无法定位您设备中的文件夹,请稍后重试。 无法找到您设备中的文件夹 - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + 由于MEGA文件夹发生变动,同步或备份此文件夹时出现问题。请停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 同步或备份此文件夹时出现问题。停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 - Folder can’t be synced as it’s already inside a synced folder + 文件夹无法同步,因为它已经在同步的文件夹中 相机上传已禁用 @@ -157,7 +157,7 @@ 无网络连接 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 此文件夹中的文件无法同步或备份。您需要从桌面应用程序重新启用同步或备份。 尚未设置任何内容 diff --git a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml index a45869960f..5900dfb6af 100644 --- a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml @@ -73,11 +73,11 @@ 由於您的方案已過期,因此無法同步或備份此資料夾。 - Folder can’t be synced as the user who shared this folder has reached their storage quota + 無法同步資料夾,因為共享此資料夾的使用者已達到其儲存配額上限 無法找到MEGA中的資料夾,因為它已被移動或刪除,或者您可能無權權存取。 - Folder can’t be synced as it’s a shared folder without full access + 資料夾無法同步,因為它是沒有完全存取權限的共享資料夾 此資料夾中的檔案無法同步或備份。您需要從桌面應用程式重新啟用同步或備份。 @@ -87,7 +87,7 @@ 由於帳戶已被封鎖,因此無法同步或備份此資料夾 - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + 同步或備份此資料夾時出現問題。稍後再試。如果問題仍然存在,請聯繫客服。 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 @@ -97,7 +97,7 @@ 無法找到外部磁碟的資料夾。 - There’s already a synced folder at the same path + 同一路徑下已有一個同步資料夾 重新命名失敗。 @@ -105,7 +105,7 @@ 無法讀取同步設定。稍後再試或檢查資料夾權限。 - Sync folder location is unknown + 同步資料夾位置未知 掃描間隔無效。檢查掃描間隔設定並且重試。 @@ -131,7 +131,7 @@ 無法找到您裝置中的資料夾 - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + 由於MEGA資料夾發生變動,因此同步或備份此資料夾時出現問題。請停止同步或備份,然後嘗試在桌面應用程式中再次設定,或者聯繫客服。 同步或備份此資料夾時出現問題。停止同步或備份,然後嘗試在桌面應用程式中重新設定,或聯繫客服。 diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 74e4154930..16f79f3aa7 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -9,7 +9,7 @@ مزامنة [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -177,7 +177,7 @@ تحديد - يحتوي الملف أو المجلد على مشكلة تحتاج إلى قرارك لحلها + An item has an issue that needs your decision to resolve it في انتظار اكتمال العمليات الأخرى @@ -201,7 +201,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - تم اكتشاف نقل أو إعادة تسمية حيث يحدث محليًا ولكن تعذر إجراؤها في ميغا MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. في انتظار انتهاء الفحص لتحديد ما إذا كان الملف قد تم نقله أو حذفه. diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index 2bd7dcd43e..df85314757 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisierungen [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -161,7 +161,7 @@ Auswählen - Ein Problem mit einer Datei oder einem Ordner erfordert Ihren Eingriff + An item has an issue that needs your decision to resolve it Es wird auf den Abschluss anderer Prozesse gewartet @@ -185,7 +185,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - Ein lokal erkannter Verschiebe- oder Umbenennungsvorgang konnte auf MEGA nicht repliziert werden. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Abschluss des Scanvorgangs wird abgewartet, um zu bestimmen, ob die Datei verschoben oder gelöscht wurde. diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index 333e3c713b..a78f76d70f 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -7,11 +7,11 @@ Sincronizar - Syncs [A](%1$d)[/A] + Sincronizaciones [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA necesita acceder al almacenamiento de tu dispositivo para poder sincronizar tu carpeta local. Pulsa aquí para permitir el acceso. - To continuously sync your files and folders, allow MEGA to run in the background + Para una sincronización continua de tus archivos y carpetas, deja que MEGA se ejecute en segundo plano %d archivo @@ -37,11 +37,11 @@ %1$d archivos - Sync options + Opciones de sincronización - Clear resolved issues + Limpiar los problemas resueltos - Two-way sync + Sincronización bidireccional Conflict A @@ -51,23 +51,23 @@ Combinar carpetas - Choose the local file + Elegir el archivo local - Choose the file stored in MEGA + Elegir el archivo almacenado en MEGA - Choose the last modified file + Elegir el último archivo modificado - Conflict resolved + Conflicto resuelto - To back up your files, MEGA needs access to the files and folders in this device. Your data is always safe with us. + Para hacer el backup de tus archivos, MEGA necesita acceder a los archivos y carpetas de este dispositivo. Tus datos siempre están seguros con nosotros. Continuar Ahora no - Access to all files + Acceso a todos los archivos - Battery optimisation + Optimización de la batería Denegar @@ -75,31 +75,31 @@ Allow MEGA to read, modify or delete all files on this device. - No resolved issues + No hay problemas resueltos - No issues + No hay problemas - Name the sync + Asignar nombre a la sincronización - Device folder + Carpeta del dispositivo Carpeta en MEGA - Sync type + Tipo de sincronización En pausa - Syncing… + Sincronizando… - Stopped + Detenido - Synced + Sincronizado - Device folder + Carpeta del dispositivo Carpeta en MEGA - Issues info + Más info Pausa @@ -111,53 +111,53 @@ Solo Wi-Fi - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + Necesitarás configurar una carpeta en tu dispositivo que se sincronizará con la carpeta elegida en tu Nube - Monitoring syncs + Monitorización de sincronizaciones - Sync options changed to: Wi-Fi only + Las opciones de sincronización han cambiado a: solo Wi-Fi - Sync options changed to: Wi-Fi or mobile data + Las opciones de sincronización han cambiado a: Wi-Fi o datos móviles No reason - File or folder issue + Problema con un archivo o una carpeta - Can’t move or rename + No se puede mover ni renombrar - Deletion or move waiting on scanning + Operación de mover o eliminar en espera - Can’t delete yet + No se puede eliminar todavía - Upload problem + Problema al subir - Download problem + Problema al descargar - Can’t create folder + No se puede crear la carpeta - Can’t delete item + No se puede eliminar el elemento - Sync item exceeds maximum folder depth + El elemento sincronizado supera la profundidad máxima de la carpeta - The file you’re attempting to sync has no extension and has the same name as an existing folder + El archivo que estás intentando sincronizar no tiene extensión y tiene el mismo nombre que una carpeta existente - Item changed since last sync + El elemento ha cambiado desde la última sincronización - File or folder conflict + Conflicto de archivo o carpeta - File or folder name conflict + Conflicto de nombre de archivo o carpeta Last plus one Carpetas - Issues (%d) + Problemas (%d) - Issues + Problemas - Resolved issues + Problemas resueltos - Set up a sync + Configurar sincronización Carpeta vacía @@ -165,33 +165,33 @@ Seleccionar - A file or folder has an issue that needs your decision to resolve it + Un elemento tiene un problema que requiere tu decisión para resolverlo - Waiting for other processes to complete + Esperando a que se completen otros procesos - Can’t reach the destination folder + No se puede acceder a la carpeta de destino - An error occurred either downloading the file, or moving the downloaded temporary file to its final location. + Se ha producido un error al descargar el archivo o al mover el archivo temporal descargado a su ubicación final. Un error local impide el acceso a la carpeta Filesystem error preventing folder access. - Target is too deep on your folder structure.\nMove it to a location that is less than 64 folders deep. + El destino está demasiado profundo en la estructura de carpetas.\nMuévelo a una ubicación que tenga menos de 64 carpetas. - The file you’re attempting to sync has no extension and has the same name as an existing folder + El archivo que estás intentando sincronizar no tiene extensión y tiene el mismo nombre que una carpeta existente - This file has been changed both in MEGA and locally since it was last synced. + Este archivo se ha modificado tanto en MEGA como en tu dispositivo desde la última vez que se ha sincronizado. - This file has conflicting copies + Este archivo tiene copias con conflictos - There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync + Hay varios elementos con el mismo nombre en un lado de la sincronización y todos se convertirían en el mismo elemento en el otro lado de la sincronización - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + Se ha detectado un movimiento o cambio de nombre en MEGA, pero no se ha podido replicar en tu dispositivo. - Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. + Se ha detectado un movimiento o cambio de nombre en tu dispositivo, pero no se ha podido replicar en MEGA. - Waiting for scan to finish to determine if the file was moved or deleted. + Esperando a que finalice el análisis para determinar si el archivo se ha movido o eliminado. - Choose folders + Elegir carpetas \ No newline at end of file diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index 20d29bdf4c..efbfe2335e 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisations [A](%1$d)[/A] - Nous devons accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour autoriser l’accès. + MEGA a besoin d’accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour autoriser l’accès. Afin de synchroniser en permanence vos fichiers et dossiers, autorisez MEGA à fonctionner en arrière-plan @@ -165,7 +165,7 @@ Choisir - Un fichier ou un dossier présente un problème qui nécessite une décision de votre part pour le résoudre + Un élément présente un problème qui nécessite une décision de votre part pour le résoudre Attente de la fin d’autres processus diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index 541818a375..566fbfe2fc 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -157,7 +157,7 @@ Pilih - A file or folder has an issue that needs your decision to resolve it + An item has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -181,7 +181,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Waiting for scan to finish to determine if the file was moved or deleted. diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index ab70fe4547..bf7c1b15a1 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -9,7 +9,7 @@ Sincronizzazioni [A](%1$d)[/A] - Abbiamo bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per dare l\’accesso. + MEGA ha bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per garantire l\’accesso. Per sincronizzare in modo continuo i tuoi file e le tue cartelle, permetti a MEGA di operare in background @@ -165,7 +165,7 @@ Seleziona - Un file o una cartella ha un problema che richiede la tua decisione per la risoluzione + Un oggetto ha un problema che richiede la tua decisione per essere risolto In attesa del completamento di altri processi @@ -189,7 +189,7 @@ MEGA ha riscontrato un\’azione di spostamento o di rinominazione, ma non riesce a ripeterla localmente. - Localmente è stato riscontrato uno spostamento o una rinominazione, ma è impossibile da replicare su MEGA. + È stata riscontrata un\’azione locale di spostamento o di rinominazione, ma non riesce a ripeterla su MEGA. In attesa del completamento della scansione per determinare se il file è stato spostato o eliminato. diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index 84eef5d252..8105c7f27d 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -9,7 +9,7 @@ 同期 [A](%1$d)[/A] - ローカルフォルダを同期するには、お使いのデバイスのストレージにアクセスする必要があります。こちらをタップしてアクセスを許可してください。 + ローカルフォルダを同期するには、MEGAはお使いのデバイスのストレージにアクセスする必要があります。こちらをタップしてアクセスを許可してください。 ファイルとフォルダを継続的に同期するには、MEGAをバックグラウンドで実行できるようにします @@ -157,7 +157,7 @@ 選ぶ - あるファイルやフォルダに問題があり、それを解決するにはあなたの決定が必要です。 + ある項目に問題があり、それを解決するにはあなたの決定が必要です 他のプロセスが完了するのを待っています @@ -181,7 +181,7 @@ MEGAで移動または名前変更アクションが検出されましたが、ローカルで複製できませんでした。 - 移動または名前変更がローカルで行われたものとして検出されましたが、MEGAでは複製できませんでした。 + 移動または名前変更アクションがローカルで検出されましたが、MEGAで複製できませんでした。 ファイルが移動または削除されたかどうかを判断するために、スキャンが完了するのを待っています。 diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 859a3eabe9..6dc0918f9a 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -9,9 +9,9 @@ 동기화 [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + 당신의 로컬 폴더를 동기화하기 위해 MEGA가 장치 저장소에 접근이 필요합니다. 접근을 승인하려면 여기를 탭하세요 - To continuously sync your files and folders, allow MEGA to run in the background + 파일과 폴더를 계속 동기화하려면, MEGA가 백그라운드에서 작동하도록 허용하세요 %d개의 파일 @@ -103,7 +103,7 @@ 와이파이 전용 - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + 당신의 클라우드 드라이브에서 선택한 폴더와 동기화할 장치의 로컬 폴더를 설정해야 합니다 동기화 감시 중 @@ -157,7 +157,7 @@ 선택 - 한 개의 파일 또는 폴더에 해결하기 위해 당신의 결정이 필요한 문제가 있습니다 + 한 개의 항목에 문제를 해결하기 위해 당신의 결정이 필요합니다 다른 프로세스가 완료되기를 기다리는 중입니다. @@ -179,7 +179,7 @@ 동기화의 한쪽에서 같은 이름을 다신 여러 항목이 있지만 동기화의 다른 쪽에서 같은 하나의 항목이 될 것입니다 - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + MEGA에서 이동 또는 이름 변경을 감지하였지만, 로컬에 반영할 수 없었습니다 로컬에서 이동 또는 이름 변경을 감지하였지만, MEGA에 반영할 수 없었습니다. diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index bb096c1087..bd8256ccef 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisaties [A](%1$d)[/A] - We hebben toegang tot de opslag van uw apparaat nodig om uw lokale map te kunnen synchroniseren. Tik hier om toegang toe te staan. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. Als u uw bestanden en mappen continu wilt synchroniseren, moet u MEGA op de achtergrond laten draaien @@ -161,7 +161,7 @@ Selecteer - Er is een probleem met een bestand of map waarvoor u een beslissing moet nemen om het probleem op te lossen + An item has an issue that needs your decision to resolve it Wachten tot andere processen zijn voltooid @@ -185,7 +185,7 @@ Er is een actie voor het verplaatsen of hernoemen van de naam gedetecteerd in MEGA, maar deze kon niet lokaal worden gerepliceerd. - Verplaatsen of hernoemen werd lokaal gedetecteerd, maar kon niet worden gerepliceerd in MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Wacht tot de scan is voltooid om te bepalen of het bestand is verplaatst of verwijderd. diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index db772e3c2e..b0063fd630 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronizacja [A](%1$d)[/A] - Musimy uzyskać dostęp do pamięci tego urządzenia, aby zsynchronizować katalog lokalny. Kliknij tutaj, aby zezwolić na dostęp. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. Aby stale synchronizować pliki i katalogi, pozwól MEGA działać w tle @@ -169,7 +169,7 @@ Wybierz - Plik lub katalog ma problem, który wymaga podjęcia decyzji, aby go rozwiązać + An item has an issue that needs your decision to resolve it Oczekiwanie na zakończenie innych procesów @@ -193,7 +193,7 @@ Akcja przeniesienia lub zmiany nazwy została wykryta w MEGA, ale nie można jej powielić lokalnie. - Przeniesienie lub zmiana nazwy zostały wykryte lokalnie, ale nie mogły zostać odtworzone w MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Oczekiwanie na zakończenie skanowania w celu ustalenia, czy plik został przeniesiony lub usunięty. diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index 844e6a1eaf..e5bc6e4472 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -9,7 +9,7 @@ Sincronizações [A](%1$d)[/A] - Nós precisamos acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque aqui para permitir o acesso + O MEGA precisa acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque aqui para permitir o acesso Para a sincronização contínua dos seus arquivos e das suas pastas, permita que o MEGA seja executado em segundo plano @@ -165,7 +165,7 @@ Selecionar - Há um problema com um arquivo ou uma pasta que precisa de uma decisão sua para ser resolvido + Há um problema com um item que precisa de uma decisão sua para ser resolvido Esperando a conclusão de outros processos @@ -189,7 +189,7 @@ Foi detectada no MEGA uma ação para mover ou renomear, mas não foi possível replicá-la no dispositivo local. - Foi detectado que uma mudança ou renomeação foi feita localmente, mas não foi possível replicá-la no MEGA. + Foi detectada no dispositivo local uma ação para mover ou renomear, mas não foi possível replicá-la no MEGA. Esperando terminar de escanear para comprovar se o arquivo foi movido ou deletado. diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index 9dfbe7a217..6685a69b56 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -9,7 +9,7 @@ Sincronizări [A](%1$d)[/A] - Trebuie să accesăm spațiul de stocare al dispozitivului pentru a vă sincroniza folderul local. Atingeți aici pentru a permite accesul. + MEGA trebuie să acceseze spațiul de stocare al dispozitivului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal @@ -165,7 +165,7 @@ Selectează - Un fișier sau folder are o problemă care necesită decizia dvs. pentru a o rezolva + Un element are o problemă care necesită decizia dvs. pentru a o rezolva În așteptarea finalizării altor procese @@ -189,7 +189,7 @@ O mutare sau redenumire a fost detectată în MEGA, dar nu a putut fi replicată local. - O mutare sau redenumire a fost detectată la nivel local, dar nu a putut fi reprodusă în MEGA. + O mutare sau redenumire a fost detectată local, dar nu a putut fi replicată în MEGA. Așteptarea finalizării scanării pentru a determina dacă fișierul a fost mutat sau șters. diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index e80ef3c997..5e02320999 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -9,7 +9,7 @@ Синхронизации [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -169,7 +169,7 @@ Выбрать - С одним файлом или папкой связана ошибка, для исправления которой требуется ваше решение + An item has an issue that needs your decision to resolve it Ожидание завершения других процессов @@ -193,7 +193,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - Обнаружено локальное перемещение или переименование, но его не удалось воспроизвести в MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Ожидание завершения сканирования, чтобы определить, был ли файл перемещён или удалён. diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index ca049e6929..1c1ea62958 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -9,7 +9,7 @@ ซิงค์ [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -157,7 +157,7 @@ เลือก - ไฟล์หรือโฟลเดอร์มีปัญหาที่ต้องแก้ไข คุณต้องตัดสินใจว่าจะดำเนินการอย่างไร + An item has an issue that needs your decision to resolve it รอให้กระบวนการอื่นเสร็จสิ้นก่อน @@ -181,7 +181,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - ระบบตรวจพบว่ามีการย้ายหรือเปลี่ยนชื่อไฟล์ในเครื่องของคุณ แต่ไม่สามารถจำลองการเปลี่ยนแปลงนี้บน MEGA ได้ + A move or rename action was detected locally, but couldn’t be replicated in MEGA. กำลังรอการสแกนเพื่อดูว่าไฟล์ถูกย้ายหรือลบไปหรือไม่ diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 6533b281ef..eb03e8c16d 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -9,7 +9,7 @@ Đồng bộ [A](%1$d)[/A] - Chúng tôi cần truy cập bộ nhớ thiết bị để đồng bộ hóa thư mục cục bộ của bạn. Chạm vào đây để cho phép quyền truy cập. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. Để liên tục đồng bộ hóa các tệp tin và thư mục của bạn, cho phép MEGA chạy trong nền @@ -157,7 +157,7 @@ Chọn - Một tệp tin hoặc thư mục gặp phải vấn đề và cần quyết định giải quyết của bạn + An item has an issue that needs your decision to resolve it Đang chờ các quy trình khác được hoàn thành @@ -181,7 +181,7 @@ Một việc di chuyển hoặc đổi tên đã được phát hiện trên MEGA, nhưng không thể phỏng y theo trong cục bộ. - Một việc di chuyển hoặc đổi tên đã được phát hiện trong cục bộ, nhưng không thể phỏng y theo trên MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Đang chờ cho quá trình quét kết thúc để xác định xem có tệp tin nào đã di chuyển hay bị xóa. diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index a05bdca570..ca808ad7bb 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -9,7 +9,7 @@ 同步[A](%1$d)[/A] - 我们需要访问您设备的存储空间,才能同步您的本地文件夹。点按此处以允许访问。 + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. 若要持续同步您的文件和文件夹,请允许MEGA在后台运行 @@ -157,7 +157,7 @@ 选择 - 单个文件或文件夹存在需要您决定才能解决的问题 + An item has an issue that needs your decision to resolve it 正在等待其它进程完成 @@ -181,7 +181,7 @@ 在MEGA中检测到移动或重命名操作,但无法在本地重现。 - 检测到本地发生的移动或重命名,但无法在MEGA中复制。 + A move or rename action was detected locally, but couldn’t be replicated in MEGA. 等待扫描完成以确定文件是否已移动或删除。 diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 7506d6d607..0d7f9dd63b 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -9,9 +9,9 @@ 同步[A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA需要存取您裝置的儲存空間,以便同步您的本地資料夾。點選此處以允許存取。 - To continuously sync your files and folders, allow MEGA to run in the background + 若要持續同步您的檔案和資料夾,請允許MEGA在背景中運行 %d個檔案 @@ -103,7 +103,7 @@ 只在WiFi連線 - You’ll need to set up a local folder on your device that will sync with a chosen folder on your Cloud drive + 您需要在您的裝置上設定一個本地資料夾,該資料夾將與您雲端硬碟上選定的資料夾同步 監控同步 @@ -157,7 +157,7 @@ 選擇 - 檔案或資料夾存在需要您決策以解決的問題 + An item has an issue that needs your decision to resolve it 正在等待其它程序完成 @@ -179,9 +179,9 @@ 同步的一側有多個具有相同名稱的項目,這些項目在同步的另一側都將成為相同的單一項目 - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + 在MEGA中偵測到移動或重新命名操作,但無法在本地複製。 - 偵測到本地發生的移動或重新命名,但無法在MEGA中複製。 + 在本地偵測到移動或重新命名操作,但無法在MEGA中複製。 等待掃描完成以確定檔案是否已移動或刪除。 diff --git a/feature/sync/src/main/res/values/strings_sync_feature.xml b/feature/sync/src/main/res/values/strings_sync_feature.xml index 42e1c1993d..0755ef749c 100644 --- a/feature/sync/src/main/res/values/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values/strings_sync_feature.xml @@ -9,7 +9,7 @@ Syncs [A](%1$d)[/A] - We need to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. To continuously sync your files and folders, allow MEGA to run in the background @@ -161,7 +161,7 @@ Select - A file or folder has an issue that needs your decision to resolve it + An item has an issue that needs your decision to resolve it Waiting for other processes to complete @@ -185,7 +185,7 @@ A move or rename action was detected in MEGA, but couldn’t be replicated locally. - Moving or renaming was detected as happening locally, but couldn’t be replicated in MEGA. + A move or rename action was detected locally, but couldn’t be replicated in MEGA. Waiting for scan to finish to determine if the file was moved or deleted. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 15a65e4e06..876795cfa0 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -119,7 +119,7 @@ مجلدات - Others + أخرى تاريخ الإضافة @@ -137,65 +137,61 @@ أقدم - Videos + مقاطع الفيديو - Playlists + قائمة تشغيل - Location + الموقع - All locations + جميع المواقع - Cloud drive + السواقة السحابية - Camera uploads + ترفيعات الكاميرا - Shared items + عناصر مشاركة - Duration + مدة - All durations + جميع المدد - Less than 10 seconds + أقل من 10 ثوانٍ - Between 10 and 60 seconds + بين 10 و60 ثانية - Between 1 and 4 minutes + بين 1 و 4 دقائق - Between 4 and 20 minutes + بين 4 و 20 دقيقة - More than 20 minutes + أكثر من 20 دقيقة - Enter playlist name + أدخل اسم قائمة التشغيل - Rename + إعادة التسمية - A playlist with this name already exists. Enter a different name. + قائمة تشغيل بهذا الاسم موجودة بالفعل. أدخل اسمًا مختلفًا. - Delete playlist\? + حذف قائمة التشغيل؟ - Delete + حذف - No playlists found + لم يتم العثور على قوائم تشغيل - Delete playlist + حذف قائمة التشغيل - Remove from playlist\? + إزالة من قائمة التشغيل؟ - Remove + احذف - Play all + تشغل الكل - No videos + لا يوجد مقطع فيديو - Choose files + اختر الملفات - - - - - - + Deleted %1$d playlist + Deleted %1$d playlists @@ -204,16 +200,28 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + تم إزالة %1$d عنصر من ”%2$s“ + تم إزالة %1$d عنصر من ”%2$s“ + تم إزالة %1$d عنصرين من ”%2$s“ + تم إزالة %1$d عناصر من ”%2$s“ + تم إزالة %1$d عنصراً من ”%2$s“ + تم إزالة %1$d عنصر من ”%2$s“ - %1$d video - %1$d videos + %1$d مقطع فيديو + %1$d مقطع فيديو + %1$d مقطعي فيديو + %1$d مقاطع فيديو + %1$d مقطع فيديو + %1$d فيديوهات You may not have any apps installed which can open this website تم حذف ”%1$s“ + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index ee64b6a94d..df755702ee 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -119,7 +119,7 @@ Ordner - Others + Sonstiges Hinzugefügt @@ -141,17 +141,17 @@ Playlists - Location + Ort - All locations + Alle Speicherorte - Cloud drive + Cloud Drive - Camera uploads + Kamera-Uploads - Shared items + Freigaben - Duration + Dauer All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Umbenennen A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Löschen No playlists found @@ -181,17 +181,17 @@ Remove from playlist\? - Remove + Entfernen Play all - No videos + Keine Videos Choose files - - + Deleted %1$d playlist + Deleted %1$d playlists @@ -200,8 +200,8 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + %1$d Element wurde aus „%2$s“ entfernt + %1$d Elemente wurden aus „%2$s“ entfernt @@ -212,4 +212,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 1122bc8682..ced7cbbf86 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -85,13 +85,13 @@ Syncing paused, battery level too low. Charge battery to resume syncing. - Easy, secure file sharing + Intercambio seguro de archivos - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Comparte archivos de gran tamaño gracias a una generosa cuota de transferencia y garantiza la seguridad con enlaces protegidos por contraseña. - Never lose data again + No vuelva a perder datos - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Sincroniza y haz backups de tus datos para disfrutar de una tranquilidad absoluta. Además, puedes usar el Rebobinado para restaurar carpetas hasta 180 días. MEGA VPN @@ -99,7 +99,7 @@ Llamadas y reuniones sin restricciones - Message, video call, and meet in total privacy with unlimited participants. + Envía mensajes, realiza videollamadas y reúnete con total privacidad con participantes ilimitados. Tipo @@ -119,7 +119,7 @@ Carpetas - Others + Otro Fecha de subida @@ -139,19 +139,19 @@ Videos - Playlists + Listas de reproducción - Location + Ubicación - All locations + Todas las ubicaciones - Cloud drive + Nube - Camera uploads + Subidas de la cámara - Shared items + Elementos compartidos - Duration + Duración All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Renombrar A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Eliminar No playlists found @@ -181,18 +181,17 @@ Remove from playlist\? - Remove + Eliminar Play all - No videos + No hay vídeos - Choose files + Elegir archivos - - - + Deleted %1$d playlist + Deleted %1$d playlists @@ -201,8 +200,9 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + Se ha eliminado %1$d elemento de “%2$s” + Se han eliminado %1$d elementos de “%2$s” + Se han eliminado %1$d elementos de “%2$s” @@ -213,4 +213,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 0ee9e94395..889f99f596 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -119,7 +119,7 @@ Dossiers - Others + Autre Date d’ajout @@ -137,80 +137,87 @@ Plus ancien - Videos + Vidéos - Playlists + Listes de lecture - Location + Emplacement - All locations + Tous les emplacements - Cloud drive + Disque nuagique - Camera uploads + Téléversements de l’appareil photo - Shared items + Éléments partagés - Duration + Durée - All durations + Toutes les durées - Less than 10 seconds + Moins de 10 secondes - Between 10 and 60 seconds + Entre 10 et 60 secondes - Between 1 and 4 minutes + Entre 1 et 4 minutes - Between 4 and 20 minutes + Entre 4 et 20 minutes - More than 20 minutes + Plus de 20 minutes - Enter playlist name + Saisir le nom de la liste de lecture - Rename + Renommer - A playlist with this name already exists. Enter a different name. + Une liste de lecture du même nom existe déjà. Saisissez un nom différent. - Delete playlist\? + Supprimer la liste de lecture \? - Delete + Supprimer - No playlists found + Aucune liste de lecture n’a été trouvée - Delete playlist + Supprimer la liste de lecture - Remove from playlist\? + Supprimer de la liste de lecture \? - Remove + Supprimer - Play all + Tout lire - No videos + Aucune vidéo - Choose files + Choisir des fichiers - - - + %1$d liste de lecture a été supprimée + %1$d de listes de lecture ont été supprimées + %1$d listes de lecture ont été supprimées - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d élément a été ajouté dans « %2$s » + %1$d d’éléments ont été ajoutés dans « %2$s » + %1$d éléments ont été ajoutés dans « %2$s » - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + %1$d élément a été supprimé de « %2$s » + %1$d d’éléments ont été supprimés de « %2$s » + %1$d éléments ont été supprimés de « %2$s » - %1$d video - %1$d videos + %1$d vidéo + %1$d de vidéos + %1$d vidéos - You may not have any apps installed which can open this website + Il semble qu’aucune appli installée ne peut ouvrir ce site Web « %1$s » a été supprimée + + Ne téléverser que pendant la charge + + Ajouter un dossier synchronisé : \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index eb40d830dd..e3670b2365 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -119,7 +119,7 @@ Folder - Others + Lainnya Tanggal ditambahkan @@ -137,21 +137,21 @@ Lama - Videos + Video - Playlists + Daftar putar - Location + Lokasi - All locations + Semua Lokasi Cloud drive - Camera uploads + Unggahan camera - Shared items + Item yang dibagikan - Duration + Durasi All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Ubah nama A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Hapus No playlists found @@ -181,16 +181,17 @@ Remove from playlist\? - Remove + Hapus Play all - No videos + Tidak ada video Choose files - + Deleted %1$d playlist + Deleted %1$d playlists @@ -199,8 +200,7 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + Menghapus %1$d barang dari “%2$s” @@ -211,4 +211,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 9d18f8acd7..27c278eb3e 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -49,7 +49,7 @@ Impossibile leggere la configurazione della sincronizzazione. Riprova più tardi o controlla le autorizzazioni della cartella. - Sync location is unknown + La posizione della sincronizzazione è sconosciuta Intervallo della scansione invalido. Controlla l’impostazione dell’intervallo della scansione e riprova. @@ -85,13 +85,13 @@ Sincronizzazione interrotta, livello della batteria troppo basso. Carica la batteria per riprendere la sincronizzazione. - Easy, secure file sharing + Condivisione di file facile e sicura - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Condividi file di grandi dimensioni grazie a una generosa banda di trasferimento e garantisci la sicurezza con link protetti da password. - Never lose data again + Non perdere mai più dati - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Effettua il backup e la sincronizzazione dei dati per la massima sicurezza. Inoltre, utilizza il Riavvolgimento per ripristinare le cartelle a qualsiasi data fino a 180 giorni. MEGA VPN @@ -99,7 +99,7 @@ Chiamate e meeting senza limiti - Message, video call, and meet in total privacy with unlimited participants. + Invia messaggi, videochiama, e incontra in totale privacy con partecipanti illimitati. Tipo @@ -119,7 +119,7 @@ Cartelle - Others + Altro Data aggiunta @@ -137,80 +137,87 @@ Vecchio - Videos + Video - Playlists + Playlist - Location + Posizione - All locations + Tutte le posizioni Cloud drive - Camera uploads + Caricamenti da fotocamera - Shared items + Oggetti condivisi - Duration + Durata - All durations + Tutte le durate - Less than 10 seconds + Meno di 10 secondi - Between 10 and 60 seconds + Tra 10 e 60 secondi - Between 1 and 4 minutes + Tra 1 e 4 minuti - Between 4 and 20 minutes + Tra 4 e 20 minuti - More than 20 minutes + Più di 20 minuti - Enter playlist name + Inserisci un nome per la playlist - Rename + Rinomina - A playlist with this name already exists. Enter a different name. + Una playlist con questo nome già esiste. Inserisci un nome differente. - Delete playlist\? + Eliminare la playlist\? - Delete + Cancella - No playlists found + Nessuna playlist trovata - Delete playlist + Elimina la playlist - Remove from playlist\? + Rimuovere dalla playlist\? - Remove + Rimuovi - Play all + Riproduci tutto - No videos + Nessun video - Choose files + Scegli i file - - - + %1$d playlist eliminata + %1$d di playlist eliminate + %1$d playlist eliminate - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d oggetto aggiunto a “%2$s” + %1$d di oggetti aggiunti a “%2$s” + %1$d oggetti aggiunti a “%2$s” - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + %1$d oggetto rimosso da “%2$s” + %1$d di oggetti rimossi da “%2$s” + %1$d oggetti rimossi da “%2$s” %1$d video - %1$d videos + %1$d di video + %1$d video - You may not have any apps installed which can open this website + Potresti non avere alcuna app installata in grado di aprire questo sito web - “%1$s” deleted + “%1$s” eliminata + + Carica solo durante la ricarica + + Aggiungi cartella sincronizzata: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index a51b07a119..8b726f187c 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -31,7 +31,7 @@ アカウントがブロックされているため、このフォルダを同期またはバックアップできません。 - このフォルダの同期またはバックアップ中に問題が発生しました。あとでもう一度お試しください。問題が解決しない場合は、サポートにお問い合わせください。 + このフォルダの同期またはバックアップ中に問題が発生しました。あとでもう一度お試しください。問題が解決しない場合は、サポートにご連絡ください。 アカウントが再読み込みされました。バックアップまたは同期に対して欠落した更新は適用されていません。 @@ -137,78 +137,79 @@ それ以前 - Videos + 動画 - Playlists + プレイリスト - Location + 場所 - All locations + すべての場所 - Cloud drive + クラウドドライブ - Camera uploads + カメラアップロード - Shared items + 共有項目 - Duration + 長さ - All durations + すべての長さ - Less than 10 seconds + 10秒未満 - Between 10 and 60 seconds + 10秒から60秒 - Between 1 and 4 minutes + 1分から4分 - Between 4 and 20 minutes + 4分から20分 - More than 20 minutes + 20分以上 - Enter playlist name + プレイリスト名を入力 - Rename + 名前を変更 - A playlist with this name already exists. Enter a different name. + この名前のプレイリストはすでに存在します。別の名前を入力してください。 - Delete playlist\? + プレイリストを削除しますか? - Delete + 削除 - No playlists found + プレイリストが見つかりません - Delete playlist + プレイリストを削除 - Remove from playlist\? + プレイリストから削除しますか? - Remove + 削除 - Play all + すべて再生 - No videos + 動画がありません - Choose files + ファイルを選択 - + %1$d個のプレイリストを削除しました - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d項目を「%2$s」に追加しました - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + 「%1$d」から%2$s個の項目を削除しました - %1$d video - %1$d videos + %1$d個の動画 - You may not have any apps installed which can open this website + このウェブサイトを開けるアプリがインストールされていない可能性があります - “%1$s” deleted + 「%1$s」が削除されました + + 充電中のみアップロード + + 同期フォルダを追加: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index fd90515014..d8eabc2b1f 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + 이 폴더는 당신의 기기의 파일 시스템이 지원하지 않기 때문에 MEGA에서 동기화 하거나 백업할 수 없습니다 선택한 폴더는 동기화할 수 없습니다 @@ -13,7 +13,7 @@ MEGA의 폴더가 이동 되었거나, 삭제 되었거나, 접근 권한이 없어서 찾을 수 없습니다 - Unable to sync or back up this folder as your storage is full + 저장소가 가득 찼기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 요금제가 만료되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 @@ -23,19 +23,19 @@ 당신에게 전체 권한 없이 공유된 폴더이기 때문에 폴더를 동기화할 수 없습니다. - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. 동기화된 폴더가 포함되어 있는 폴더이기 때문에 동기화할 수 없습니다 MEGA는 VirtualBox 폴더를 동기화 또는 백업할 수 없습니다 - Unable to sync or back up this folder as the account has been blocked + 계정이 차단되었기 때문에 이 폴더를 동기화 또는 백업할 수 없습니다 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 나중에 다시 시도하세요. 만약 문제가 계속되면, 지원에 연락주세요. 계정을 다시 불러왔습니다. 백업 또는 동기화에 누락된 변경사항이 적용되지 않습니다. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + 데스크톱 앱에서 로그아웃한 것으로 나타나서 동기화 또는 백업이 멈추었습니다. 데스크톱 앱에서 다시 로그인하고, 동기화 또는 백업을 재개하세요. N/A @@ -43,13 +43,13 @@ 같은 위치에 이미 동기화된 폴더가 있습니다. - Renaming failed + 이름 변경 실패 이 동기화를 위한 .megaignore 파일을 만들 수 없습니다 동기화 설정을 읽을 수 없습니다. 나중에 다시 시도하거나 폴더 권한을 확인하세요. - Sync location is unknown + 동기화 위치를 알 수 없습니다 잘못된 탐색 간격. 탐색 간격 설정을 확인하고 다시 시도하세요. @@ -69,7 +69,7 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + MEGA 폴더가 휴지통에 있어서 폴더를 동기화 또는 백업할 수 없습니다 장치의 폴더를 찾을 수 없습니다. 나중에 다시 시도하세요. @@ -79,19 +79,19 @@ 이 폴더를 동기화 또는 백업하던 중 문제가 발생했습니다. 동기화 또는 백업을 멈추고 데스크톱 앱에서 다시 설정하세요, 또는 지원에 연락주세요. - Folder can’t be synced as it’s already inside a synced folder + 동기화된 폴더 안에 위치한 폴더이기 때문에 동기화할 수 없습니다 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 이 폴더의 파일을 동기화 또는 백업할 수 없습니다. 데스크톱 앱에서 동기화 또는 백업을 다시 활성화 해야 합니다. - Syncing paused, battery level too low. Charge battery to resume syncing. + 배터리 수준이 너무 낮아서, 동기화가 일시정지 되었습니다. 동기화를 재개하려면 배터리를 충전하세요. - Easy, secure file sharing + 쉽고, 안전한 파일 공유 - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + 넉넉한 전송 할당량 덕분에 큰 파일을 공유하고 암호로 공유된 링크로 보안을 보장하세요. - Never lose data again + 다시는 데이터를 잃지 마세요 - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + 완벽한 확신을 위해 데이터를 백업하고 동기화하세요. 또한, 되돌리기를 이용하여 폴더를 최대 180일까지 원하는 날짜로 복원하세요. MEGA VPN @@ -99,7 +99,7 @@ 제한 없는 통화와 회의 - Message, video call, and meet in total privacy with unlimited participants. + 제한 없는 참가자와 함께 완벽한 개인 정보 보호 안에서 메시지, 영상 통화, 회의하세요. 형식 @@ -119,7 +119,7 @@ 폴더 - Others + 기타 추가된 날짜 @@ -137,78 +137,79 @@ 더 오래됨 - Videos + 동영상 - Playlists + 재생 목록 - Location + 위치 - All locations + 모든 위치 - Cloud drive + 클라우드 드라이브 - Camera uploads + 카메라 업로드 - Shared items + 공유된 항목 - Duration + 길이 - All durations + 모든 기간 - Less than 10 seconds + 10초 이하 - Between 10 and 60 seconds + 10초와 60초 사이 - Between 1 and 4 minutes + 1분과 4분 사이 - Between 4 and 20 minutes + 4분과 20분 사이 - More than 20 minutes + 20분 이상 - Enter playlist name + 재생목록 이름을 입력하세요 - Rename + 이름 바꾸기 - A playlist with this name already exists. Enter a different name. + 이 이름을 가진 재생목록이 이미 존재합니다. 다른 이름을 입력하세요. - Delete playlist\? + 재생목록을 삭제할까요\? - Delete + 삭제 - No playlists found + 재생목록 없음 - Delete playlist + 재생목록 삭제 - Remove from playlist\? + 재생목록에서 제거할까요\? - Remove + 제거 - Play all + 모두 재생 - No videos + 동영상 없음 - Choose files + 파일 선택 - + %1$d개의 재생목록 삭제됨 - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d개의 항목을 “%2$s”에 추가함 - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + “%2$s”에서 %1$d개의 항목 제거함 - %1$d video - %1$d videos + 동영상 %1$d개 - You may not have any apps installed which can open this website + 이 웹사이트를 열 수 있는 앱을 설치하지 않은 것 같습니다 - “%1$s” deleted + “%1$s” 삭제됨 + + 충전 중일 때만 업로드 + + 동기화된 폴더 추가: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index ad2c22d8e4..93c1ec89ed 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -119,7 +119,7 @@ Mappen - Andere + Overige Datum toegevoegd @@ -137,79 +137,83 @@ Ouder - Videos + Video\’s - Playlists + Afspeellijsten - Location + Locatie - All locations + Alle lokaties - Cloud drive + Cloud schijf Camera uploads - Shared items + Gedeelde items - Duration + Looptijd - All durations + Alle looptijden - Less than 10 seconds + Minder dan 10 seconden - Between 10 and 60 seconds + Tussen 10 en 60 seconden - Between 1 and 4 minutes + Tussen 1 en 4 minuten - Between 4 and 20 minutes + Tussen 4 en 20 minuten - More than 20 minutes + Meer dan 20 minuten - Enter playlist name + Voer de naam van de afspeellijst in - Rename + Hernoemen - A playlist with this name already exists. Enter a different name. + Er bestaat al een playlist met deze naam. Voer een andere naam in. - Delete playlist\? + Afspeellijst verwijderen\? - Delete + Verwijderen - No playlists found + Geen afspeellijsten gevonden - Delete playlist + Afspeellijst verwijderen - Remove from playlist\? + Uit de afspeellijst verwijderen\? - Remove + Verwijderen - Play all + Alles afspelen - No videos + Geen video\’s - Choose files + Kies bestanden - - + Deleted %1$d playlist + Deleted %1$d playlists - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + Item %1$dtoegevoegd naar “%2$s” + Items %1$d toegevoegd naar “%2$s” - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + Item %1$d verwijderd van “%2$s” + Items %1$d verwijderd van “%2$s” %1$d video - %1$d videos + %1$d video\’s - You may not have any apps installed which can open this website + Mogelijk hebt u geen applicaties geïnstalleerd die deze website kunnen openen “%1$s” verwijderd + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 4159e91875..ecffdb9ad0 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -119,7 +119,7 @@ Katalogi - Pozostałe + Inne Data dodania @@ -137,21 +137,21 @@ Starsze - Videos + Filmy - Playlists + Listy odtwarzania - Location + Lokalizacja - All locations + Wszystkie lokalizacje - Cloud drive + Dysk - Camera uploads + Przesyłanie z kamery - Shared items + Udostępnione - Duration + Czas trwania All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Zmień nazwę A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Usuń No playlists found @@ -181,19 +181,17 @@ Remove from playlist\? - Remove + Usuń Play all - No videos + Brak filmów - Choose files + Wybierz pliki - - - - + Deleted %1$d playlist + Deleted %1$d playlists @@ -214,4 +212,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 5c5c670cbf..c30bcf519d 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -137,80 +137,87 @@ Mais antigo - Videos + Vídeos - Playlists + Listas de reprodução - Location + Localização - All locations + Todos os locais - Cloud drive + Nuvem de arquivos - Camera uploads + Uploads da câmera - Shared items + Itens compartilhados - Duration + Duração - All durations + Qualquer duração - Less than 10 seconds + Menos de 10 segundos - Between 10 and 60 seconds + Entre 10 e 60 segundos - Between 1 and 4 minutes + Entre 1 e 4 minutos - Between 4 and 20 minutes + Entre 4 e 20 minutos - More than 20 minutes + Mais de 20 minutos - Enter playlist name + Digite o nome da lista de reprodução - Rename + Renomear - A playlist with this name already exists. Enter a different name. + Já existe uma lista de reprodução com este nome. Digite outro nome. - Delete playlist\? + Deletar a lista de reprodução\? - Delete + Deletar - No playlists found + Não há listas de reprodução - Delete playlist + Deletar a lista de reprodução - Remove from playlist\? + Você quer eliminar da lista de reprodução\? - Remove + Remover - Play all + Reproduzir tudo - No videos + Não há vídeos - Choose files + Escolher arquivos - - - + %1$d lista de reprodução foi deletada + %1$d de listas de reprodução foram deletadas + %1$d listas de reprodução foram deletadas - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d item foi adicionado a “%2$s” + %1$d de itens foram adicionados a “%2$s” + %1$d itens foram adicionados a “%2$s” - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + %1$d item foi eliminado de “%2$s” + %1$d de itens foram eliminados de “%2$s” + %1$d itens foram eliminados de “%2$s” - %1$d video - %1$d videos + %1$d vídeo + %1$d de vídeos + %1$d vídeos - You may not have any apps installed which can open this website + Parece que não há nenhum aplicativo que permita acessar este site “%1$s” foi deletada + + Somente fazer upload quando estiver carregando + + Adicionar pasta sincronizada: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 62d96fb102..1387b34631 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -119,7 +119,7 @@ Foldere - Alte + Altul Data adăugării @@ -137,80 +137,87 @@ Mai vechi - Videos + Videoclipuri - Playlists + Listuri de redare - Location + Locație - All locations + Toate locațiile - Cloud drive + Unitate cloud - Camera uploads + Încărcări cameră - Shared items + Elemente partajate - Duration + Durată - All durations + Toate duratele - Less than 10 seconds + Mai puțin de 10 secunde - Between 10 and 60 seconds + Între 10 și 60 de secunde - Between 1 and 4 minutes + Între 1 și 4 minute - Between 4 and 20 minutes + Între 4 și 20 de minute - More than 20 minutes + Mai mult de 20 de minute - Enter playlist name + Introduceți numele listei de redare - Rename + Redenumește - A playlist with this name already exists. Enter a different name. + Există deja o listă de redare cu acest nume. Introduceți un alt nume. - Delete playlist\? + Ștergeți lista de redare\? - Delete + Șterge - No playlists found + Nicio listă de redare găsită - Delete playlist + Ștergeți lista de redare - Remove from playlist\? + Eliminați din listă de redare\? - Remove + Elimină - Play all + Redați toate - No videos + Niciun videoclip - Choose files + Alegeți fișiere - - - + %1$d listă de redare a fost ștearsă + %1$d liste de redare au fost șterse + %1$d de liste de redare au fost șterse - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + %1$d a fost adăugat la „%2$s” + %1$d elemente au fost adăugate la „%2$s” + %1$d de elemente au fost adăugate la „%2$s” - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + %1$d element a fost eliminat din „%2$s” + %1$d elemente au fost eliminate din „%2$s” + %1$d de elemente au fost eliminate din „%2$s” - %1$d video - %1$d videos + %1$d videoclip + %1$d videoclipuri + %1$d de videoclipuri - You may not have any apps installed which can open this website + Este posibil să nu aveți instalată nicio aplicație care să poată deschide acest site web „%1$s” a fost șters + + Încărcați doar când dispozitivul se încarcă + + Adăugați folder sincronizat: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 05c55481ea..7e7a07a638 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -85,13 +85,13 @@ Syncing paused, battery level too low. Charge battery to resume syncing. - Easy, secure file sharing + Простой и безопасный обмен файлами - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Делитесь большими файлами благодаря большому объёму передачи данных и обеспечьте безопасность с помощью ссылок, защищённых паролем. - Never lose data again + Данные больше не потеряются - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Создавайте резервные копии и синхронизируйте данные для полной уверенности. Также используйте функцию перемотки, чтобы восстановить папки до любой даты за период до 180 дней. MEGA VPN @@ -99,7 +99,7 @@ Неограниченные звонки и встречи - Message, video call, and meet in total privacy with unlimited participants. + Пишите сообщения, совершайте видеозвонки и проводите встречи в условиях полной конфиденциальности с неограниченным количеством участников. Тип @@ -119,7 +119,7 @@ Папки - Others + Другие Дата добавления @@ -137,21 +137,21 @@ Старше - Videos + Видео - Playlists + Плейлисты - Location + Расположение - All locations + Все расположения - Cloud drive + Облачный диск - Camera uploads + Загрузки из камеры - Shared items + Общие элементы - Duration + Продолжительность All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Переименовать A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Удалить No playlists found @@ -181,19 +181,17 @@ Remove from playlist\? - Remove + Удалить Play all - No videos + Нет видео Choose files - - - - + Deleted %1$d playlist + Deleted %1$d playlists @@ -202,8 +200,10 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + Из «%2$s» удалён %1$d элемент + Из «%2$s» удалено %1$d элемента + Из «%2$s» удалено %1$d элементов + Из «%2$s» удалено %1$d элемента @@ -214,4 +214,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 654ad014d1..bfbf515cfb 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -119,7 +119,7 @@ โฟลเดอร์ - Others + อื่น ๆ วันที่เพิ่ม @@ -137,21 +137,21 @@ เก่ากว่า - Videos + วิดีโอ - Playlists + เพลย์ลิส - Location + ตำแหน่งที่ตั้ง - All locations + ทุกตำแหน่งที่ตั้ง - Cloud drive + คลาวด์ไดรฟ์ - Camera uploads + อัปโหลดจากกล้อง - Shared items + รายการที่แชร์ไว้ - Duration + ระยะเวลา All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + เปลี่ยนชื่อ A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + ลบ No playlists found @@ -181,16 +181,17 @@ Remove from playlist\? - Remove + ลบออก Play all - No videos + ไม่มีวิดีโอ Choose files - + Deleted %1$d playlist + Deleted %1$d playlists @@ -199,8 +200,7 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + ลบ %1$d รายการออกจาก “%2$s” แล้ว @@ -211,4 +211,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 026066309c..f2ea631054 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -119,7 +119,7 @@ Thư mục - Others + Khác Ngày đã thêm @@ -139,19 +139,19 @@ Videos - Playlists + Danh sách phát - Location + Vị trí - All locations + Tất cả các vị trí - Cloud drive + Ổ Mây - Camera uploads + Đăng tải camêra - Shared items + Các mục chia sẻ - Duration + Thời lượng All durations @@ -167,13 +167,13 @@ Enter playlist name - Rename + Đổi tên A playlist with this name already exists. Enter a different name. Delete playlist\? - Delete + Xóa No playlists found @@ -181,16 +181,17 @@ Remove from playlist\? - Remove + Loại bỏ Play all - No videos + Không có video - Choose files + Chọn tệp tin - + Deleted %1$d playlist + Deleted %1$d playlists @@ -199,8 +200,7 @@ - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + Đã loại bỏ %1$d mục khỏi “%2$s” @@ -211,4 +211,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Thêm thư mục đồng bộ hóa: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 55469c0407..6e8c84eacc 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -17,39 +17,39 @@ 由于您的方案已过期,因此无法同步或备份此文件夹 - Folder can’t be synced as the user who shared this folder has reached their storage limit + 无法同步该文件夹,因为共享此文件夹的用户已达到其存储限制 无法找到MEGA中的文件夹,因为它已被移动或删除,或者您可能没有访问权限 - Folder can’t be synced as it’s a shared folder that you don’t have full access to + 无法同步该文件夹,因为您没有完全访问此共享文件夹的权限 - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + 无法同步或备份此文件夹中的文件。您需要从桌面应用程序重新启用同步或备份。 - Folder can’t be synced as it already contains synced folders + 文件夹无法同步,因为它已经包含在已经同步的文件夹中 - MEGA can’t sync or back up VirtualBox folders + MEGA无法同步或备份VirtualBox文件夹 - Unable to sync or back up this folder as the account has been blocked + 由于该帐户已被封锁,无法同步或备份此文件夹 同步或备份此文件夹时出现问题。请稍后再试。如果问题仍然存在,请联系客服部门。 帐户已重新加载。对备份或同步的任何更新尚未应用。 - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + 由于您似乎已登出桌面应用程序,因此同步或备份已停止。通过桌面应用程序重新登录,然后恢复同步或备份。 N/A 无法定位外部驱动器中的文件夹。 - There’s already a synced folder at the same location + 在同一个位置已经有一个同步的文件夹 - Renaming failed + 重命名失败 - Couldn’t create a .megaignore file for this sync + 无法为此同步创建.megaignore文件 无法读取同步配置。稍后重试或检查文件夹权限。 - Sync location is unknown + 同步位置未知 扫描间隔无效。请检查扫描间隔设置,然后重试。 @@ -61,17 +61,17 @@ Unable to open state cache database - Insufficient storage space on your device + 您设备上的存储空间不足 无法读取同步位置。检查该位置是否可访问以及是否已授予该文件夹位置的权限。 - An unknown error occurred. Contact Support. + 出现未知错误。请联系客服。 Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + 由于MEGA文件夹位于回收站中,文件夹无法同步或备份 - Folder in your device can’t be located right now. Try again later. + 目前无法找到您设备中的文件夹。稍后重试。 无法找到您设备中的文件夹 @@ -79,19 +79,19 @@ 同步或备份此文件夹时出现问题。停止同步或备份,然后尝试在桌面应用程序中重新进行设置,或者联系客服。 - Folder can’t be synced as it’s already inside a synced folder + 文件夹无法同步,因为它已经在同步的文件夹中 - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + 此文件夹中的文件无法同步或备份。您需要从桌面应用程序重新启用同步或备份。 - Syncing paused, battery level too low. Charge battery to resume syncing. + 同步已暂停,电池电量太低。为电池充电以恢复同步。 - Easy, secure file sharing + 轻松、安全的文件共享 - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + 感谢充足的传输流量共享大文件,并通过受密码保护的链接确保安全。 - Never lose data again + 再也不会丢失数据 - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + 让您完全放心的备份和同步您的数据。另外,使用还原功能将可将文件夹恢复到任何日期,最长可达180天。 MEGA VPN @@ -99,7 +99,7 @@ 无限制的通话和会议 - Message, video call, and meet in total privacy with unlimited participants. + 消息,视频通话,以及无限参与者的完全私密会议。 类型 @@ -119,7 +119,7 @@ 文件夹 - Others + 其它 添加日期 @@ -137,78 +137,79 @@ 较旧的 - Videos + 视频 - Playlists + 播放列表 - Location + 位置 - All locations + 所有位置 - Cloud drive + 云盘 - Camera uploads + 相机上传 - Shared items + 已共享项目 - Duration + 时长 - All durations + 所有时长 - Less than 10 seconds + 少于10秒 - Between 10 and 60 seconds + 在10到60秒之间 - Between 1 and 4 minutes + 在1到4分钟之间 - Between 4 and 20 minutes + 在4到20分钟之间 - More than 20 minutes + 超过20分钟 - Enter playlist name + 输入播放列表名称 - Rename + 重命名 - A playlist with this name already exists. Enter a different name. + 使用此名称的播放列表已经存在。输入不同的名称。 - Delete playlist\? + 删除播放列表? - Delete + 删除 - No playlists found + 未找到播放列表 - Delete playlist + 删除播放列表 - Remove from playlist\? + 从播放列表中移除? - Remove + 移除 - Play all + 全部播放 - No videos + 没有视频 - Choose files + 选择文件 - + 已删除%1$d个播放列表 - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + 已添加%1$d个项目到“%2$s” - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + 已从“%2$s”中移除了%1$d个项目 - %1$d video - %1$d videos + %1$d个视频 - You may not have any apps installed which can open this website + 您可能没有安装任何可以打开此网站的应用程序 - “%1$s” deleted + 已删除“%1$s” + + 仅在充电时上传 + + Add synchronised folder: \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 143dfe4fbe..2fb5df36a6 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -17,7 +17,7 @@ 由於您的方案已過期,因此無法同步或備份此資料夾。 - 無法同步資料夾,因為共享此資料夾的使用者已達到其儲存限制。 + 無法同步資料夾,因為共享此資料夾的使用者已達到其儲存上限。 MEGA無法找到MEGA中的資料夾,因為它已被移動或刪除,或者您可能沒有存取權限。 @@ -83,7 +83,7 @@ 此資料夾中的檔案無法同步或備份。您需要從桌面應用程式重新啟用同步或備份。 - 同步暫停,電池電量過低。 為電池充電以恢復同步。 + 同步暫停,電池電量過低。為電池充電以恢復同步。 輕鬆、安全的檔案共享 @@ -119,7 +119,7 @@ 資料夾 - 其它 + 其他 新增日期 @@ -137,78 +137,79 @@ 較舊的 - Videos + 影片 - Playlists + 播放列表 - Location + 位置 - All locations + 所有位置 - Cloud drive + 雲端硬碟 - Camera uploads + 相機上傳 - Shared items + 共享項目 - Duration + 通話時間 - All durations + 所有時間 - Less than 10 seconds + 少數10秒 - Between 10 and 60 seconds + 10到60秒之間 - Between 1 and 4 minutes + 1到4分鐘之間 - Between 4 and 20 minutes + 4到20分鐘之間 - More than 20 minutes + 超過20分鐘 - Enter playlist name + 輸入播放列表名稱 - Rename + 重新命名 - A playlist with this name already exists. Enter a different name. + 已存在同名的播放列表。輸入不同的名稱。 - Delete playlist\? + 刪除播放列表? - Delete + 刪除 - No playlists found + 未找到播放列表 - Delete playlist + 刪除播放列表 - Remove from playlist\? + 要從播放列表中移除? - Remove + 移除 - Play all + 播放全部 - No videos + 沒有影片 - Choose files + 選擇檔案 - + 已刪除%1$d個播放列表 - Added %1$d item to “%2$s” - Added %1$d items to “%2$s” + 已新增%1$d個項目到「%2$s」 - Removed %1$d item from “%2$s” - Removed %1$d items from “%2$s” + 已從「%2$s」移除%1$d個項目 - %1$d video - %1$d videos + %1$d個影片 - You may not have any apps installed which can open this website + 您可能沒有安裝任何可以開啟本網站的應用程式 - “%1$s” deleted + 已刪除「%1$s」 + + 僅在充電時上傳 + + 新增同步資料夾: \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index ee763ec55a..5f84a9f44a 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -212,4 +212,8 @@ You may not have any apps installed which can open this website “%1$s” deleted + + Upload only while charging + + Add synchronised folder: \ No newline at end of file From e8cc2b6db7da9e5afe90caa6f124ef3283aba76d Mon Sep 17 00:00:00 2001 From: rohitsoni Date: Mon, 22 Apr 2024 15:41:46 +0530 Subject: [PATCH 103/261] AND-18561 FOlder name is not visible while navigating in cloud drive --- .../app/presentation/clouddrive/FileBrowserViewModel.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt index 8a9d352c8f..d1cf4aad93 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/clouddrive/FileBrowserViewModel.kt @@ -230,7 +230,10 @@ class FileBrowserViewModel @Inject constructor( } } else { _state.update { - it.copy(fileBrowserHandle = handle) + it.copy( + fileBrowserHandle = handle, + updateToolbarTitleEvent = triggered + ) } } refreshNodesState() From ff765b73576bd56852aa92cf5d966d36222c771a Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Tue, 23 Apr 2024 15:37:41 +1200 Subject: [PATCH 104/261] T15942021 Receive a call recording dialog --- .../privacy/android/app/meeting/activity/MeetingActivity.kt | 2 +- .../meeting/view/dialog/CallRecordingConsentDialog.kt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt index 9825b0f449..f34e72df38 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivity.kt @@ -316,7 +316,7 @@ class MeetingActivity : PasscodeActivity() { val state by meetingViewModel.state.collectAsStateWithLifecycle() if (state.isSessionOnRecording && state.showRecordingConsentDialog && !state.isRecordingConsentAccepted) { MegaAppTheme(isDark = true) { - CallRecordingConsentDialog() + CallRecordingConsentDialog(meetingViewModel = meetingViewModel) } } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/dialog/CallRecordingConsentDialog.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/dialog/CallRecordingConsentDialog.kt index 5711f6da18..c7373d599a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/dialog/CallRecordingConsentDialog.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/dialog/CallRecordingConsentDialog.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.style.TextDecoration import androidx.hilt.navigation.compose.hiltViewModel import mega.privacy.android.app.R +import mega.privacy.android.app.meeting.activity.MeetingActivityViewModel import mega.privacy.android.app.presentation.chat.ChatViewModel import mega.privacy.android.core.ui.controls.dialogs.ConfirmationDialog import mega.privacy.android.core.ui.controls.text.MegaSpannedClickableText @@ -31,15 +32,18 @@ import mega.privacy.android.shared.theme.MegaAppTheme @Composable fun CallRecordingConsentDialog( viewModel: ChatViewModel = hiltViewModel(), + meetingViewModel: MeetingActivityViewModel? = null ) { CallRecordingConsentDialog( onConfirm = { viewModel.setIsRecordingConsentAccepted(value = true) viewModel.setShowRecordingConsentDialogConsumed() + meetingViewModel?.setShowRecordingConsentDialogConsumed() }, onDismiss = { viewModel.setIsRecordingConsentAccepted(value = false) viewModel.setShowRecordingConsentDialogConsumed() + meetingViewModel?.setShowRecordingConsentDialogConsumed() }, ) } From d5213e4b94356cc5c84a3f8d9c97123a2b9b970b Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Tue, 23 Apr 2024 15:59:41 +1200 Subject: [PATCH 105/261] T15942012 Cancel a scheduled meeting --- .../meeting/ScheduledMeetingManagementViewModel.kt | 2 ++ .../presentation/chat/list/ChatTabsViewModelTest.kt | 3 --- .../usecase/meeting/IsChatHistoryEmptyUseCase.kt | 12 +++++------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/ScheduledMeetingManagementViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/ScheduledMeetingManagementViewModel.kt index cec7325f0c..bfad1ef05f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/ScheduledMeetingManagementViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/ScheduledMeetingManagementViewModel.kt @@ -40,6 +40,7 @@ import mega.privacy.android.domain.usecase.RemoveChatLink import mega.privacy.android.domain.usecase.account.GetCurrentSubscriptionPlanUseCase import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.chat.ArchiveChatUseCase +import mega.privacy.android.domain.usecase.chat.message.MonitorChatRoomMessagesUseCase import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase import mega.privacy.android.domain.usecase.meeting.BroadcastScheduledMeetingCanceledUseCase import mega.privacy.android.domain.usecase.meeting.CancelScheduledMeetingOccurrenceUseCase @@ -158,6 +159,7 @@ class ScheduledMeetingManagementViewModel @Inject constructor( * @return True if the chat history is empty (only management messages) or false otherwise. */ fun checkIfIsChatHistoryEmpty(chatId: Long) = viewModelScope.launch { + monitorLoadedMessages(chatId) loadMessagesUseCase(chatId) } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/chat/list/ChatTabsViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/chat/list/ChatTabsViewModelTest.kt index fcd28bf976..bd804278b1 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/chat/list/ChatTabsViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/chat/list/ChatTabsViewModelTest.kt @@ -26,7 +26,6 @@ import mega.privacy.android.domain.usecase.chat.MonitorLeaveChatUseCase import mega.privacy.android.domain.usecase.chat.SetNextMeetingTooltipUseCase import mega.privacy.android.domain.usecase.meeting.AnswerChatCallUseCase import mega.privacy.android.domain.usecase.meeting.CancelScheduledMeetingUseCase -import mega.privacy.android.domain.usecase.meeting.IsChatHistoryEmptyUseCase import mega.privacy.android.domain.usecase.meeting.IsParticipatingInChatCallUseCase import mega.privacy.android.domain.usecase.meeting.LoadMessagesUseCase import mega.privacy.android.domain.usecase.meeting.MonitorChatCallUpdatesUseCase @@ -65,7 +64,6 @@ internal class ChatTabsViewModelTest { private val rtcAudioManagerGateway: RTCAudioManagerGateway = mock() private val getCurrentChatStatusUseCase: GetCurrentChatStatusUseCase = mock() private val clearChatHistoryUseCase: ClearChatHistoryUseCase = mock() - private val isChatHistoryEmptyUseCase: IsChatHistoryEmptyUseCase = mock() private val loadMessagesUseCase: LoadMessagesUseCase = mock() private val cancelScheduledMeetingUseCase: CancelScheduledMeetingUseCase = mock() private val isParticipatingInChatCallUseCase: IsParticipatingInChatCallUseCase = mock() @@ -98,7 +96,6 @@ internal class ChatTabsViewModelTest { rtcAudioManagerGateway, getCurrentChatStatusUseCase, clearChatHistoryUseCase, - isChatHistoryEmptyUseCase, loadMessagesUseCase, cancelScheduledMeetingUseCase, isParticipatingInChatCallUseCase, diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/meeting/IsChatHistoryEmptyUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/meeting/IsChatHistoryEmptyUseCase.kt index 4dceda6679..064e64e6c2 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/meeting/IsChatHistoryEmptyUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/meeting/IsChatHistoryEmptyUseCase.kt @@ -1,6 +1,7 @@ package mega.privacy.android.domain.usecase.meeting -import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow import mega.privacy.android.domain.entity.chat.ChatHistoryLoadStatus import mega.privacy.android.domain.repository.ChatRepository import mega.privacy.android.domain.usecase.meeting.LoadMessagesUseCase.Companion.NUMBER_MESSAGES_TO_LOAD @@ -9,7 +10,6 @@ import javax.inject.Inject /** * Monitor if chat history is empty (only management messages) * - * @property chatRepository [ChatRepository] * @property loadMessagesUseCase [LoadMessagesUseCase] */ class IsChatHistoryEmptyUseCase @Inject constructor( @@ -26,15 +26,14 @@ class IsChatHistoryEmptyUseCase @Inject constructor( * @param chatId Chat ID * @return True if the chat history is empty (only management messages) or false otherwise. */ - operator fun invoke(chatId: Long) = callbackFlow { + operator fun invoke(chatId: Long): Flow = flow { chatRepository.monitorOnMessageLoaded(chatId) .collect { message -> message?.let { chatMessage -> pendingToLoad-- if (!chatMessage.isManagementMessage) { - trySend(false) - close() + emit(false) } else { //Management message, no action required. } @@ -46,8 +45,7 @@ class IsChatHistoryEmptyUseCase @Inject constructor( when (chatHistoryLoadStatus) { ChatHistoryLoadStatus.NONE -> { // Full history loaded - trySend(true) - close() + emit(true) } else -> { From fa98ce312f90e6735e838dd865b280c731c44d9d Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Tue, 23 Apr 2024 17:30:00 +1200 Subject: [PATCH 106/261] Pre-release v13.0 --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 36 ++++++++++--------- app/src/main/res/values-th/strings.xml | 31 ++++++++-------- app/src/main/res/values-vi/strings.xml | 6 ++-- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- .../strings_device_center_feature.xml | 24 ++++++------- .../res/values-ar/strings_sync_feature.xml | 2 +- .../res/values-de/strings_sync_feature.xml | 2 +- .../res/values-es/strings_sync_feature.xml | 2 +- .../res/values-in/strings_sync_feature.xml | 2 +- .../res/values-it/strings_sync_feature.xml | 2 +- .../res/values-ja/strings_sync_feature.xml | 2 +- .../res/values-ko/strings_sync_feature.xml | 2 +- .../res/values-nl/strings_sync_feature.xml | 8 ++--- .../res/values-pl/strings_sync_feature.xml | 2 +- .../res/values-pt/strings_sync_feature.xml | 2 +- .../res/values-ru/strings_sync_feature.xml | 6 ++-- .../res/values-th/strings_sync_feature.xml | 2 +- .../res/values-vi/strings_sync_feature.xml | 2 +- .../values-zh-rCN/strings_sync_feature.xml | 2 +- .../values-zh-rTW/strings_sync_feature.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 12 +++++++ .../src/main/res/values-de/strings_shared.xml | 12 +++++++ .../src/main/res/values-es/strings_shared.xml | 14 +++++++- .../src/main/res/values-fr/strings_shared.xml | 12 +++++++ .../src/main/res/values-in/strings_shared.xml | 12 +++++++ .../src/main/res/values-it/strings_shared.xml | 12 +++++++ .../src/main/res/values-ja/strings_shared.xml | 12 +++++++ .../src/main/res/values-ko/strings_shared.xml | 12 +++++++ .../src/main/res/values-nl/strings_shared.xml | 20 ++++++++--- .../src/main/res/values-pl/strings_shared.xml | 12 +++++++ .../src/main/res/values-pt/strings_shared.xml | 12 +++++++ .../src/main/res/values-ro/strings_shared.xml | 12 +++++++ .../src/main/res/values-ru/strings_shared.xml | 28 ++++++++++----- .../src/main/res/values-th/strings_shared.xml | 26 ++++++++++---- .../src/main/res/values-vi/strings_shared.xml | 24 +++++++++---- .../main/res/values-zh-rCN/strings_shared.xml | 12 +++++++ .../main/res/values-zh-rTW/strings_shared.xml | 12 +++++++ 50 files changed, 313 insertions(+), 108 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 9698027c1c..04c2f04fe9 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -884,7 +884,7 @@ هناك الكثير من المحاولات الفاشلة لتسجيل الدخول، يرجى الانتظار لمدة ساعة. - لم يتم التحقق من صحة هذا الحساب حتى الآن. تحقق من صندوق البريد الإلكتروني الخاص بك. + تحقق من صندوق البريد الإلكتروني الخاص بك واتبع الرابط لتأكيد حسابك. رابط المجلد غير متوفر diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a43786ba4b..8d5a9a4dbd 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -844,7 +844,7 @@ Zuviele Login-Fehlversuche. Bitte warten Sie eine Stunde. - This account has not been validated yet. Check your email inbox. + Check your email inbox and follow the link to confirm your account. Ordnerlink nicht verfügbar diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 4bcb227db7..c71c873c6b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -854,7 +854,7 @@ Demasiados intentos de acceso incorréctos. Vuelve a intentarlo en una hora. - Todavía no has confirmado la cuenta. Ve a la bandeja de entrada de tu correo electrónico para proceder. + Ve a la bandeja de entrada de tu correo y pulsa en el enlace que te hemos envíado para confirmar tu cuenta. Enlace de la carpeta no disponible diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index eb701ecf74..1d139f41e2 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -854,7 +854,7 @@ Trop de tentatives infructueuses de connexion, veuillez patienter pendant une heure. - Ce compte n’a pas encore été validé. Vérifiez votre boîte de réception des courriels. + Vérifiez votre boîte de réception des courriels et suivez le lien pour confirmer votre compte. Le lien de dossier est inaccessible diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 262baece73..b188632b1a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -834,7 +834,7 @@ Terlalu banyak coba masuk yang gagal, mohon tunggu selama satu jam. - This account has not been validated yet. Check your email inbox. + Check your email inbox and follow the link to confirm your account. Tautan folder tidak tersedia diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a8ad69aeef..161188ac54 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -854,7 +854,7 @@ Troppi tentativi falliti di effettuare il login, per favore aspetta un’ora. - Questo account non è stato ancora verificato. Controlla la tua casella di posta elettronica. + Controlla la tua casella di posta elettronica e segui il link per confermare il tuo account. Link della cartella non disponibile diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a2d29f1e9d..17d16bd7e5 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -834,7 +834,7 @@ ログインに失敗した回数が多すぎます。1時間お待ちください - このアカウントはまだ検証されていません。メール受信箱をご確認ください。 + メール受信箱を確認し、リンクをクリックしてアカウントを認証してください。 フォルダリンクが使用できません diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index f906237c00..e6c73e6b10 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -834,7 +834,7 @@ 로그인 시도 실패가 너무 많습니다, 1시간 동안 기다려주세요. - 이 계정은 아직 확인되지 않았습니다. 이메일 수신함을 확인하세요. + 계정을 확인하려면 이메일 수신함을 확인하고 링크를 따라가세요. 폴더 링크가 사용불가입니다 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3a572544bc..0a2e3b9676 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -844,7 +844,7 @@ Teveel mislukte pogingen om in te loggen, alstublieft wacht voor een uur. - Dit account is nog niet gevalideerd. Controleer uw e-mailinbox. + Controleer uw e-mailinbox en volg de link om uw account te bevestigen. Link naar map is niet beschikbaar diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 9b5e25b069..40f1e7e8c7 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -864,7 +864,7 @@ Zbyt wiele nieudanych prób logowania. Zaczekaj godzinę. - To konto nie zostało jeszcze zweryfikowane. Sprawdź swoją skrzynkę email. + Sprawdź swoją skrzynkę email i kliknij link, aby potwierdź swoje konto. Link do katalogu jest niedostępny diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 7c06e88f4a..7d28ed0b2f 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -854,7 +854,7 @@ Muitas tentativas de login incorretas. Por favor, aguarde uma hora. - Esta conta ainda não foi confirmada. Acesse o seu email. + Acesse o seu email e use o link para confirmar a sua conta. O link da pasta não está disponível diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 4df08ee410..2cb64b1d53 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -854,7 +854,7 @@ Prea multe încercări eșuate de autentificare, vă rugăm să așteptați o oră. - Acest cont nu a fost încă validat. Verificați căsuța de e-mail. + Verificați căsuța de e-mail și urmați linkul pentru a vă confirma contul. Linkul folderului indisponibil diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1381a81799..de44d39664 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -773,7 +773,7 @@ Подтверждение электронной почты - Check your email inbox to proceed. + Проверьте свою электронную почту, чтобы продолжить. Произошла ошибка, попробуйте снова. @@ -817,7 +817,7 @@ Это ваш существующий адрес электронной почты. - This is the last step to change your email address. Enter your password below. + Остался один шаг до смены адреса электронной почты. Введите пароль. Изменение электронной почты @@ -833,7 +833,7 @@ Получение информации… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + Новый адрес электронной почты нужно подтвердить. Проверьте электронную почту, чтобы продолжить. Удалить изображение профиля? @@ -864,7 +864,7 @@ Слишком много неудачных попыток войти. Пожалуйста, подождите час. - This account has not been validated yet. Check your email inbox. + Подтвердите регистрацию, перейдя по ссылке в письме, которое вам придёт. Ссылка на папку недоступна @@ -2146,8 +2146,10 @@ Больше - Choose file - Choose files + Выбор файла + Выбор файлов + Выбор файлов + Выбор файлов Выбрать папку @@ -2430,7 +2432,7 @@ Разрешить звонки - Allow access to your address book + Разрешите доступ к адресной книге Легко находите контакты из своей адресной книги в MEGA. @@ -3572,7 +3574,7 @@ У вас уже есть подписка. Если вы оформите ещё одну, вы будете платить дважды. Чтобы избежать этого, отмените текущую подписку, зайдя в MEGA в настольном или мобильном веб-браузере. Посетите наш справочный центр для получения дополнительной информации. - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + Перейдите в «Настройки», чтобы разрешить MEGA доступ к устройствам поблизости с помощью Bluetooth. Мы не можем продолжить выставление счёта. Если вы используете клонированное приложение, попробуйте войти в MEGA без него. Если нет, попробуйте улучшить аккаунт через веб-браузер. @@ -3942,7 +3944,7 @@ Здесь хранятся резервные копии файлов и папок. Резервные копии доступны «только для чтения», чтобы защитить их от случайного изменения на Облачном диске.\nВы можете делать резервные копии элементов со своего компьютера в MEGA с помощью нашего настольного приложения. - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + Ваш аккаунт MEGA был заблокирован из-за неоднократных обвинений в нарушении авторских прав. Это означает, что вы не можете получить доступ к аккаунту или данным в нём. \nля получения дополнительной информации о том, как подать встречное заявление, проверьте свою электронную почту. Ваш аккаунт был удалён из-за нарушения Условий использования MEGA.\nВы не сможете восстановить доступ к своим сохранённым данным или зарегистрировать новый аккаунт MEGA. @@ -4083,7 +4085,7 @@ Удалить из альбома? - To enable camera uploads, allow MEGA access to your photos and other media on your device. + Чтобы включить загрузки из камеры, предоставьте MEGA доступ к фотографиям и другим медиафайлам на вашем устройстве. Открыть доступ @@ -5567,13 +5569,13 @@ Получите больше с планом Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. + Перейдите на план Pro и получите больше места для хранения и доступ к функциям Pro. Планы стоят от %1$s в месяц. - MEGA Pro plans include: + Планы MEGA   Pro включают: Максимально гибкое хранилище - Starting from %1$s, find the perfect fit for your storage needs. + Найдите свой идеальный объём хранилища. От %1$s. Перейти на Pro @@ -5680,7 +5682,7 @@ Подписки продлеваются автоматически на последующие периоды той же продолжительности и по той же цене, что и первоначально выбранный период. Вы можете отключить автоматическое продление подписки MEGA Pro не позднее чем за 24 часа до следующего платежа за подписку на странице «Подписки» в [A]Google Play[/A]. - Allow access to your Gallery + Разрешите доступ к «Галерее» Открыть доступ @@ -5864,11 +5866,11 @@ Фото - Flash mode on + Режим вспышки включён - Flash mode off + Режим вспышки выключен - Flash mode auto + Автоматический режим вспышки Отправить в «%1$s» \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index b2c5242a92..312e76ca16 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -746,7 +746,7 @@ การยืนยันที่อยู่อีเมล - Check your email inbox to proceed. + ตรวจสอบกล่องจดหมายอีเมลของคุณเพื่อดำเนินการต่อ เกิดข้อผิดพลาด กรุณาลองอีกครั้ง @@ -790,7 +790,7 @@ นี่คืออีเมลที่คุณมีอยู่ - This is the last step to change your email address. Enter your password below. + นี่เป็นขั้นตอนสุดท้ายในการเปลี่ยนที่อยู่อีเมลของคุณ กรอกรหัสผ่านของคุณด้านล่าง เปลี่ยนอีเมล @@ -806,7 +806,7 @@ กำลังรับข้อมูล… - Your new email address needs to be validated. Check the inbox of the new email address to proceed. + อีเมลใหม่ของคุณยังไม่ได้รับการยืนยัน ตรวจสอบกล่องจดหมายของอีเมลใหม่เพื่อดำเนินการต่อ ลบรูปโปรไฟล์ของคุณหรือไม่ @@ -834,7 +834,7 @@ มีการเข้าสู่ระบบไม่สำเร็จหลายครั้งเกินไป กรุณารอประมาณหนึ่งชั่วโมง - This account has not been validated yet. Check your email inbox. + ตรวจสอบกล่องจดหมายอีเมลของคุณและไปที่ลิงก์เพื่อยืนยันการเปิดบัญชีของคุณ ลิงก์โฟลเดอร์ยังไม่พร้อมใช้งาน @@ -848,7 +848,7 @@ กำลังรอการยืนยันทางอีเมล - Check your email inbox and follow the link to confirm your account. + ตรวจสอบกล่องจดหมายอีเมลของคุณและไปที่ลิงก์เพื่อยืนยันการเปิดบัญชีของคุณ %1$d รายการ @@ -2011,8 +2011,7 @@ เพิ่มเติม - Choose file - Choose files + เลือกไฟล์ เลือกโฟลเดอร์ @@ -2271,7 +2270,7 @@ เปิดใช้งานการโทร - Allow access to your address book + อนุญาตให้เข้าถึงสมุดรายชื่อของคุณ ค้นหารายชื่อจากสมุดรายชื่อของคุณได้อย่างง่ายดายบน MEGA @@ -3299,7 +3298,7 @@ คุณมีการสมัครใช้งานอยู่แล้ว หากคุณซื้ออีกรายการหนึ่ง คุณจะถูกเรียกเก็บเงินสองครั้ง เพื่อหลีกเลี่ยงปัญหานี้ ให้ยกเลิกการสมัครใช้งานปัจจุบันของคุณโดยไปที่ MEGA ในเบราว์เซอร์เดสก์ท็อปหรือมือถือ เยี่ยมชมศูนย์ช่วยเหลือของเราเพื่อศึกษาข้อมูลเพิ่มเติม - Go to Settings to allow MEGA permission to access your nearby devices using Bluetooth. + ไปที่การตั้งค่าเพื่ออนุญาตให้ MEGA เข้าถึงอุปกรณ์ใกล้เคียงของคุณผ่านบลูทูธ เราไม่สามารถดำเนินการเรียกเก็บเงินได้ หากคุณกำลังใช้แอปที่ติดตั้งแบบซ้ำกันอยู่ กรุณาพิจารณาลงชื่อเข้าใช้ MEGA โดยไม่ใช้แอปนี้ หากไม่เป็นเช่นนั้น ให้ลองอัปเกรดผ่านเว็บเบราว์เซอร์ของคุณแทน @@ -3651,7 +3650,7 @@ นี่คือที่จัดเก็บไฟล์และโฟลเดอร์สำหรับสำรองข้อมูล รายการที่สำรองไว้ของคุณเป็นแบบ “อ่านอย่างเดียว” เพื่อป้องกันไม่ให้ถูกแก้ไขโดยไม่ได้ตั้งใจในไดรฟ์ระบบคลาวด์ของคุณ\nคุณสามารถสำรองข้อมูลไฟล์ต่าง ๆ ได้จากคอมพิวเตอร์ของคุณไปยัง MEGA โดยใช้แอปเดสก์ท็อปของเรา - Your MEGA account has been suspended due to repeated allegations of copyright infringements. This means you cannot access your account or data within it.\nCheck your email inbox for more information on how to file a counter-notice. + บัญชี MEGA ของคุณถูกระงับชั่วคราว เนื่องจากมีการร้องเรียนเรื่องการละเมิดลิขสิทธิ์ซ้ำหลายครั้ง หมายความว่าคุณไม่สามารถเข้าถึงบัญชีหรือข้อมูลใด ๆ ภายในบัญชีของคุณได้\nตรวจสอบกล่องจดหมายอีเมลของคุณเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการยื่นเรื่องโต้แย้ง บัญชีของคุณถูกยุติการใช้งานเนื่องจากละเมิดเงื่อนไขการให้บริการของ MEGA\nคุณจะไม่สามารถเข้าถึงข้อมูลที่เก็บไว้หรือลงทะเบียนบัญชี MEGA ใหม่ได้อีกต่อไป @@ -3777,7 +3776,7 @@ นำออกจากอัลบั้มหรือไม่ - To enable camera uploads, allow MEGA access to your photos and other media on your device. + หากต้องการเปิดใช้งานการอัปโหลดจากกล้อง ต้องอนุญาตให้ MEGA เข้าถึงรูปภาพและสื่ออื่น ๆ บนอุปกรณ์ของคุณ อนุญาตให้เข้าถึง @@ -4761,7 +4760,7 @@ แอปได้รับการอัปเดตแล้ว - Relaunch the app + เริ่มต้นการทำงานแอปใหม่ อนุญาตให้เข้าถึงไฟล์เสียง @@ -4877,15 +4876,15 @@ รับสิทธิประโยชน์เพิ่มเติมด้วยการอัปเกรดเป็นแผน Pro - Upgrade to a Pro plan and get more storage and access to Pro features. Plans start from as low as %1$s a month. + อัปเกรดเป็นแผน Pro เพิ่มพื้นที่เก็บข้อมูลและเข้าถึงฟีเจอร์ Pro เริ่มต้นเพียง %1$s ต่อเดือน MEGA Pro plans include: - Ultimate storage flexibility + เก็บข้อมูลได้อย่างจุใจ Starting from %1$s, find the perfect fit for your storage needs. - Upgrade to Pro today + อัปเกรดเป็นแผน Pro วันนี้เลย %1$s กำลังนำเสนออยู่ @@ -5147,7 +5146,7 @@ Report your issue - Show hidden items + แสดงรายการที่ถูกซ่อนไว้ All hidden items will be visible, but blurred to indicate their “hidden” status diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1e9244487f..21333e8670 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -834,7 +834,7 @@ Đăng nhập sai quá nhiều lần, xin chờ một tiếng đồng hồ rồi thử lại. - This account has not been validated yet. Check your email inbox. + Kiểm tra hộp thư email của bạn và đi theo đường liên kết để xác nhận tài khoản của bạn. Liên kết thư mục bất khả dụng @@ -848,7 +848,7 @@ Đang chờ xác nhận địa chỉ e-mail - Check your email inbox and follow the link to confirm your account. + Kiểm tra hộp thư email của bạn và đi theo đường liên kết để xác nhận tài khoản của bạn. %1$d mục @@ -4880,7 +4880,7 @@ Các gói MEGA Pro có bao gồm: - Ultimate storage flexibility + Tính linh hoạt không gian tối ưu Starting from %1$s, find the perfect fit for your storage needs. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2163b57560..b9cea15ba7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -834,7 +834,7 @@ 尝试登录次数过多,请一小时后再试。 - 此帐户尚未通过验证。检查您的电子邮件收件箱。 + 查看您的电子邮件收件箱并跟随链接确认您的帐户。 文件夹链接不可用 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 6e0586f7c7..9680e18f47 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -834,7 +834,7 @@ 嘗試登入失敗的次數太多,請稍候一個小時後再試。 - 此帳戶尚未通過驗證。請檢查您的電子郵件收件匣。 + 檢查您的電子郵件收件匣,並點選連結以確認您的帳戶。 資料夾連結無法使用 diff --git a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml index 9e4ee67080..6cc4300f48 100644 --- a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml @@ -59,7 +59,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA не может синхронизировать эту папку или сделать резервную копию, потому что файловая система на вашем устройстве не поддерживается Выбранную папку невозможно синхронизировать @@ -73,13 +73,13 @@ Невозможно синхронизировать или создать резервную копию этой папки, так как срок действия вашего плана истёк - Folder can’t be synced as the user who shared this folder has reached their storage quota + Невозможно синхронизировать папку, так как у пользователя, который поделился ей, хранилище полностью заполнено Не удалось найти папку в MEGA, так как она была перемещена или удалена, либо у вас нет доступа. - Folder can’t be synced as it’s a shared folder without full access + Папку нельзя синхронизировать, так как это общая папка без полного доступа - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. Папку нельзя синхронизировать, так как она уже содержит синхронизируемые папки @@ -87,17 +87,17 @@ Невозможно синхронизировать или создать резервную копию этой папки, так как аккаунт заблокирован - Problem syncing or backing up this folder. Try again later. If the issue continues, contact support. + Проблема с синхронизацией или резервным копированием этой папки. Повторите попытку позже. Если проблема не исчезнет, обратитесь в поддержку. Аккаунт перезагружен. Любые пропущенные обновления ваших резервных копий или синхронизаций не были применены. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Синхронизация или резервное копирование остановлены, поскольку вы, похоже, вышли из настольного приложения. Снова войдите в систему в настольном приложении и возобновите синхронизацию или резервное копирование. N/A Не удаётся найти папку на внешнем диске. - There’s already a synced folder at the same path + По тому же пути уже есть синхронизируемая папка Не удалось переименовать. @@ -105,7 +105,7 @@ Не удалось прочитать конфигурацию синхронизации. Повторите попытку позже или проверьте права доступа к папке. - Sync folder location is unknown + Расположение папки синхронизации неизвестно Недействительный интервал сканирования. Проверьте настройку интервала сканирования и попробуйте ещё раз. @@ -125,17 +125,17 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Папку невозможно синхронизировать или создать её резервную копию, так как папка MEGA находится в Корзине Не удалось найти папку на вашем устройстве. Повторите попытку позже. Не удалось найти папку на вашем устройстве - Problem syncing or backing up this folder because of changes to the MEGA folder. Stop the sync or backup and try setting it up again in the desktop app, or contact support. + Проблема с синхронизацией или резервным копированием этой папки из-за изменений в папке MEGA. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. Проблема с синхронизацией или резервным копированием этой папки. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. - Folder can’t be synced as it’s already inside a synced folder + Папку нельзя синхронизировать, так как она уже находится внутри синхронизируемой папки Загрузки из камеры отключены @@ -157,7 +157,7 @@ Нет подключения к Интернету - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. Пока ничего не настроено diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 16f79f3aa7..9192fa6b9d 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -137,7 +137,7 @@ لا يمكن النقل أو إعادة التسمية - الحذف أو الانتقال أثناء انتظار الفحص + Delete or move action is waiting for scan لا يمكن الحذف بعد diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index df85314757..facff0eb32 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -121,7 +121,7 @@ Verschieben oder Umbenennen nicht möglich - Löschen oder Verschieben während des Scanvorgangs + Delete or move action is waiting for scan Löschen noch nicht möglich diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index a78f76d70f..77761c833a 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -125,7 +125,7 @@ No se puede mover ni renombrar - Operación de mover o eliminar en espera + La acción de eliminar o mover está a la espera de ser analizada No se puede eliminar todavía diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index 566fbfe2fc..ea5a53875e 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -117,7 +117,7 @@ Can’t move or rename - Deletion or move waiting on scanning + Delete or move action is waiting for scan Can’t delete yet diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index bf7c1b15a1..1ee7a8caed 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -125,7 +125,7 @@ Impossibile spostare o rinominare - Eliminazione o spostamento in attesa della scansione + Delete or move action is waiting for scan Impossibile eliminare ora diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index 8105c7f27d..f7652444d2 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -117,7 +117,7 @@ 移動や名前変更ができません - スキャン待ちの削除または移動 + 削除または移動アクションはスキャン待ちです まだ削除できません diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 6dc0918f9a..79925bc3da 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -117,7 +117,7 @@ 이동 또는 이름 변경을 할 수 없습니다 - 스캔을 기다리던 중 삭제 또는 이동 + Delete or move action is waiting for scan 아직 삭제할 수 없음 diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index bd8256ccef..3264c2fd4b 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -9,7 +9,7 @@ Synchronisaties [A](%1$d)[/A] - MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. + MEGA heeft toegang nodig tot de opslag van uw apparaat om uw lokale map te kunnen synchroniseren. Tik hier om toegang toe te staan. Als u uw bestanden en mappen continu wilt synchroniseren, moet u MEGA op de achtergrond laten draaien @@ -121,7 +121,7 @@ Kan niet verplaatsen of hernoemen - Verwijdering of verplaatsing in wacht terwijl u scant + De verijderen of verplaatsen actie wacht op een scan Kan niet verwijderen @@ -161,7 +161,7 @@ Selecteer - An item has an issue that needs your decision to resolve it + Er is een probleem met een item waarvoor u een beslissing moet nemen om het op te lossen Wachten tot andere processen zijn voltooid @@ -185,7 +185,7 @@ Er is een actie voor het verplaatsen of hernoemen van de naam gedetecteerd in MEGA, maar deze kon niet lokaal worden gerepliceerd. - A move or rename action was detected locally, but couldn’t be replicated in MEGA. + Er is lokaal een actie voor het verplaatsen of hernoemen van de naam gedetecteerd, maar deze kon niet worden gerepliceerd in MEGA. Wacht tot de scan is voltooid om te bepalen of het bestand is verplaatst of verwijderd. diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index b0063fd630..625288c09a 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -129,7 +129,7 @@ Nie można przenieść ani zmienić nazwy - Usuwanie lub przeniesienie w oczekiwaniu na skanowanie + Delete or move action is waiting for scan Nie można jeszcze usunąć diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index e5bc6e4472..1070132a54 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -125,7 +125,7 @@ Não é possível mover ou renomear - Eliminação ou o movimento pendente de análise + A ação para deletar ou mover está aguardando o escaneio Ainda não é possível deletar diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index 5e02320999..572700afd4 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -129,7 +129,7 @@ Невозможно переместить или переименовать - Поиск ожидающих операций удаления или перемещения + Delete or move action is waiting for scan Пока нельзя удалить @@ -191,9 +191,9 @@ На одной стороне синхронизации есть несколько элементов с одинаковым названием, которые на другой стороне синхронизации станут одним и тем же элементом - A move or rename action was detected in MEGA, but couldn’t be replicated locally. + В MEGA обнаружена операция перемещения или переименования, но её не удалось воспроизвести локально. - A move or rename action was detected locally, but couldn’t be replicated in MEGA. + Обнаружена локальная операция перемещения или переименования, но её не удалось воспроизвести в MEGA. Ожидание завершения сканирования, чтобы определить, был ли файл перемещён или удалён. diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index 1c1ea62958..048e9ece57 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -117,7 +117,7 @@ ไม่สามารถย้ายหรือเปลี่ยนชื่อได้ - การลบหรือย้ายไฟล์ค้างอยู่ที่ขั้นตอนการสแกน + Delete or move action is waiting for scan ยังไม่สามารถลบได้ diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index eb03e8c16d..a3b0ebd545 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -117,7 +117,7 @@ Không thể di chuyển hoặc đổi tên - Việc xóa hoặc di chuyển đang chờ việc quét được hoàn tất + Delete or move action is waiting for scan Chưa thể xóa diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index ca808ad7bb..0bf86af23b 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -117,7 +117,7 @@ 无法移动或重命名 - 等待删除或移动的扫描中 + Delete or move action is waiting for scan 还无法删除 diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 0d7f9dd63b..676a2993ec 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -117,7 +117,7 @@ 無法移動或重新命名 - 等待刪除或移動的掃描中 + Delete or move action is waiting for scan 還無法刪除 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 876795cfa0..c8f7a8de45 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -224,4 +224,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + محدود + + مجاني + + تابع + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index df755702ee..b6539cc081 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -216,4 +216,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + Begrenzt + + Free + + Fortfahren + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index ced7cbbf86..07c9003b10 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -165,7 +165,7 @@ More than 20 minutes - Enter playlist name + Introducir el nombre de la lista de reproducción Renombrar @@ -217,4 +217,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + Limitado + + Gratis + + Continuar + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 889f99f596..300098e7ce 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -220,4 +220,16 @@ Ne téléverser que pendant la charge Ajouter un dossier synchronisé : + + %1$s GB + + Free + + Limité + + Gratuit + + Poursuivre + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index e3670b2365..649c2b6842 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -215,4 +215,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + Terbatas + + Gratis + + Lanjutkan + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 27c278eb3e..12c64d7c1a 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -220,4 +220,16 @@ Carica solo durante la ricarica Aggiungi cartella sincronizzata: + + %1$s GB + + Free + + Limitata + + Gratis + + Continua + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 8b726f187c..abc9ab98cf 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -212,4 +212,16 @@ 充電中のみアップロード 同期フォルダを追加: + + %1$s GB + + Free + + 制限付き + + 無料 + + 続ける + + MEGAプランのご選択 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index d8eabc2b1f..c9a9feabbd 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -212,4 +212,16 @@ 충전 중일 때만 업로드 동기화된 폴더 추가: + + %1$s GB + + Free + + 제한됨 + + 무료 + + 계속 + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 93c1ec89ed..e74743a40f 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -190,8 +190,8 @@ Kies bestanden - Deleted %1$d playlist - Deleted %1$d playlists + %1$d afspeellijst verwijderd + %1$d afspeellijsten verwijderd @@ -213,7 +213,19 @@ “%1$s” verwijderd - Upload only while charging + Alleen uploaden tijdens het opladen - Add synchronised folder: + Gesynchroniseerde map toevoegen: + + %1$s  GB + + Free + + Beperkt + + Gratis + + Doorgaan + + Kies je MEGA-abonnement \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index ecffdb9ad0..a414915f09 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -216,4 +216,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + Ograniczony + + Darmowe + + Kontynuuj + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index c30bcf519d..f871a0052f 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -220,4 +220,16 @@ Somente fazer upload quando estiver carregando Adicionar pasta sincronizada: + + %1$s GB + + Free + + Limitado + + Grátis + + Continuar + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 1387b34631..ffc8f814fd 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -220,4 +220,16 @@ Încărcați doar când dispozitivul se încarcă Adăugați folder sincronizat: + + %1$s GB + + Free + + Limitat + + Gratuit + + Continuă + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 7e7a07a638..a2527c9381 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA can’t sync or backup this folder because the file system on your device is not supported + MEGA не может синхронизировать эту папку или сделать резервную копию, потому что файловая система на вашем устройстве не поддерживается Выбранную папку невозможно синхронизировать @@ -23,7 +23,7 @@ Невозможно синхронизировать папку, так как это общая папка, к которой у вас нет полного доступа - Files in this folder can’t be synced or backed up. You’ll need to re-enable the sync or backup from the desktop app. + Файлы в этой папке невозможно синхронизировать или создать их резервные копии. Вам нужно снова включить синхронизацию или резервное копирование из настольного приложения. Папку нельзя синхронизировать, так как она уже содержит синхронизируемые папки @@ -35,7 +35,7 @@ Аккаунт перезагружен. Любые пропущенные обновления ваших резервных копий или синхронизаций не были применены. - Sync or backup has been stopped as you appear to have logged out of the desktop app. Log back in via the desktop app, and resume the sync or backup. + Синхронизация или резервное копирование остановлены, поскольку вы, похоже, вышли из настольного приложения. Снова войдите в систему в настольном приложении и возобновите синхронизацию или резервное копирование. N/A @@ -43,7 +43,7 @@ В том же расположении уже есть синхронизируемая папка - Renaming failed + Не удалось переименовать Не удалось создать файл .megaignore для этой синхронизации @@ -69,7 +69,7 @@ Something went wrong. - Folder can’t be synced or backed up as the MEGA folder is in the Rubbish bin + Папку невозможно синхронизировать или создать её резервную копию, так как папка MEGA находится в Корзине Не удалось найти папку на вашем устройстве в данный момент. Повторите попытку позже. @@ -79,9 +79,9 @@ Проблема с синхронизацией или резервным копированием этой папки. Остановите синхронизацию или резервное копирование и попробуйте настроить их снова в настольном приложении или обратитесь в поддержку. - Folder can’t be synced as it’s already inside a synced folder + Папку нельзя синхронизировать, так как она уже находится внутри синхронизируемой папки - Files in this folder can’t be synced or backed up. You will need to re-enable the sync or backup from the desktop app. + Файлы в этой папке невозможно синхронизировать или создать их резервную копию. Вам нужно будет повторно включить синхронизацию или резервное копирование из настольного приложения. Syncing paused, battery level too low. Charge battery to resume syncing. @@ -187,7 +187,7 @@ Нет видео - Choose files + Выберите файлы Deleted %1$d playlist @@ -218,4 +218,16 @@ Upload only while charging Add synchronised folder: + + %1$s ГБ + + Free + + Ограничено + + Бесплатный + + Продолжить + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index bfbf515cfb..8a98c3fa59 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -85,13 +85,13 @@ Syncing paused, battery level too low. Charge battery to resume syncing. - Easy, secure file sharing + แชร์ไฟล์ได้ง่าย ปลอดภัย ไร้กังวล - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + แชร์ไฟล์ใหญ่ ๆ สบายใจด้วยโควต้าการโอนถ่ายที่จุใจ พร้อมทั้งมั่นใจในความปลอดภัยด้วยลิงก์ที่ป้องกันด้วยรหัสผ่าน - Never lose data again + ไม่มีพลาดทุกข้อมูลสำคัญของคุณ - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + สำรองและซิงค์ข้อมูลของคุณเพื่อความมั่นใจสูงสุด เพิ่มเติมด้วยฟีเจอร์ย้อนกลับ ที่ช่วยให้คุณกู้คืนโฟลเดอร์กลับไปยังวันที่ต้องการได้สูงสุด 180 วัน MEGA VPN @@ -99,7 +99,7 @@ โทรและประชุมได้ไม่จำกัด - Message, video call, and meet in total privacy with unlimited participants. + สื่อสารแบบส่วนตัว ปลอดภัยไร้กังวล กับข้อความ วิดีโอคอล และการประชุม รองรับผู้เข้าร่วมได้ไม่จำกัด ประเภท @@ -165,7 +165,7 @@ More than 20 minutes - Enter playlist name + กรอกชื่อเพลย์ลิสต์ เปลี่ยนชื่อ @@ -187,7 +187,7 @@ ไม่มีวิดีโอ - Choose files + เลือกไฟล์ Deleted %1$d playlist @@ -215,4 +215,16 @@ Upload only while charging Add synchronised folder: + + %1$s GB + + Free + + ถูกจำกัด + + ฟรี + + ดำเนินการต่อ + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index f2ea631054..16c9f4950e 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -85,13 +85,13 @@ Syncing paused, battery level too low. Charge battery to resume syncing. - Easy, secure file sharing + Chia sẻ tệp tin dễ dàng và an toàn - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + Chia sẻ các tệp tin lớn nhờ băng thông truyền tải hào phóng và đảm bảo bảo mật với các đường liên kết được bảo vệ bằng mật khẩu. - Never lose data again + Không bao giờ mất dữ liệu nữa - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Sao lưu và đồng bộ hóa dữ liệu để bạn hoàn toàn tự tin. Ngoài ra, sử dụng Tua lại để khôi phục các thư mục về bất kỳ ngày nào trong phạm vi 180 ngày. MEGA VPN @@ -99,7 +99,7 @@ Cuộc gọi và cuộc họp không hạn chế - Message, video call, and meet in total privacy with unlimited participants. + Nhắn tin, gọi video và họp hoàn toàn riêng tư với số lượng người tham gia không giới hạn. Dạng @@ -165,7 +165,7 @@ More than 20 minutes - Enter playlist name + Đặt tên danh sách phát Đổi tên @@ -215,4 +215,16 @@ Upload only while charging Thêm thư mục đồng bộ hóa: + + %1$s GB + + Free + + Bị giới hạn + + Miễn phí + + Tiếp tục + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 6e8c84eacc..40feb4d6b0 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -212,4 +212,16 @@ 仅在充电时上传 Add synchronised folder: + + %1$s GB + + Free + + 限制 + + 免费 + + 继续 + + Choose your MEGA plan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 2fb5df36a6..1d9467b4a0 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -212,4 +212,16 @@ 僅在充電時上傳 新增同步資料夾: + + %1$s GB + + Free + + 有限制的 + + 免費 + + 繼續 + + Choose your MEGA plan \ No newline at end of file From 25591d8705ab27460f115a1ff7ade30cd33adef0 Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Wed, 1 May 2024 14:08:27 +0600 Subject: [PATCH 107/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index e6d795c0c8..9768f88875 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -71,7 +71,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240430.075836" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 441dbcdb36b6d010d2b7d1e869d23ccb118c8d2f Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Thu, 2 May 2024 21:59:22 +1200 Subject: [PATCH 108/261] SAO-265: Fix issue with multi selection in backups --- .../app/main/adapters/MegaNodeAdapter.java | 18 ++++-- .../NodeAttachmentHistoryAdapter.java | 59 ++++++++++--------- .../presentation/backups/BackupsFragment.kt | 2 + app/src/main/res/layout/item_file_grid.xml | 18 +++--- 4 files changed, 55 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java b/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java index c69a03e907..6c10ee539d 100644 --- a/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java +++ b/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java @@ -53,6 +53,7 @@ import android.view.animation.AnimationUtils; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.TextView; @@ -201,7 +202,7 @@ public ViewHolderBrowserGrid(View v) { public ImageButton imageButtonThreeDotsForFile; public TextView textViewFileNameForFile; public ImageView takenDownImageForFile; - public ImageView fileGridSelected; + public RadioButton fileGridSelected; } public class ViewHolderSortBy extends ViewHolderBrowser { @@ -758,7 +759,7 @@ public ViewHolderBrowser onCreateViewHolder(ViewGroup parent, int viewType) { holderGrid.imageViewVideoIcon = v.findViewById(R.id.file_grid_video_icon); holderGrid.videoDuration = v.findViewById(R.id.file_grid_title_video_duration); holderGrid.videoInfoLayout = v.findViewById(R.id.item_file_videoinfo_layout); - holderGrid.fileGridSelected = v.findViewById(R.id.file_grid_selected); + holderGrid.fileGridSelected = v.findViewById(R.id.file_grid_radio_button); holderGrid.bottomContainer = v.findViewById(R.id.grid_bottom_container); holderGrid.bottomContainer.setTag(holderGrid); holderGrid.bottomContainer.setOnClickListener(this); @@ -917,13 +918,20 @@ public void onBindViewHolderGrid(ViewHolderBrowserGrid holder, int position) { } } + if (isMultipleSelect()) { + holder.imageButtonThreeDotsForFile.setVisibility(View.GONE); + holder.fileGridSelected.setVisibility(View.VISIBLE); + } else { + holder.imageButtonThreeDotsForFile.setVisibility(View.VISIBLE); + holder.fileGridSelected.setVisibility(View.GONE); + } + if (isMultipleSelect() && isItemChecked(position)) { + holder.fileGridSelected.setChecked(true); holder.itemLayout.setBackground(ContextCompat.getDrawable(context, R.drawable.background_item_grid_selected)); - holder.fileGridSelected.setImageResource(mega.privacy.android.core.R.drawable.ic_select_folder); - } else { + holder.fileGridSelected.setChecked(false); holder.itemLayout.setBackground(ContextCompat.getDrawable(context, R.drawable.background_item_grid)); - holder.fileGridSelected.setImageDrawable(new ColorDrawable(Color.TRANSPARENT)); } } } diff --git a/app/src/main/java/mega/privacy/android/app/main/megachat/chatAdapters/NodeAttachmentHistoryAdapter.java b/app/src/main/java/mega/privacy/android/app/main/megachat/chatAdapters/NodeAttachmentHistoryAdapter.java index ca73c23ec6..10fa01886f 100644 --- a/app/src/main/java/mega/privacy/android/app/main/megachat/chatAdapters/NodeAttachmentHistoryAdapter.java +++ b/app/src/main/java/mega/privacy/android/app/main/megachat/chatAdapters/NodeAttachmentHistoryAdapter.java @@ -27,6 +27,7 @@ import android.view.animation.AnimationUtils; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.TextView; @@ -123,7 +124,7 @@ public ViewHolderBrowserGrid(View v) { public ImageView fileGridIconForFile; public ImageButton imageButtonThreeDotsForFile; public TextView textViewFileNameForFile; - public ImageView fileGridSelected; + public RadioButton fileGridSelected; } public void toggleAllSelection(int pos) { @@ -281,7 +282,7 @@ public ArrayList getSelectedMessages() { ArrayList messages = new ArrayList(); for (int i = 0; i < selectedItems.size(); i++) { - if (selectedItems.valueAt(i) == true) { + if (selectedItems.valueAt(i)) { MegaChatMessage message = getMessageAt(selectedItems.keyAt(i)); if (message != null) { messages.add(message); @@ -334,15 +335,15 @@ public NodeAttachmentHistoryAdapter.ViewHolderBrowser onCreateViewHolder(ViewGro View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_file_list, parent, false); ViewHolderBrowserList holderList = new ViewHolderBrowserList(v); - holderList.itemLayout = (RelativeLayout) v.findViewById(R.id.file_list_item_layout); - holderList.imageView = (ImageView) v.findViewById(R.id.file_list_thumbnail); - holderList.savedOffline = (ImageView) v.findViewById(R.id.file_list_saved_offline); - holderList.publicLinkImage = (ImageView) v.findViewById(R.id.file_list_public_link); - holderList.textViewFileName = (TextView) v.findViewById(R.id.file_list_filename); + holderList.itemLayout = v.findViewById(R.id.file_list_item_layout); + holderList.imageView = v.findViewById(R.id.file_list_thumbnail); + holderList.savedOffline = v.findViewById(R.id.file_list_saved_offline); + holderList.publicLinkImage = v.findViewById(R.id.file_list_public_link); + holderList.textViewFileName = v.findViewById(R.id.file_list_filename); holderList.textViewMessageInfo = v.findViewById(R.id.file_list_filesize); - holderList.threeDotsLayout = (RelativeLayout) v.findViewById(R.id.file_list_three_dots_layout); - holderList.threeDotsImageView = (ImageView) v.findViewById(R.id.file_list_three_dots); - holderList.versionsIcon = (ImageView) v.findViewById(R.id.file_list_versions_icon); + holderList.threeDotsLayout = v.findViewById(R.id.file_list_three_dots_layout); + holderList.threeDotsImageView = v.findViewById(R.id.file_list_three_dots); + holderList.versionsIcon = v.findViewById(R.id.file_list_versions_icon); holderList.textViewMessageInfo.setVisibility(View.VISIBLE); RelativeLayout.LayoutParams paramsThreeDotsIcon = (RelativeLayout.LayoutParams) holderList.threeDotsImageView.getLayoutParams(); @@ -377,21 +378,21 @@ public NodeAttachmentHistoryAdapter.ViewHolderBrowser onCreateViewHolder(ViewGro NodeAttachmentHistoryAdapter.ViewHolderBrowserGrid holderGrid = new NodeAttachmentHistoryAdapter.ViewHolderBrowserGrid(v); holderGrid.fileLayout = v.findViewById(R.id.item_file_grid_file); - holderGrid.itemLayout = (RelativeLayout) v.findViewById(R.id.file_grid_item_layout); - holderGrid.imageViewThumb = (ImageView) v.findViewById(R.id.file_grid_thumbnail); - holderGrid.imageViewIcon = (ImageView) v.findViewById(R.id.file_grid_icon); - holderGrid.fileGridIconForFile = (ImageView) v.findViewById(R.id.file_grid_icon_for_file); - holderGrid.thumbLayout = (RelativeLayout) v.findViewById(R.id.file_grid_thumbnail_layout); - holderGrid.thumbLayoutForFile = (RelativeLayout) v.findViewById(R.id.file_grid_thumbnail_layout_for_file); - holderGrid.textViewFileName = (TextView) v.findViewById(R.id.file_grid_filename); - holderGrid.textViewFileNameForFile = (TextView) v.findViewById(R.id.file_grid_filename_for_file); - holderGrid.imageButtonThreeDotsForFile = (ImageButton) v.findViewById(R.id.file_grid_three_dots_for_file); - holderGrid.imageButtonThreeDots = (ImageButton) v.findViewById(R.id.file_grid_three_dots); - - holderGrid.imageViewVideoIcon = (ImageView) v.findViewById(R.id.file_grid_video_icon); - holderGrid.videoDuration = (TextView) v.findViewById(R.id.file_grid_title_video_duration); - holderGrid.videoInfoLayout = (RelativeLayout) v.findViewById(R.id.item_file_videoinfo_layout); - holderGrid.fileGridSelected = (ImageView) v.findViewById(R.id.file_grid_selected); + holderGrid.itemLayout = v.findViewById(R.id.file_grid_item_layout); + holderGrid.imageViewThumb = v.findViewById(R.id.file_grid_thumbnail); + holderGrid.imageViewIcon = v.findViewById(R.id.file_grid_icon); + holderGrid.fileGridIconForFile = v.findViewById(R.id.file_grid_icon_for_file); + holderGrid.thumbLayout = v.findViewById(R.id.file_grid_thumbnail_layout); + holderGrid.thumbLayoutForFile = v.findViewById(R.id.file_grid_thumbnail_layout_for_file); + holderGrid.textViewFileName = v.findViewById(R.id.file_grid_filename); + holderGrid.textViewFileNameForFile = v.findViewById(R.id.file_grid_filename_for_file); + holderGrid.imageButtonThreeDotsForFile = v.findViewById(R.id.file_grid_three_dots_for_file); + holderGrid.imageButtonThreeDots = v.findViewById(R.id.file_grid_three_dots); + + holderGrid.imageViewVideoIcon = v.findViewById(R.id.file_grid_video_icon); + holderGrid.videoDuration = v.findViewById(R.id.file_grid_title_video_duration); + holderGrid.videoInfoLayout = v.findViewById(R.id.item_file_videoinfo_layout); + holderGrid.fileGridSelected = v.findViewById(R.id.file_grid_radio_button); holderGrid.itemLayout.setTag(holderGrid); holderGrid.itemLayout.setOnClickListener(this); @@ -588,6 +589,8 @@ public void onBindViewHolderList(ViewHolderBrowserList holder, int position) { holder.textViewMessageInfo.setVisibility(View.VISIBLE); if (!multipleSelect) { + holder.threeDotsLayout.setVisibility(View.VISIBLE); + holder.threeDotsLayout.setOnClickListener(this); Timber.d("Not multiselect"); holder.itemLayout.setBackground(null); holder.imageView.setImageResource(MimeTypeList.typeForName(node.getName()).getIconResourceId()); @@ -608,6 +611,8 @@ public void onBindViewHolderList(ViewHolderBrowserList holder, int position) { getThumbAndSetViewOrCreate(holder, node); } } else { + holder.threeDotsLayout.setOnClickListener(null); + holder.threeDotsLayout.setVisibility(View.GONE); Timber.d("Multiselection ON"); if (this.isItemChecked(position)) { RelativeLayout.LayoutParams paramsMultiselect = (RelativeLayout.LayoutParams) holder.imageView.getLayoutParams(); @@ -695,9 +700,9 @@ public void onClick(View v) { int[] screenPosition = new int[2]; ImageView imageView; if (adapterType == NodeAttachmentHistoryAdapter.ITEM_VIEW_TYPE_LIST) { - imageView = (ImageView) v.findViewById(R.id.file_list_thumbnail); + imageView = v.findViewById(R.id.file_list_thumbnail); } else { - imageView = (ImageView) v.findViewById(R.id.file_grid_thumbnail); + imageView = v.findViewById(R.id.file_grid_thumbnail); } imageView.getLocationOnScreen(screenPosition); diff --git a/app/src/main/java/mega/privacy/android/app/presentation/backups/BackupsFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/backups/BackupsFragment.kt index 5035f3027d..bdb9e88a5e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/backups/BackupsFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/backups/BackupsFragment.kt @@ -180,6 +180,7 @@ class BackupsFragment : RotatableFragment() { override fun activateActionMode() { Timber.d("activateActionMode()") megaNodeAdapter?.let { + it.notifyDataSetChanged() if (!it.isMultipleSelect) { it.isMultipleSelect = true actionMode = (requireActivity() as AppCompatActivity).startSupportActionMode( @@ -296,6 +297,7 @@ class BackupsFragment : RotatableFragment() { override fun onDestroyActionMode(arg0: ActionMode) { Timber.d("onDestroyActionMode()") clearSelections() + megaNodeAdapter?.notifyDataSetChanged() megaNodeAdapter?.isMultipleSelect = false checkScroll() } diff --git a/app/src/main/res/layout/item_file_grid.xml b/app/src/main/res/layout/item_file_grid.xml index 4633997b72..6d6171052e 100644 --- a/app/src/main/res/layout/item_file_grid.xml +++ b/app/src/main/res/layout/item_file_grid.xml @@ -85,16 +85,6 @@ android:scaleType="fitXY" tools:ignore="ContentDescription" /> - - + + \ No newline at end of file From bdad749af71e6b9b1e34ecac3c4dcaa724fe9d14 Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Thu, 2 May 2024 16:12:25 +0530 Subject: [PATCH 109/261] SAO-265: Fix issue with node attachment history activity --- .../app/main/megachat/NodeAttachmentHistoryActivity.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/megachat/NodeAttachmentHistoryActivity.java b/app/src/main/java/mega/privacy/android/app/main/megachat/NodeAttachmentHistoryActivity.java index 0cdf02ef5a..13e92ad57a 100644 --- a/app/src/main/java/mega/privacy/android/app/main/megachat/NodeAttachmentHistoryActivity.java +++ b/app/src/main/java/mega/privacy/android/app/main/megachat/NodeAttachmentHistoryActivity.java @@ -111,7 +111,6 @@ import mega.privacy.android.app.utils.MegaProgressDialogUtil; import mega.privacy.android.app.utils.permission.PermissionUtils; import mega.privacy.android.domain.entity.StorageState; -import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase; import nz.mega.sdk.MegaApiAndroid; import nz.mega.sdk.MegaChatApi; import nz.mega.sdk.MegaChatApiJava; @@ -138,9 +137,6 @@ public class NodeAttachmentHistoryActivity extends PasscodeActivity implements @Inject CopyRequestMessageMapper copyRequestMessageMapper; - @Inject - GetFeatureFlagValueUseCase getFeatureFlagUseCase; - private NodeAttachmentHistoryViewModel viewModel; private StartDownloadViewModel startDownloadViewModel; @@ -480,6 +476,7 @@ public void activateActionMode() { Timber.d("activateActionMode"); if (!adapter.isMultipleSelect()) { adapter.setMultipleSelect(true); + adapter.notifyDataSetChanged(); actionMode = startSupportActionMode(new NodeAttachmentHistoryActivity.ActionBarCallBack()); } } @@ -895,6 +892,7 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) { public void onDestroyActionMode(ActionMode arg0) { Timber.d("onDestroyActionMode"); adapter.clearSelections(); + adapter.notifyDataSetChanged(); adapter.setMultipleSelect(false); checkScroll(); } From 29bcd476cd32ad2be431646aed4748130b001fdb Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Mon, 6 May 2024 10:50:09 +0530 Subject: [PATCH 110/261] SAO-265: text overlap with selection radio button issue fix --- .../app/main/adapters/MegaNodeAdapter.java | 4 ++- app/src/main/res/layout/item_file_grid.xml | 36 ++++++++++++------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java b/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java index 6c10ee539d..0d81a99852 100644 --- a/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java +++ b/app/src/main/java/mega/privacy/android/app/main/adapters/MegaNodeAdapter.java @@ -59,6 +59,7 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -192,7 +193,8 @@ public ViewHolderBrowserGrid(View v) { public RelativeLayout thumbLayout; public ImageView imageViewVideoIcon; public TextView videoDuration; - public RelativeLayout videoInfoLayout, bottomContainer; + public RelativeLayout videoInfoLayout; + public ConstraintLayout bottomContainer; public ImageButton imageButtonThreeDots; public View folderLayout; diff --git a/app/src/main/res/layout/item_file_grid.xml b/app/src/main/res/layout/item_file_grid.xml index 6d6171052e..6319602d49 100644 --- a/app/src/main/res/layout/item_file_grid.xml +++ b/app/src/main/res/layout/item_file_grid.xml @@ -130,7 +130,7 @@ android:layout_below="@+id/file_grid_thumbnail_layout_for_file" android:background="@color/grey_012_white_012" /> - + android:textSize="14sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/file_grid_taken_down_for_file" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + tools:ignore="ContentDescription" + tools:visibility="visible" /> @@ -176,7 +184,11 @@ android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" - android:visibility="gone"/> - + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible" /> + \ No newline at end of file From fc8b10f3b05bbd6d81bf2325866ee2c689415781 Mon Sep 17 00:00:00 2001 From: Yenel Date: Mon, 6 May 2024 13:35:44 +0200 Subject: [PATCH 111/261] Hotfix: T16078852 Join an active-meeting as guest --- .../meeting/CallRecordingViewModel.kt | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/CallRecordingViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/CallRecordingViewModel.kt index 66edf14495..68b1b206ad 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/CallRecordingViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/CallRecordingViewModel.kt @@ -7,6 +7,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -62,6 +63,10 @@ class CallRecordingViewModel @Inject constructor( * Sets chatId. */ fun setChatId(chatId: Long) { + if (chatId == this.chatId) { + return + } + this.chatId = chatId monitorCallSessionOnRecording(chatId) monitorCallInChat(chatId) @@ -73,40 +78,46 @@ class CallRecordingViewModel @Inject constructor( private fun monitorCallSessionOnRecording(chatId: Long) { monitorCallSessionOnRecordingJob?.cancel() monitorCallSessionOnRecordingJob = viewModelScope.launch { - monitorCallSessionOnRecordingUseCase(chatId).collectLatest { callRecordingEvent -> - callRecordingEvent?.let { - _state.update { state -> - state.copy(callRecordingEvent = callRecordingEvent) - } - if (!it.isSessionOnRecording) { - broadcastCallRecordingConsentEvent(null) + monitorCallSessionOnRecordingUseCase(chatId) + .catch { Timber.d(it) } + .collectLatest { callRecordingEvent -> + callRecordingEvent?.let { + _state.update { state -> + state.copy(callRecordingEvent = callRecordingEvent) + } + if (!it.isSessionOnRecording) { + broadcastCallRecordingConsentEvent(null) + } } } - } } } private fun monitorCallInChat(chatId: Long) { monitorCallInChatJob?.cancel() monitorCallInChatJob = viewModelScope.launch { - monitorCallInChatUseCase(chatId).collectLatest { call -> - _state.update { state -> - call?.let { - val isParticipatingInCall = call.status?.isJoined == true - val isRecording = call.sessionByClientId - .filter { it.value.isRecording }.isNotEmpty() + monitorCallInChatUseCase(chatId) + .catch { Timber.d(it) } + .collectLatest { call -> + _state.update { state -> + call?.let { + val isParticipatingInCall = call.status?.isJoined == true + val isRecording = call.sessionByClientId + .filter { it.value.isRecording }.isNotEmpty() - if (!isRecording || !isParticipatingInCall) { - broadcastCallRecordingConsentEvent(null) - } + if (!isRecording || !isParticipatingInCall) { + broadcastCallRecordingConsentEvent(null) + } - state.copy( - callRecordingEvent = state.callRecordingEvent.copy(isSessionOnRecording = isRecording), - isParticipatingInCall = isParticipatingInCall, - ) - } ?: CallRecordingUIState() + state.copy( + callRecordingEvent = state.callRecordingEvent.copy( + isSessionOnRecording = isRecording + ), + isParticipatingInCall = isParticipatingInCall, + ) + } ?: CallRecordingUIState() + } } - } } } From 46877ea476f5a84c82ed4887804d81796e9c4517 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Thu, 2 May 2024 09:39:17 +0200 Subject: [PATCH 112/261] AND-18714: Add missing tag in Location title in file info --- .../app/presentation/fileinfo/view/FileInfoViewConstants.kt | 1 + .../app/presentation/fileinfo/view/LocationInfoView.kt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoViewConstants.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoViewConstants.kt index 83cc057bf4..857e2c9c94 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoViewConstants.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoViewConstants.kt @@ -8,6 +8,7 @@ internal const val TEST_TAG_AVAILABLE_OFFLINE_SWITCH = "switch" internal const val TEST_TAG_CREATION_TIME = "creationTime" internal const val TEST_TAG_MODIFICATION_TIME = "modificationTime" internal const val TEST_TAG_VERSIONS_BUTTON = "versionsButton" +internal const val TEST_TAG_LOCATION_TITLE = "file_info:text_location_title" internal const val TEST_TAG_LOCATION = "location" internal const val TEST_SHARE_LINK_COPY = "shareLinkCopy" internal const val TEST_TAKE_TEXT = "takeDownText" diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt index 7a53c7a6f9..b6e66ad2b9 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import mega.privacy.android.app.R -import mega.privacy.android.shared.theme.MegaAppTheme import mega.privacy.android.core.ui.preview.CombinedTextAndThemePreviews import mega.privacy.android.core.ui.theme.extensions.subtitle2medium import mega.privacy.android.core.ui.theme.extensions.textColorPrimary +import mega.privacy.android.shared.theme.MegaAppTheme /** @@ -39,6 +39,8 @@ internal fun LocationInfoView( Text( text = stringResource(id = R.string.file_properties_info_location), style = MaterialTheme.typography.subtitle2medium.copy(color = MaterialTheme.colors.textColorPrimary), + modifier = Modifier + .testTag(TEST_TAG_LOCATION_TITLE) ) Text( text = location, From 41176d54926c0dba9e9f09878f70a9a65ebc8270 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Fri, 3 May 2024 11:13:24 +0200 Subject: [PATCH 113/261] AND-18714: Add missing tag in Location title in file info --- .../android/app/presentation/fileinfo/view/LocationInfoView.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt index b6e66ad2b9..f7ab9a1d64 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/LocationInfoView.kt @@ -40,6 +40,7 @@ internal fun LocationInfoView( text = stringResource(id = R.string.file_properties_info_location), style = MaterialTheme.typography.subtitle2medium.copy(color = MaterialTheme.colors.textColorPrimary), modifier = Modifier + .fillMaxWidth() .testTag(TEST_TAG_LOCATION_TITLE) ) Text( From 9736c4b4571f512fbe710c1c38ef1f28339ce3b7 Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Tue, 7 May 2024 20:49:01 +1200 Subject: [PATCH 114/261] Pre-release v13.1 --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-in/strings.xml | 10 +++---- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-th/strings.xml | 4 +-- app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- .../strings_device_center_feature.xml | 2 +- .../res/values-ko/strings_sync_feature.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 14 +++++++--- .../src/main/res/values-de/strings_shared.xml | 22 +++++++++++----- .../src/main/res/values-es/strings_shared.xml | 12 +++++++-- .../src/main/res/values-fr/strings_shared.xml | 10 ++++++- .../src/main/res/values-in/strings_shared.xml | 14 +++++++--- .../src/main/res/values-it/strings_shared.xml | 22 +++++++++++----- .../src/main/res/values-ja/strings_shared.xml | 12 +++++++-- .../src/main/res/values-ko/strings_shared.xml | 26 ++++++++++++------- .../src/main/res/values-nl/strings_shared.xml | 16 +++++++++--- .../src/main/res/values-pl/strings_shared.xml | 16 +++++++++--- .../src/main/res/values-pt/strings_shared.xml | 14 +++++++--- .../src/main/res/values-ro/strings_shared.xml | 10 ++++++- .../src/main/res/values-ru/strings_shared.xml | 12 +++++++-- .../src/main/res/values-th/strings_shared.xml | 18 +++++++++---- .../src/main/res/values-vi/strings_shared.xml | 12 +++++++-- .../main/res/values-zh-rCN/strings_shared.xml | 12 +++++++-- .../main/res/values-zh-rTW/strings_shared.xml | 12 +++++++-- .../src/main/res/values/strings_shared.xml | 14 +++++++--- 37 files changed, 230 insertions(+), 86 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index a8038cd73c..c6d93e63d7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6156,7 +6156,7 @@ Upload paused due to no internet connection - تم إيقاف الترفيع مؤقتًا. شحن البطارية أقل من %1$d%% و ليست تُشحن الآن. + Upload paused as battery is below %1$d%% توقفت ترفيعات الكاميرا عن العمل. حاول إعادة تمكين ترفيعات الكاميرا لحلها. في حالة استمرار المشكلة، تواصل مع الدعم. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 335aeb1899..9e0290361b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5228,7 +5228,7 @@ Upload-Pause wegen fehlender Internetverbindung - Upload pausiert. Akku unter %1$d %% und nicht an Ladegerät angeschlossen. + Upload paused as battery is below %1$d%% Kamera-Uploads funktionieren nicht mehr. Um das Problem zu lösen, versuchen Sie, die Kamera-Uploads wieder zu aktivieren. Wenn das Problem weiterhin besteht, wenden Sie sich an den Support. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 96703ef796..b59541edc5 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5460,7 +5460,7 @@ Upload paused due to no internet connection - La subida está en pausa. Batería por debajo del %1$d %% y no se está cargando. + La subida está en pausa porque la batería está por debajo %1$d %% Las subidas de la cámara han dejado de funcionar. Intenta volver a activarlas para solucionarlo. Si el problema persiste, contactar con el servicio de soporte. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 454944a3c2..90a4428b1f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5460,7 +5460,7 @@ Les téléversements ont été mis en pause, car il n’y a pas de connexion à Internet - Le téléversement est en pause. Le niveau de batterie est inférieur à %1$d %% et l’appareil n’est pas en charge. + Le téléversement est en pause, car le niveau de la batterie est inférieur à %1$d %% Les téléversements de l’appareil photo ne fonctionnent plus. Essayez de les réactiver afin de résoudre la situation. Si le problème persiste, contactez l’assistance. diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 8fca01b616..d015848805 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -834,7 +834,7 @@ Terlalu banyak coba masuk yang gagal, mohon tunggu selama satu jam. - Check your email inbox and follow the link to confirm your account. + Periksa kotak masuk email anda dan ikuti tautan untuk mengonfirmasi akun anda. Tautan folder tidak tersedia @@ -848,7 +848,7 @@ Menunggu konfirmasi e-mail - Check your email inbox and follow the link to confirm your account. + Periksa kotak masuk email anda dan ikuti tautan untuk mengonfirmasi akun anda. %1$d barang @@ -4757,7 +4757,7 @@ Aplikasi telah diperbarui - Relaunch the app + Luncurkan kembali aplikasi Izinkan akses ke file audio @@ -4997,7 +4997,7 @@ Upload paused due to no internet connection - Unggahan dijeda. Baterai di bawah %1$d%% dan tidak mengisi daya. + Upload paused as battery is below %1$d%% Unggahan kamera berhenti berfungsi. Coba aktifkan kembali unggahan kamera untuk menyelesaikannya. Jika masalah berlanjut, hubungi dukungan. @@ -5139,7 +5139,7 @@ Laporkan masalah anda - Show hidden items + Tampilkan item tersembunyi All hidden items will be visible, but blurred to indicate their “hidden” status diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 45797bb344..81e25002b9 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5460,7 +5460,7 @@ Upload paused due to no internet connection - Caricamento in pausa. Batteria inferiore al %1$d%% e non in carica. + Upload paused as battery is below %1$d%% I Caricamenti da fotocamera hanno smesso di funzionare. Prova a riattivare i Caricamenti da fotocamera per risolvere il problema. Se il problema persiste, contatta il supporto. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index b94d3c9480..c4e25dd3b2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4996,7 +4996,7 @@ インターネット接続がないためアップロードが一時停止されました - アップロードが一時停止されました。バッテリーが%1$d %%を下回っており、充電されていません。 + バッテリーが%1$d%%を下回っているため、アップロードが一時停止されました カメラアップロードが機能しなくなりました。これを解決するには、カメラアップロードを再度有効にしてみてください。問題が解決しない場合は、サポートにご連絡ください。 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 20b90ea92f..654a7c77cd 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4996,7 +4996,7 @@ 인터넷 연결이 없어서 업로드가 일시정지 되었습니다 - 업로드가 일시 정지되었습니다. 배터리가 %1$d%% 이하이고 충전 중이지 않습니다 + 배터리가 %1$d%% 이하이기 대문에 업로드를 일시정지 하였습니다 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면, 지원으로 연락하세요. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index cdc47be5ec..ac33e8e388 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5228,7 +5228,7 @@ Upload onderbroken omdat er geen internetverbinding is - Het uploaden is gepauzeerd. Batterij onder %1$d%% en laad niet op. + Upload paused as battery is below %1$d%% Camera-uploads werken niet meer. Probeer camera-uploads opnieuw in te schakelen om het probleem op te lossen. Als het probleem zich blijft voordoen, neem contact op met de klantenservice. diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a40acf9c87..c81d38701b 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5692,7 +5692,7 @@ Upload paused due to no internet connection - Przesyłanie wstrzymane. Bateria poniżej %1$d%% i nie ładuje. + Upload paused as battery is below %1$d%% Przesyłanie wgraj kamery przestało działać. Spróbuj ponownie włączyć przesyłanie z kamery, aby rozwiązać ten problem. Jeśli problem nadal występuje, skontaktuj kontakt wsparcie. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 513f177525..256944fc9b 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5460,7 +5460,7 @@ O upload foi pausado por falta de conexão à Internet - O upload foi pausado. Há menos de %1$d%% de bateria, e não está sendo carregada. + O upload foi pausado porque a bateria há menos de %1$d%% de bateria Os uploads da câmera pararam de funcionar - tente reativá-los. Se o problema persistir, entre em contato com o suporte. diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 67d7178c7d..37c83ab23e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5460,7 +5460,7 @@ Încărcarea întreruptă din cauza lipsei conexiunii la internet - Încărcarea întreruptă. Baterie este sub %1$d %% și nu se încarcă. + Încărcarea a fost întreruptă deoarece bateria este sub %1$d %%. Încărcări camere au încetat să funcționeze. Încercați să reactivați încărcările camerei pentru a o rezolva. Dacă problema persistă, contactați asistență. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 201016bf6b..23c3b46861 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5692,7 +5692,7 @@ Upload paused due to no internet connection - Загрузка приостановлена. Аккумулятор заряжен менее чем на %1$d %% и не заряжается. + Загрузка приостановлена, так как заряд батареи ниже %1$d%% Загрузки из камеры перестали работать. Попробуйте повторно включить загрузки из камеры. Если проблема повторяется, обратитесь в поддержку. diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index ab0e62ef52..bfcfd2b50a 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -2188,7 +2188,7 @@ ชื่อไฟล์ - แสดงดูครั้งล่าสุด + แสดงการดูครั้งล่าสุด อนุญาตให้ผู้ติดต่อของคุณเห็นเวลาใช้งาน MEGA ล่าสุดของคุณ @@ -4996,7 +4996,7 @@ การอัปโหลดถูกหยุดชั่วคราวเนื่องจากการเชื่อมต่ออินเทอร์เน็ตขาดหายไป - การอัปโหลดถูกหยุดชั่วคราว เนื่องจากแบตเตอรี่เหลือน้อยกว่า %1$d%% และยังไม่ได้เสียบชาร์จ + Upload paused as battery is below %1$d%% การอัปโหลดจากกล้องหยุดทำงาน ลองเปิดใช้งานการอัปโหลดรูปภาพจากกล้องอีกครั้งเพื่อแก้ไข หากปัญหายังมีอยู่ กรุณาติดต่อฝ่ายสนับสนุน diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1c1fe358f2..5cbde98c38 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4996,7 +4996,7 @@ Tải lên bị tạm dừng do không có kết nối internet - Tải lên bị tạm dừng. Pin bên dưới %1$d%% và không được sạc. + Upload paused as battery is below %1$d%% Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với bộ phận hỗ trợ. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 31fbcb3001..4eb2265645 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4996,7 +4996,7 @@ 由于没有互联网连接,上传已暂停 - 上传已暂停。电量低于%1$d%%而且不在充电。 + 由于电池电量已低于%1$d%%,上传已暂停。 相机上传功能已停止运行。尝试重新启用相机上传功能来解决问题。如果问题仍然存在,请联系客服人员。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index de30ded333..018ed0c4ad 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4996,7 +4996,7 @@ 由於沒有網路連線,上傳已暫停 - 上傳暫停。電量低於%1$d%%且未處充電中。 + Upload paused as battery is below %1$d%% 相機上傳停止運作。嘗試重新啟用相機上傳來解決問題。如果問題仍然存在,聯繫客服。 diff --git a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml index 287145bc00..d965ac1be5 100644 --- a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml @@ -111,7 +111,7 @@ ไม่สามารถสื่อสารกับตำแหน่งที่ตั้งโฟลเดอร์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ - ไม่สามารถเพิ่มการตรวจดูระบบไฟล์ได้ ตรวจสอบให้แน่ใจว่ามีพื้นที่ว่างและหน่วยความจำเพียงพอแล้ว และคุณได้ให้สิทธิ์ในการเข้าถึงตำแหน่งที่ตั้งโฟลเดอร์แล้ว + ไม่สามารถติดตามการเปลี่ยนแปลงไฟล์ในโฟลเดอร์นี้ได้ ตรวจสอบพื้นที่ว่างบนอุปกรณ์และหน่วยความจำ และตรวจสอบให้แน่ใจว่าคุณมีสิทธิ์เข้าถึงโฟลเดอร์นี้ ไม่สามารถอ่านตำแหน่งที่ตั้งการซิงค์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 79925bc3da..2da881bec3 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -117,7 +117,7 @@ 이동 또는 이름 변경을 할 수 없습니다 - Delete or move action is waiting for scan + 삭제 또는 이동이 스캔을 기다리는 중입니다 아직 삭제할 수 없음 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 770ea34da0..6e1207e1e3 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -279,7 +279,7 @@ Only this time - Always save here + Always download here Always ask for destination @@ -287,13 +287,21 @@ تيرابايت - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. Insufficient storage space - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. انظر إلى الباقات ليس الآن + + If you have misspelt your email address, correct it and tap [A]Resend[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + ترقية + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 18c3a4f00c..e3d133ec88 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -255,25 +255,33 @@ Links teilen - Download to this location\? + An diesen Speicherort herunterladen\? - Only this time + Nur dieses Mal - Always save here + Always download here - Always ask for destination + Immer nach Zielort fragen GB TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. - Insufficient storage space + Unzureichender Speicherplatz - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. Pakete ansehen Jetzt nicht + + Wenn Sie sich bei der E-Mail-Adresse vertippt haben, korrigieren Sie diese und tippen Sie auf [A]Erneut senden[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + Upgrade + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 93790c6194..76c6c49e67 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -267,9 +267,9 @@ Sólo esta vez - Siempre guardar aquí + Descargar siempre aquí - Siempre pregunte por el destino + Preguntar siempre el destino GB @@ -284,4 +284,12 @@ Ver planes Ahora no + + Si has escrito mal tu dirección de correo electrónico, corrígela y pulsa en [A]Reenviar[/A]. + + La sincronización se ha interrumpido. Tu plan MEGA se ha quedado sin espacio de almacenamiento. + + Ampliar + + Subida en pausa, el teléfono no se está cargando. \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 76f18b7b49..9da26cbc3b 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -267,7 +267,7 @@ Cette fois seulement - Toujours enregistrer ici + Toujours télécharger ici Toujours demander la destination @@ -284,4 +284,12 @@ Voir les abonnements Pas maintenant + + Si une erreur s’est glissée dans votre adresse courriel, corrigez-la et touchez [A]Renvoyer[/A]. + + La synchronisation est interrompue. Votre abonnement MEGA est à court d\’espace de stockage. + + Surclasser mon compte + + Le téléversement est en pause, car le téléphone n’est pas en charge \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 008df64d67..08d3396ee9 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -255,7 +255,7 @@ Only this time - Always save here + Always download here Always ask for destination @@ -263,13 +263,21 @@ TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. Insufficient storage space - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. Lihat rencana Jangan Sekarang + + If you have misspelt your email address, correct it and tap [A]Resend[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + Tingkatkan + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index b4a83a6c79..079448e932 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -263,25 +263,33 @@ Condividi link - Download to this location\? + Scaricare in questa posizione\? - Only this time + Solo questa volta - Always save here + Always download here - Always ask for destination + Chiedi sempre la posizione del download GB TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. - Insufficient storage space + Spazio di archiviazione insufficiente - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. Vedi i piani Non adesso + + Se hai scritto male il tuo indirizzo e-mail, correggilo e poi tocca su [A]Reinvia[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + Effettua l’upgrade + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 3ad811d77f..613c441b4d 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -251,7 +251,7 @@ 今回だけ - 常にここに保存 + 常にここにダウンロード 常に保存先を尋ねる @@ -259,7 +259,7 @@ TB - %1$s%2$sから始めて、お客様のストレージのニーズに最適なものを見つけてください。 + %1$s %2$sから始めて、お客様のストレージニーズに最適なものを見つけてください。 ストレージ容量が不十分です @@ -268,4 +268,12 @@ プランを見る 今はやめます + + メールアドレスのスペルを間違った場合、それを修正して[A]再送信[/A]をタップしてください。 + + 同期が一時停止されました。MEGAプランのストレージが不足しています。 + + アップグレード + + アップロードが一時停止されました、携帯電話は充電されていません \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 3d47367a1b..0345af7243 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -213,7 +213,7 @@ 동기화된 폴더 추가: - %1$s GB + %1$sGB Free @@ -223,7 +223,7 @@ 계속 - Choose your MEGA plan + MEGA 요금제 선택 포함된 항목 @@ -247,25 +247,33 @@ 링크 공유 - Download to this location\? + 이 위치에 다운로드 할까요\? - Only this time + 이번 한번만 - Always save here + 항상 여기에 다운로드 - Always ask for destination + 항상 대상 묻기 GB TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + %1$s%2$s부터 시작하여, 당신의 저장소 수요에 맞는 것을 찾으세요. - Insufficient storage space + 저장 공간 부족 - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + 이 폴더의 크기는 당신의 MEGA 계정의 저장소 한도를 초과할 것입니다. 동기화를 가능하게 하려면 여유 공간을 확보하거나 MEGA 계정을 업그레이드 하세요. 요금제 보기 나중에 + + 만약 이메일 주소를 잘못 입력하였다면, 수정하고 [A]재발송[/A]을 탭하세요. + + 당신의 MEGA 요금제의 저장소를 다 써서, 동기화가 일시정지 되었습니다. + + 업그레이드 + + 휴대전화가 충전 중이 아니어서, 업로드가 일시정지 되었습니다 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 60509fc3f8..7e25e97fef 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -259,7 +259,7 @@ Alleen deze keer - Altijd hier opslaan + Always download here Vraag altijd naar de bestemming @@ -267,13 +267,21 @@ TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. - Insufficient storage space + Onvoldoende opslagruimte - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. Zie abonnementen Niet Nu + + Als u uw e-mailadres verkeerd hebt gespeld, corrigeer het en tik op [A]Opnieuw versturen[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + Upgraden + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 7338db40cf..d00cea2677 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -275,7 +275,7 @@ Tylko tym razem - Zawsze zapisuj tutaj + Zawsze pobieraj tutaj Zawsze pytaj o miejsce docelowe @@ -283,13 +283,21 @@ TB - Zaczynając od %1$s %2$s, znajdź idealne dopasowanie do swoich potrzeb pojemność. + Zaczynając od %1$s %2$s, znajdź idealne dopasowanie do swoich potrzeb pojemność. - Insufficient storage space + Niewystarczająca dostępna pamięć - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + Rozmiar tego katalogu spowoduje, że Twoje konto MEGA przekroczy limit pojemności. Aby móc go zsynchronizować, musisz zwolnić trochę miejsca lub uaktualnić swoje konto MEGA. Zobacz abonamenty Nie teraz + + Jeśli błędnie wpisałeś swój adres email, popraw go i kliknij [A]Wyślij ponownie[/A]. + + Synchronizacja jest wstrzymana, w planie MEGA zabrakło pamięci. + + Zmień + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 8ba6471ec0..cafac3f743 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -267,7 +267,7 @@ Somente esta vez - Sempre salvar aqui + Sempre fazer o download aqui Sempre perguntar o destino @@ -275,13 +275,21 @@ TB - Encontre a melhor opção para as suas necessidades de armazenamento a partir de %1$s %2$s . + Encontre a melhor opção para as suas necessidades de armazenamento a partir de %1$s %2$s . Espaço de armazenamento insuficiente - O tamanho dessa pasta fará com que a sua conta no MEGA ultrapasse o limite de armazenamento. Para poder sincronizá-la, você vai precisar liberar espaço ou fazer o upgrade da sua conta no MEGA. + O tamanho dessa pasta vai fazer que a sua conta no MEGA ultrapasse o limite de armazenamento. Para poder sincronizá-la, você vai precisar liberar espaço ou fazer o upgrade da sua conta. Veja os planos Agora não + + Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[/A]. + + A sincronização foi pausada porque o seu plano do MEGA já não tem armazenamento disponível. + + Upgrade + + O upload foi pausado porque o telefone não está carregando \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index bbce5c7e78..afe5750457 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -267,7 +267,7 @@ Doar de data aceasta - Întotdeauna salvați aici + Întotdeauna descărcați aici Întotdeauna cereți locația @@ -284,4 +284,12 @@ Vezi abonamentele Nu acum + + Dacă ați scris greșit adresa dvs. de e-mail, corectați-o și atingeți [A]Retrimite[/A]. + + Sincronizarea a fost întreruptă. Planul dvs. MEGA a rămas fără spațiu de stocare. + + Upgradează + + Încărcarea este întreruptă, deoarece telefonul nu se încarcă \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 9d70a38977..555f40c64b 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -275,7 +275,7 @@ Только в этот раз - Всегда сохранять здесь + Всегда скачивать сюда Всегда спрашивать расположение @@ -283,7 +283,7 @@ ТБ - Найдите свой идеальный объём хранилища. От %1$s %2$s. + Найдите свой идеальный объём хранилища. От %1$s %2$s. Недостаточно места для хранения @@ -292,4 +292,12 @@ Подписки Не сейчас + + Если вы неправильно написали свой адрес электронной почты, исправьте его и нажмите [A]«Выслать повторно»[/A]. + + Синхронизация приостановлена, в вашем плане MEGA закончилось место. + + Улучшить + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 86555cd2ca..8f72880baa 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -9,7 +9,7 @@ ไม่สามารถซิงค์ไฟล์ทีละไฟล์ได้ คุณต้องตั้งค่าการซิงค์จากโฟลเดอร์แทน - การสแกนเริ่มต้นล้มเหลว คุณจะต้องเปิดใช้งานการซิงค์หรือสำรองข้อมูลจากแอปเดสก์ทอปของคุณใหม่ + การสแกนเริ่มต้นล้มเหลว คุณต้องเปิดใช้งานการซิงค์หรือสำรองข้อมูลจากแอปเดสก์ท็อปอีกครั้ง ไม่สามารถหาโฟลเดอร์ใน MEGA ได้ เนื่องจากถูกย้ายหรือลบออก หรือคุณอาจไม่สามารถเข้าถึงได้ @@ -33,7 +33,7 @@ มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ ลองใหม่อีกครั้งในภายหลัง หากยังประสบปัญหาอยู่ กรุณาติดต่อฝ่ายสนับสนุน - บัญชีของคุณถูกโหลดซ้ำ การเปลี่ยนแปลงที่หายไปจะไม่มีผลกับการสำรองข้อมูลหรือการซิงค์ของคุณ + โหลดข้อมูลในบัญชีใหม่แล้ว แต่การอัปเดตสำรองข้อมูลหรือการซิงค์ที่พลาดไปยังไม่ได้ถูกนำไปใช้ การซิงค์หรือสำรองข้อมูลหยุดลง เนื่องจากคุณออกจากระบบแอปเดสก์ท็อปแล้ว เข้าสู่ระบบแอปเดสก์ท็อปอีกครั้งเพื่อดำเนินการซิงค์หรือสำรองข้อมูลต่อ @@ -251,7 +251,7 @@ เฉพาะครั้งนี้เท่านั้น - บันทึกไว้ที่นี่เสมอ + ดาวน์โหลดไว้ที่นี่เสมอ ถามให้เลือกปลายทางทุกครั้ง @@ -259,13 +259,21 @@ TB - เริ่มต้นที่ %1$s %2$s เลือกขนาดพื้นที่เก็บข้อมูลที่เหมาะกับคุณ + Starting from %1$s %2$s, find the perfect fit for your storage needs. พื้นที่จัดเก็บข้อมูลไม่เพียงพอ - โฟลเดอร์นี้มีขนาดใหญ่เกินกว่าพื้นที่เก็บข้อมูล MEGA ของคุณ หากต้องการซิงค์โฟลเดอร์นี้ คุณต้องเพิ่มพื้นที่ว่างในบัญชี MEGA ของคุณ หรืออัปเกรดเป็นแผนที่มีพื้นที่เก็บข้อมูลมากกว่า + โฟลเดอร์นี้มีขนาดใหญ่เกินกว่าพื้นที่เก็บข้อมูล MEGA ของคุณ หากต้องการซิงค์โฟลเดอร์นี้ คุณต้องเพิ่มพื้นที่ว่างในบัญชี MEGA ของคุณ หรืออัปเกรดเป็นแผนที่มีพื้นที่เก็บข้อมูลมากกว่าเดิม ดูแผนการ ไม่ใช่ตอนนี้ + + หากคุณสะกดที่อยู่อีเมลผิด ให้แก้ไขแล้วแตะ[A]ส่งใหม่[/A] + + การซิงค์ถูกหยุดไว้ชั่วคราว เนื่องจากพื้นที่เก็บข้อมูลใน MEGA ของคุณเต็มแล้ว + + อัปเกรด + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 697304b6e3..2b2fe8a35d 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -251,7 +251,7 @@ Chỉ lần này - Luôn lưu vào đây + Luôn tải xuống vào đây Luôn hỏi vị trí lưu @@ -259,7 +259,7 @@ TB - Bắt đầu từ %1$s %2$s, tìm gói phù hợp hoàn hảo cho nhu cầu lưu trữ của bạn. + Bắt đầu với %1$s %2$s, tìm gói phù hợp hoàn hảo cho nhu cầu lưu trữ của bạn. Không gian lưu trữ không đủ @@ -268,4 +268,12 @@ Xem các gói thuê bao Không phải lúc này + + Nếu địa chỉ email bị viết sai, sửa lại cho đúng và chạm vào [A]Gửi lại[/A]. + + Đồng bộ hóa tạm dừng, gói MEGA của bạn đã hết dung lượng lưu trữ. + + Nâng cấp + + Upload paused, phone is not charging \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 84dd5cc862..26101f20d6 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -251,7 +251,7 @@ 只有这次 - 总是保存在此 + 总是下载到此处 总是询问下载位置 @@ -259,7 +259,7 @@ TB - 从%1$s%2$s起,找到最适合您存储需求的方案。 + 从%1$s %2$s起,找到最适合您存储需求的方案。 存储空间不足 @@ -268,4 +268,12 @@ 查看方案 现在不用 + + 如果您拼错了您的电子邮件地址,请更正并点按[A]重新发送[/A]。 + + 同步已暂停,您MEGA方案的存储空间已用完。 + + 升级 + + 上传已暂停,手机未在充电 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index a0348d8681..9cb5bbfa7b 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -251,7 +251,7 @@ 只有這一次 - 總是儲存在此 + 總是下載到此 總是詢問下載位置 @@ -259,7 +259,7 @@ TB - 從%1$s%2$s起,找到最適合您的儲存需求方案。 + 從%1$s %2$s起,找到最適合您的儲存需求方案。 儲存空間不足 @@ -268,4 +268,12 @@ 檢視方案 稍後再說 + + 如果您拼錯您的電子郵件地址,請更正並點選[A]重新發送[/A]。 + + 同步已暫停,您的MEGA方案的儲存空間已用完。 + + 升級 + + 上傳已暫停,手機未在充電 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 36fa459693..7d5455a50b 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -259,7 +259,7 @@ Only this time - Always save here + Always download here Always ask for destination @@ -267,13 +267,21 @@ TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Starting from %1$s %2$s, find the perfect fit for your storage needs. Insufficient storage space - The size of this folder will take your MEGA account over its storage limit. In order to be able to sync it, you will need to either free up some space or upgrade your MEGA account. + The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. See plans Not now + + If you have misspelt your email address, correct it and tap [A]Resend[/A]. + + Syncing paused, your MEGA plan has run out of storage. + + Upgrade + + Upload paused, phone is not charging \ No newline at end of file From 5ce3cc0f9e799d46395dcee54697fe38609db877 Mon Sep 17 00:00:00 2001 From: JoeJi Date: Wed, 15 May 2024 20:02:26 +1200 Subject: [PATCH 115/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index e6d795c0c8..52a1c82283 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -71,7 +71,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240510.025619" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 8375bb3df8b0b4fc0ae98509f13ec5a22f97b58e Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Fri, 17 May 2024 14:50:38 +1200 Subject: [PATCH 116/261] AND-18791:Fix ImagePreview non-fatal issue --- .../imagepreview/ImagePreviewViewModel.kt | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt index 213df8c5ff..20b1b5e454 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt @@ -721,8 +721,10 @@ class ImagePreviewViewModel @Inject constructor( } suspend fun isAvailableOffline(imageNode: ImageNode): Boolean { - val typedNode = addImageTypeUseCase(imageNode) - return isAvailableOfflineUseCase(typedNode) + return runCatching { + val typedNode = addImageTypeUseCase(imageNode) + isAvailableOfflineUseCase(typedNode) + }.onFailure { Timber.e(it) }.getOrDefault(false) } /** @@ -748,22 +750,28 @@ class ImagePreviewViewModel @Inject constructor( suspend fun getFallbackImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(previewUri) ?: checkUri(thumbnailUri) + safeCheckUri(previewUri) ?: safeCheckUri(thumbnailUri) } } suspend fun getHighestResolutionImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(fullSizeUri) ?: checkUri(previewUri) ?: checkUri(thumbnailUri) + safeCheckUri(fullSizeUri) ?: safeCheckUri(previewUri) ?: safeCheckUri(thumbnailUri) } } suspend fun getLowestResolutionImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(thumbnailUri) ?: checkUri(previewUri) ?: checkUri(fullSizeUri) + safeCheckUri(thumbnailUri) ?: safeCheckUri(previewUri) ?: safeCheckUri(fullSizeUri) } } + private suspend fun safeCheckUri(uriPath: String?): String? { + return runCatching { + checkUri(uriPath) + }.onFailure { Timber.e(it) }.getOrNull() + } + /** * Move to rubbish */ @@ -804,14 +812,21 @@ class ImagePreviewViewModel @Inject constructor( * Hide the node (mark as sensitive) */ fun hideNode(nodeId: NodeId) = viewModelScope.launch { - updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = true) + runCatching { + updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = true) + }.onFailure { + Timber.e(it) + } } /** * Unhide the node (unmark as sensitive) */ fun unhideNode(nodeId: NodeId) = viewModelScope.launch { - updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = false) + runCatching { + updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = false) + }.onFailure { Timber.e(it) } + } fun playVideo( From 8cae2def04775e9d1654d9b2c68a5cb30553396d Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Fri, 17 May 2024 17:06:00 +1200 Subject: [PATCH 117/261] AND-15164: Fix toolbar elevation issue of call in progress UI (cherry picked from commit 623195161b98282310118b9c8d0def89238b7a70) --- .../java/mega/privacy/android/app/main/ManagerActivity.kt | 5 ++++- .../privacy/android/app/main/view/OngoingCallViewModel.kt | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 490df18d2f..1caaffe806 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -3676,7 +3676,8 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } drawerItem = item ?: DrawerItem.CLOUD_DRIVE callInProgressViewModel.setShow( - drawerItem != DrawerItem.TRANSFERS && drawerItem != DrawerItem.NOTIFICATIONS && drawerItem != DrawerItem.HOMEPAGE + resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT + && drawerItem != DrawerItem.TRANSFERS && drawerItem != DrawerItem.NOTIFICATIONS && drawerItem != DrawerItem.HOMEPAGE ) // Homepage may hide the Appbar before @@ -7518,6 +7519,8 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf mElevationCause = mElevationCause xor cause } + if (mElevationCause == ELEVATION_CALL_IN_PROGRESS && !callInProgressViewModel.isShowing()) return + // If any Tablayout is visible, set the background of the toolbar to transparent (or its elevation // overlay won't be correctly set via AppBarLayout) and then set the elevation of AppBarLayout, // in this way, both Toolbar and TabLayout would have expected elevation overlay. diff --git a/app/src/main/java/mega/privacy/android/app/main/view/OngoingCallViewModel.kt b/app/src/main/java/mega/privacy/android/app/main/view/OngoingCallViewModel.kt index 8fb1a4efd0..ff966607a5 100644 --- a/app/src/main/java/mega/privacy/android/app/main/view/OngoingCallViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/main/view/OngoingCallViewModel.kt @@ -41,4 +41,8 @@ internal class OngoingCallViewModel @Inject constructor( fun setShow(show: Boolean) { _state.update { it.copy(isShown = show) } } + + fun isShowing(): Boolean { + return state.value.isShown && state.value.currentCall != null + } } \ No newline at end of file From 4c13167e2b9999c2e8383f1570bbdab2fe586752 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Fri, 17 May 2024 11:15:03 +0700 Subject: [PATCH 118/261] AND-16305: Fix log out issue doesn't navigate to login page (cherry picked from commit 5addc38d0b1c937dd7742f73fcd0b6106bfcb9a0) --- .../main/java/mega/privacy/android/app/MegaApplication.kt | 6 +++++- .../java/mega/privacy/android/app/SqliteDatabaseHandler.kt | 5 +++++ .../app/globalmanagement/BackgroundRequestListener.kt | 1 + .../mega/privacy/android/data/database/DatabaseHandler.kt | 2 +- .../migration/CredentialsPreferencesMigration.kt | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt index 167514d927..b5eb530d35 100644 --- a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt +++ b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt @@ -334,7 +334,11 @@ class MegaApplication : MultiDexApplication(), DefaultLifecycleObserver, } } - private fun setupMegaChatApi() { + /** + * Setup mega chat api + * + */ + fun setupMegaChatApi() { if (!registeredChatListeners) { Timber.d("Add listeners of megaChatApi") megaChatApi.apply { diff --git a/app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt b/app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt index 459fe03301..fd1cfca0b9 100644 --- a/app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt +++ b/app/src/main/java/mega/privacy/android/app/SqliteDatabaseHandler.kt @@ -1883,6 +1883,11 @@ class SqliteDatabaseHandler @Inject constructor( } } + override fun clearCredentials() { + Timber.w("Clear local credentials!") + writableDatabase.execSQL("DROP TABLE IF EXISTS $TABLE_CREDENTIALS") + } + override fun clearEphemeral() { writableDatabase.execSQL("DROP TABLE IF EXISTS $TABLE_EPHEMERAL") legacyDatabaseMigration.onCreate(writableDatabase) diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt index 4fff3448f5..dc3b5f664b 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/BackgroundRequestListener.kt @@ -166,6 +166,7 @@ class BackgroundRequestListener @Inject constructor( if (dbH.myChatFilesFolderHandle == INVALID_HANDLE) { megaApi.getMyChatFilesFolder(listener) } + MegaApplication.getInstance().setupMegaChatApi() applicationScope.launch { // Init CU sync data after login successfully runCatching { diff --git a/data/src/main/java/mega/privacy/android/data/database/DatabaseHandler.kt b/data/src/main/java/mega/privacy/android/data/database/DatabaseHandler.kt index 512f8226af..97b81a911f 100644 --- a/data/src/main/java/mega/privacy/android/data/database/DatabaseHandler.kt +++ b/data/src/main/java/mega/privacy/android/data/database/DatabaseHandler.kt @@ -6,7 +6,6 @@ import mega.privacy.android.data.model.chat.AndroidMegaChatMessage import mega.privacy.android.data.model.chat.NonContactInfo import mega.privacy.android.domain.entity.Contact import mega.privacy.android.domain.entity.Offline -import mega.privacy.android.domain.entity.StorageState import mega.privacy.android.domain.entity.login.EphemeralCredentials import mega.privacy.android.domain.entity.settings.ChatSettings import mega.privacy.android.domain.entity.user.UserCredentials @@ -124,6 +123,7 @@ interface DatabaseHandler { fun setLastPublicHandleTimeStamp(lastPublicHandleTimeStamp: Long) fun setLastPublicHandleTimeStamp() fun setInvalidateSdkCache(invalidateSdkCache: Boolean) + fun clearCredentials() @Deprecated("Call to ClearEphemeralCredentialsUseCase instead") fun clearEphemeral() fun clearPreferences() diff --git a/data/src/main/java/mega/privacy/android/data/preferences/migration/CredentialsPreferencesMigration.kt b/data/src/main/java/mega/privacy/android/data/preferences/migration/CredentialsPreferencesMigration.kt index a396c905c2..b1cf5ee341 100644 --- a/data/src/main/java/mega/privacy/android/data/preferences/migration/CredentialsPreferencesMigration.kt +++ b/data/src/main/java/mega/privacy/android/data/preferences/migration/CredentialsPreferencesMigration.kt @@ -21,6 +21,8 @@ internal class CredentialsPreferencesMigration @Inject constructor( databaseHandler.credentials?.let { return currentData.toMutablePreferences().apply { migrate(this, it) + }.also { + databaseHandler.clearCredentials() } } return currentData From 8f0d631dca9cbf95f06b2ec9665bc3afff8d7a4b Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Mon, 20 May 2024 14:18:49 +0700 Subject: [PATCH 119/261] Update versionName for hotfix release --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2e418e8898..7c823f9c19 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -74,7 +74,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "13.1" +extra["appVersion"] = "13.1.1" // Sdk and tools extra["compileSdkVersion"] = 34 From 58990c5b689244947167287d964dd017ab3e968d Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Fri, 17 May 2024 14:50:38 +1200 Subject: [PATCH 120/261] AND-18791:Fix ImagePreview non-fatal issue --- .../imagepreview/ImagePreviewViewModel.kt | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt index 7aec229100..d5d50266b0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt @@ -740,8 +740,10 @@ class ImagePreviewViewModel @Inject constructor( } suspend fun isAvailableOffline(imageNode: ImageNode): Boolean { - val typedNode = addImageTypeUseCase(imageNode) - return isAvailableOfflineUseCase(typedNode) + return runCatching { + val typedNode = addImageTypeUseCase(imageNode) + isAvailableOfflineUseCase(typedNode) + }.onFailure { Timber.e(it) }.getOrDefault(false) } /** @@ -767,22 +769,28 @@ class ImagePreviewViewModel @Inject constructor( suspend fun getFallbackImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(previewUri) ?: checkUri(thumbnailUri) + safeCheckUri(previewUri) ?: safeCheckUri(thumbnailUri) } } suspend fun getHighestResolutionImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(fullSizeUri) ?: checkUri(previewUri) ?: checkUri(thumbnailUri) + safeCheckUri(fullSizeUri) ?: safeCheckUri(previewUri) ?: safeCheckUri(thumbnailUri) } } suspend fun getLowestResolutionImagePath(imageResult: ImageResult?): String? { return imageResult?.run { - checkUri(thumbnailUri) ?: checkUri(previewUri) ?: checkUri(fullSizeUri) + safeCheckUri(thumbnailUri) ?: safeCheckUri(previewUri) ?: safeCheckUri(fullSizeUri) } } + private suspend fun safeCheckUri(uriPath: String?): String? { + return runCatching { + checkUri(uriPath) + }.onFailure { Timber.e(it) }.getOrNull() + } + /** * Move to rubbish */ @@ -836,14 +844,21 @@ class ImagePreviewViewModel @Inject constructor( * Hide the node (mark as sensitive) */ fun hideNode(nodeId: NodeId) = viewModelScope.launch { - updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = true) + runCatching { + updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = true) + }.onFailure { + Timber.e(it) + } } /** * Unhide the node (unmark as sensitive) */ fun unhideNode(nodeId: NodeId) = viewModelScope.launch { - updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = false) + runCatching { + updateNodeSensitiveUseCase(nodeId = nodeId, isSensitive = false) + }.onFailure { Timber.e(it) } + } fun playVideo( From 369a099076317f75ca1d83975552b29fc15a94be Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Mon, 20 May 2024 20:10:19 +1200 Subject: [PATCH 121/261] Fix T16264681: Send file link to group chat, save to device and add to cloud drive --- .../data/repository/NodeRepositoryImpl.kt | 2 + .../domain/repository/NodeRepository.kt | 2 + .../usecase/node/CopyCollidedNodeUseCase.kt | 6 +- .../domain/usecase/node/CopyNodeUseCase.kt | 7 ++- .../node/CopyCollidedNodeUseCaseTest.kt | 55 +++++++++++++++---- .../usecase/node/CopyNodeUseCaseTest.kt | 9 ++- 6 files changed, 66 insertions(+), 15 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/repository/NodeRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/NodeRepositoryImpl.kt index 90daed9860..d6d772bf62 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/NodeRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/NodeRepositoryImpl.kt @@ -574,10 +574,12 @@ internal class NodeRepositoryImpl @Inject constructor( override suspend fun copyNode( nodeToCopy: NodeId, + nodeToCopySerializedData: String?, newNodeParent: NodeId, newNodeName: String?, ): NodeId = withContext(ioDispatcher) { val node = getMegaNodeByHandle(nodeToCopy, true) + ?: nodeToCopySerializedData?.let { MegaNode.unserialize(it) } val parent = getMegaNodeByHandle(newNodeParent, true) requireNotNull(node) { "Node to copy with handle $nodeToCopy not found" } requireNotNull(parent) { "Destination node with handle $newNodeParent not found" } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/repository/NodeRepository.kt b/domain/src/main/kotlin/mega/privacy/android/domain/repository/NodeRepository.kt index b4d49d2a7e..68a187865b 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/repository/NodeRepository.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/repository/NodeRepository.kt @@ -359,6 +359,7 @@ interface NodeRepository { * Copy a [Node] and move it to a new [Node] while updating its name if set * * @param nodeToCopy the [NodeId] to copy + * @param nodeToCopySerializedData optional node serialized data when a node from link needs to be copied * @param newNodeParent the [NodeId] that [nodeToCopy] will be moved to * @param newNodeName the new name for [nodeToCopy] once it is moved to [newNodeParent] if it's not null, if it's null the name will be the same * @@ -366,6 +367,7 @@ interface NodeRepository { */ suspend fun copyNode( nodeToCopy: NodeId, + nodeToCopySerializedData: String? = null, newNodeParent: NodeId, newNodeName: String?, ): NodeId diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCase.kt index b7469733f7..31a256c3a3 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCase.kt @@ -4,6 +4,7 @@ import mega.privacy.android.domain.entity.node.MoveRequestResult import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.NodeNameCollision import mega.privacy.android.domain.exception.extension.shouldEmitErrorForNodeMovement +import mega.privacy.android.domain.repository.NodeRepository import mega.privacy.android.domain.usecase.node.chat.GetChatFilesUseCase import javax.inject.Inject @@ -13,7 +14,7 @@ import javax.inject.Inject class CopyCollidedNodeUseCase @Inject constructor( private val getChatFilesUseCase: GetChatFilesUseCase, private val copyTypedNodeUseCase: CopyTypedNodeUseCase, - private val copyNodeUseCase: CopyNodeUseCase, + private val nodeRepository: NodeRepository, ) { /** @@ -42,8 +43,9 @@ class CopyCollidedNodeUseCase @Inject constructor( newNodeName = if (rename) nameCollision.renameName else null ) } else { - copyNodeUseCase( + nodeRepository.copyNode( nodeToCopy = NodeId(nameCollision.nodeHandle), + nodeToCopySerializedData = nameCollision.serializedData, newNodeParent = NodeId(nameCollision.parentHandle), newNodeName = if (rename) nameCollision.renameName else null ) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCase.kt index 93b0e7c509..f816e7ef03 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCase.kt @@ -22,5 +22,10 @@ class CopyNodeUseCase @Inject constructor(private val nodeRepository: NodeReposi nodeToCopy: NodeId, newNodeParent: NodeId, newNodeName: String?, - ) = nodeRepository.copyNode(nodeToCopy, newNodeParent, newNodeName) + ) = nodeRepository.copyNode( + nodeToCopy = nodeToCopy, + nodeToCopySerializedData = null, + newNodeParent = newNodeParent, + newNodeName = newNodeName, + ) } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCaseTest.kt index cc78ce2200..b4b417254d 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyCollidedNodeUseCaseTest.kt @@ -8,6 +8,7 @@ import mega.privacy.android.domain.entity.node.chat.ChatDefaultFile import mega.privacy.android.domain.exception.NotEnoughQuotaMegaException import mega.privacy.android.domain.exception.QuotaExceededMegaException import mega.privacy.android.domain.exception.node.ForeignNodeException +import mega.privacy.android.domain.repository.NodeRepository import mega.privacy.android.domain.usecase.node.chat.GetChatFilesUseCase import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach @@ -18,14 +19,13 @@ import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.reset -import org.mockito.kotlin.verify import org.mockito.kotlin.whenever internal class CopyCollidedNodeUseCaseTest { private val getChatFilesUseCase: GetChatFilesUseCase = mock() private val copyTypedNodeUseCase: CopyTypedNodeUseCase = mock() - private val copyNodeUseCase: CopyNodeUseCase = mock() + private val nodeRepository: NodeRepository = mock() private lateinit var underTest: CopyCollidedNodeUseCase @@ -34,13 +34,13 @@ internal class CopyCollidedNodeUseCaseTest { underTest = CopyCollidedNodeUseCase( getChatFilesUseCase = getChatFilesUseCase, copyTypedNodeUseCase = copyTypedNodeUseCase, - copyNodeUseCase = copyNodeUseCase + nodeRepository = nodeRepository ) } @AfterEach fun resetMocks() { - reset(copyNodeUseCase, copyTypedNodeUseCase, getChatFilesUseCase) + reset(nodeRepository, copyTypedNodeUseCase, getChatFilesUseCase) } @Test @@ -50,8 +50,16 @@ internal class CopyCollidedNodeUseCaseTest { on { nodeHandle } doReturn 1L on { parentHandle } doReturn 2L on { renameName } doReturn "new name" + on { serializedData } doReturn null } - whenever(copyNodeUseCase(NodeId(any()), NodeId(any()), anyOrNull())).thenReturn( + whenever( + nodeRepository.copyNode( + NodeId(any()), + any(), + NodeId(any()), + anyOrNull() + ) + ).thenReturn( NodeId( 1L ) @@ -59,7 +67,6 @@ internal class CopyCollidedNodeUseCaseTest { val result = underTest(nodeNameCollision, rename = true) - verify(copyNodeUseCase).invoke(NodeId(1L), NodeId(2L), "new name") assertThat(result.count).isEqualTo(1) assertThat(result.errorCount).isEqualTo(0) } @@ -71,10 +78,12 @@ internal class CopyCollidedNodeUseCaseTest { on { nodeHandle } doReturn 1L on { parentHandle } doReturn 2L on { renameName } doReturn "new name" + on { serializedData } doReturn null } whenever( - copyNodeUseCase( + nodeRepository.copyNode( NodeId(any()), + anyOrNull(), NodeId(any()), anyOrNull() ) @@ -82,7 +91,6 @@ internal class CopyCollidedNodeUseCaseTest { val result = underTest(nodeNameCollision, rename = true) - verify(copyNodeUseCase).invoke(NodeId(1L), NodeId(2L), "new name") assertThat(result.count).isEqualTo(1) assertThat(result.errorCount).isEqualTo(1) } @@ -98,6 +106,7 @@ internal class CopyCollidedNodeUseCaseTest { on { parentHandle } doReturn 2L on { chatId } doReturn 1L on { messageId } doReturn 1L + on { serializedData } doReturn null } whenever(getChatFilesUseCase(1L, 1L)).thenReturn(listOf(chatFile)) whenever(copyTypedNodeUseCase(chatFile, NodeId(2L), null)).thenReturn(NodeId(2L)) @@ -164,8 +173,16 @@ internal class CopyCollidedNodeUseCaseTest { val nodeNameCollision = mock { on { nodeHandle } doReturn 1L on { parentHandle } doReturn 2L + on { serializedData } doReturn null } - whenever(copyNodeUseCase(NodeId(any()), NodeId(any()), anyOrNull())) + whenever( + nodeRepository.copyNode( + NodeId(any()), + anyOrNull(), + NodeId(any()), + anyOrNull() + ) + ) .thenThrow(ForeignNodeException::class.java) assertThrows { @@ -179,8 +196,16 @@ internal class CopyCollidedNodeUseCaseTest { val nodeNameCollision = mock { on { nodeHandle } doReturn 1L on { parentHandle } doReturn 2L + on { serializedData } doReturn "data" } - whenever(copyNodeUseCase(NodeId(any()), NodeId(any()), anyOrNull())) + whenever( + nodeRepository.copyNode( + NodeId(any()), + anyOrNull(), + NodeId(any()), + anyOrNull() + ) + ) .thenAnswer { throw NotEnoughQuotaMegaException(1, "") } @@ -195,8 +220,16 @@ internal class CopyCollidedNodeUseCaseTest { val nodeNameCollision = mock { on { nodeHandle } doReturn 1L on { parentHandle } doReturn 2L + on { serializedData } doReturn "data" } - whenever(copyNodeUseCase(NodeId(any()), NodeId(any()), anyOrNull())) + whenever( + nodeRepository.copyNode( + NodeId(any()), + anyOrNull(), + NodeId(any()), + anyOrNull() + ) + ) .thenAnswer { throw QuotaExceededMegaException(1, "") } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCaseTest.kt index 0de5b9405f..1f29313693 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/node/CopyNodeUseCaseTest.kt @@ -42,7 +42,14 @@ class CopyNodeUseCaseTest { val newNodeParent = NodeId(456L) val newNodeName = "new Node" val expected = NodeId(789L) - whenever(nodeRepository.copyNode(nodeToCopy, newNodeParent, newNodeName)).thenReturn( + whenever( + nodeRepository.copyNode( + nodeToCopy, + nodeToCopySerializedData = null, + newNodeParent = newNodeParent, + newNodeName = newNodeName + ) + ).thenReturn( expected ) val actual = underTest(nodeToCopy, newNodeParent, newNodeName) From 011128885d0dba5e5a19cb6732d284de111bc0c9 Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Mon, 20 May 2024 22:48:08 +1200 Subject: [PATCH 122/261] SAO-1232: T16099240 fix ui issue in file info page --- .../fileinfo/view/FileInfoContent.kt | 2 +- .../fileinfo/view/FileInfoHeader.kt | 6 +- .../fileinfo/view/FileInfoScreen.kt | 7 +- .../layouts/CollapsibleHeaderWithTitle.kt | 5 +- .../layouts/ScaffoldWithCollapsibleHeader.kt | 96 +++++++++---------- 5 files changed, 55 insertions(+), 61 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoContent.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoContent.kt index e5b14f0080..05262f82e0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoContent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoContent.kt @@ -81,7 +81,7 @@ internal fun FileInfoContent( text = stringResource(id = R.string.contact_approve_credentials_toolbar_title), style = MaterialTheme.typography.subtitle2.copy(color = MaterialTheme.colors.secondary), modifier = Modifier - .padding(bottom = 16.dp, start = paddingStartDefault.dp, end = 16.dp) + .padding(bottom = 16.dp, start = 72.dp, end = 16.dp) .clickable(onClick = { onVerifyContactClick(contactItem.email) }) .testTag(TEST_TAG_LOCATION) ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoHeader.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoHeader.kt index 14fa0f074d..feb2b585eb 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoHeader.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoHeader.kt @@ -38,9 +38,9 @@ internal fun FileInfoHeader( modifier = Modifier .testTag(TEST_TAG_ICON) .constrainAs(icon) { - start.linkTo(parent.start, 16.dp) - end.linkTo(parent.end, 16.dp) - top.linkTo(titleConstrainedLayoutReference.bottom, 32.dp) + start.linkTo(parent.start) + end.linkTo(parent.end) + top.linkTo(titleConstrainedLayoutReference.bottom, 16.dp) width = Dimension.value(96.dp) height = Dimension.value(96.dp) }, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoScreen.kt index 3ffafff46e..ed9bba945a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp import de.palm.composestateevents.consumed import mega.privacy.android.app.R import mega.privacy.android.app.presentation.contact.view.contactItemForPreviews @@ -116,6 +117,7 @@ internal fun FileInfoScreen( ?.takeIf { viewState.isIncomingSharedNode }, ) }, + headerSpacerHeight = if (viewState.iconResource != null && !viewState.hasPreview) (MAX_HEADER_HEIGHT + APP_BAR_HEIGHT).dp else MAX_HEADER_HEIGHT.dp, headerBelowTopBar = actionModeSelect, //actionMode doesn't have collapsible title, the header needs to be drawn below the app bar snackbarHost = { SnackbarHost(hostState = snackBarHostState) { data -> @@ -346,4 +348,7 @@ internal class FileInfoViewStatePreviewsProvider : PreviewParameterProvider Unit)? = null, content: @Composable BoxScope.() -> Unit, -) = Box( - modifier = modifier - .fillMaxWidth() -) { +) = Box(modifier = modifier.fillMaxWidth()) { content() val titleDisplacement = LocalCollapsibleHeaderTitleTransition.current.offset Box( diff --git a/core-ui/src/main/java/mega/privacy/android/core/ui/controls/layouts/ScaffoldWithCollapsibleHeader.kt b/core-ui/src/main/java/mega/privacy/android/core/ui/controls/layouts/ScaffoldWithCollapsibleHeader.kt index acb726a1df..9ddf4c0752 100644 --- a/core-ui/src/main/java/mega/privacy/android/core/ui/controls/layouts/ScaffoldWithCollapsibleHeader.kt +++ b/core-ui/src/main/java/mega/privacy/android/core/ui/controls/layouts/ScaffoldWithCollapsibleHeader.kt @@ -84,6 +84,7 @@ fun ScaffoldWithCollapsibleHeader( floatingActionButton: @Composable () -> Unit = {}, titleDisplacementFactor: Float = 0.5f, headerBelowTopBar: Boolean = false, + headerSpacerHeight: Dp = SPACER_HEIGHT.dp, snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }, content: @Composable () -> Unit, ) { @@ -107,23 +108,20 @@ fun ScaffoldWithCollapsibleHeader( val headerHeight by remember { derivedStateOf { - (HEADER_MAX_HEIGHT - (scrollState.value / density)) - .coerceAtLeast(HEADER_MIN_HEIGHT) + (HEADER_MAX_HEIGHT - (scrollState.value / density)).coerceAtLeast(HEADER_MIN_HEIGHT) } } val headerAlpha by remember { derivedStateOf { - ((headerHeight - HEADER_GONE_HEIGHT) - / (HEADER_START_GONE_HEIGHT - HEADER_GONE_HEIGHT)) + ((headerHeight - HEADER_GONE_HEIGHT) / (HEADER_START_GONE_HEIGHT - HEADER_GONE_HEIGHT)) .coerceIn(0f, 1f) } } val topBarBackgroundAlpha by remember(hasHeaderBelowSystemBar) { derivedStateOf { if (hasHeaderBelowSystemBar) { - (topBarOpacityTransitionDelta(headerHeight) * 10) - .coerceIn(0f, 1f) + (topBarOpacityTransitionDelta(headerHeight) * 10).coerceIn(0f, 1f) } else { 1f } @@ -168,30 +166,29 @@ fun ScaffoldWithCollapsibleHeader( val collapsibleHeaderTitleTransition by remember { derivedStateOf { //The offset is 0 when it's collapsed, and it grows [titleDisplacementFactor] of the expansion when expanded. - val offset = ((headerHeight - HEADER_GONE_HEIGHT) - * titleDisplacementFactor).coerceAtLeast(0f).dp + val offset = + ((headerHeight - HEADER_GONE_HEIGHT) * titleDisplacementFactor).coerceAtLeast(0f).dp // alpha transition will be done in last 20dp, title alpha will start earlier because we want the title to be opaque all the time (to views with 0.5f alpha are like 0.75 alpha, not 1f alpha) val startShowingToolbarTitle = 20.dp val startHidingHeaderTitle = 15.dp val headerTitleAlpha = (offset / startHidingHeaderTitle).coerceIn(0f, 1f) - val toolbarTitleAlpha = 1 - - ((offset - startHidingHeaderTitle) / (startShowingToolbarTitle - startHidingHeaderTitle)) - .coerceIn(0f, 1f) + val toolbarTitleAlpha = + 1 - ((offset - startHidingHeaderTitle) / (startShowingToolbarTitle - startHidingHeaderTitle)) + .coerceIn(0f, 1f) CollapsibleHeaderTitleTransition(offset, headerTitleAlpha, toolbarTitleAlpha) } } //set the status bar color to match toolbar color if (!LocalView.current.isInEditMode) { - val statusColor = MegaTheme.colors.background.pageBackground - .copy(LocalMegaAppBarColors.current.backgroundAlpha) - .surfaceColorAtElevation(absoluteElevation = appBarElevation) - .copy(alpha = topBarBackgroundAlpha) + val statusColor = + MegaTheme.colors.background.pageBackground.copy(LocalMegaAppBarColors.current.backgroundAlpha) + .surfaceColorAtElevation(absoluteElevation = appBarElevation) + .copy(alpha = topBarBackgroundAlpha) val systemUiController = rememberSystemUiController() DisposableEffect(systemUiController, statusColor) { systemUiController.setStatusBarColor( - color = statusColor, - darkIcons = systemUiController.statusBarDarkContentEnabled + color = statusColor, darkIcons = systemUiController.statusBarDarkContentEnabled ) onDispose { } } @@ -200,18 +197,16 @@ fun ScaffoldWithCollapsibleHeader( //draw the composables val (headerRef, headerBelowRef) = createRefs() if (headerIncludingSystemBar != null && headerAlpha > 0) { - Box( - modifier = Modifier - .constrainAs(headerBelowRef) { - top.linkTo(parent.top) - start.linkTo(parent.start) - end.linkTo(parent.end) - bottom.linkTo(headerRef.bottom) - height = Dimension.fillToConstraints - width = Dimension.fillToConstraints - } - .alpha(headerAlpha) - ) { + Box(modifier = Modifier + .constrainAs(headerBelowRef) { + top.linkTo(parent.top) + start.linkTo(parent.start) + end.linkTo(parent.end) + bottom.linkTo(headerRef.bottom) + height = Dimension.fillToConstraints + width = Dimension.fillToConstraints + } + .alpha(headerAlpha)) { CompositionLocalProvider( LocalMegaAppBarColors provides MegaAppBarColors( iconsTintColor = iconTintColor, @@ -266,10 +261,9 @@ fun ScaffoldWithCollapsibleHeader( .verticalScroll(scrollState) .padding(innerPadding) ) { - Spacer(Modifier.height(SPACER_HEIGHT.dp)) //to give space for the header (that it's outside this column) + Spacer(Modifier.height(headerSpacerHeight)) //to give space for the header (that it's outside this column) Box( - modifier = Modifier - .heightIn(min = this@BoxWithConstraints.maxHeight), + modifier = Modifier.heightIn(min = this@BoxWithConstraints.maxHeight), ) { content() } @@ -304,18 +298,16 @@ private fun ConstraintLayoutScope.DrawHeader( subtitleColor: Color, header: @Composable BoxScope.() -> Unit, ) { - Box( - modifier = Modifier - .statusBarsPadding() - .constrainAs(headerRef) { - top.linkTo(parent.top) - start.linkTo(parent.start) - end.linkTo(parent.end) - height = Dimension.wrapContent - width = Dimension.fillToConstraints - } - .alpha(collapsibleHeaderTitleTransition.headerAlpha) - ) { + Box(modifier = Modifier + .statusBarsPadding() + .constrainAs(headerRef) { + top.linkTo(parent.top) + start.linkTo(parent.start) + end.linkTo(parent.end) + height = Dimension.wrapContent + width = Dimension.fillToConstraints + } + .alpha(collapsibleHeaderTitleTransition.headerAlpha)) { if (headerAlpha > 0) { CompositionLocalProvider( LocalMegaAppBarColors provides MegaAppBarColors( @@ -352,13 +344,12 @@ internal val LocalCollapsibleHeaderTitleTransition = internal const val APP_BAR_HEIGHT = 56f private const val HEADER_MIN_HEIGHT = APP_BAR_HEIGHT private const val HEADER_MAX_HEIGHT = HEADER_MIN_HEIGHT + 96f -private const val HEADER_START_GONE_HEIGHT = HEADER_MIN_HEIGHT + 96f -private const val HEADER_GONE_HEIGHT = HEADER_MIN_HEIGHT + 56f -private const val SPACER_HEIGHT = HEADER_MAX_HEIGHT - APP_BAR_HEIGHT + 56f +private const val HEADER_START_GONE_HEIGHT = HEADER_MIN_HEIGHT + 76f +private const val HEADER_GONE_HEIGHT = HEADER_MIN_HEIGHT + 18f +private const val SPACER_HEIGHT = HEADER_MAX_HEIGHT - APP_BAR_HEIGHT private fun topBarOpacityTransitionDelta(headerHeight: Float) = - 1 - ((headerHeight - HEADER_MIN_HEIGHT) - / (HEADER_GONE_HEIGHT - HEADER_MIN_HEIGHT)) + 1 - ((headerHeight - HEADER_MIN_HEIGHT) / (HEADER_GONE_HEIGHT - HEADER_MIN_HEIGHT)) .coerceIn(0f, 1f) @Composable @@ -438,8 +429,7 @@ private fun ScaffoldWithCollapsibleHeaderWithSubtitlePreview() { title = title, subtitle = subtitle, titleIcons = titleIcons, - ) { - } + ) {} }, headerIncludingSystemBar = { Header() @@ -471,6 +461,8 @@ private fun Header() = Box( ) private fun getSampleToolbarActions(): List = listOf( - object : MenuActionString(iconPackR.drawable.ic_alert_circle_regular_medium_outline, R.string.password_text, "circle") {}, + object : MenuActionString( + iconPackR.drawable.ic_alert_circle_regular_medium_outline, R.string.password_text, "circle" + ) {}, object : MenuActionWithoutIcon(R.string.password_text, "password") {}, ) \ No newline at end of file From 40d0fbcbf5fdac0b28514ae1419afbfd40444965 Mon Sep 17 00:00:00 2001 From: Sida Qian Date: Tue, 21 May 2024 13:03:37 +1200 Subject: [PATCH 123/261] SAO-1346: T16078520 Add Separate Chips Events (Release) --- .../search/SearchActivityViewModel.kt | 10 +-- .../search/SearchFilterOptionExtension.kt | 71 +++++++++++++++++++ gradle/catalogs/lib.versions.toml | 2 +- 3 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/mega/privacy/android/app/presentation/search/SearchFilterOptionExtension.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index e688171d45..7b0c3efb5f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import mega.privacy.android.analytics.Analytics import mega.privacy.android.app.extensions.updateItemAt import mega.privacy.android.app.featuretoggle.AppFeatures import mega.privacy.android.app.presentation.data.NodeUIItem @@ -47,9 +46,6 @@ import mega.privacy.android.domain.usecase.search.GetSearchCategoriesUseCase import mega.privacy.android.domain.usecase.search.SearchUseCase import mega.privacy.android.domain.usecase.viewtype.MonitorViewType import mega.privacy.android.domain.usecase.viewtype.SetViewType -import mega.privacy.mobile.analytics.event.SearchDateAddedFilterClickedEvent -import mega.privacy.mobile.analytics.event.SearchFileTypeOptionClickedEvent -import mega.privacy.mobile.analytics.event.SearchLastModifiedOptionClickedEvent import nz.mega.sdk.MegaApiJava import timber.log.Timber import javax.inject.Inject @@ -488,7 +484,7 @@ class SearchActivityViewModel @Inject constructor( ) } ) - Analytics.tracker.trackEvent(SearchFileTypeOptionClickedEvent(typeOption?.name.orEmpty())) + typeOption?.trackAsAnalyticsEvent() } DATE_MODIFIED -> { @@ -503,7 +499,7 @@ class SearchActivityViewModel @Inject constructor( ) } ) - Analytics.tracker.trackEvent(SearchLastModifiedOptionClickedEvent(dateModifiedOption?.name.orEmpty())) + dateModifiedOption?.trackAsLastModifiedAnalyticsEvent() } DATE_ADDED -> { @@ -518,7 +514,7 @@ class SearchActivityViewModel @Inject constructor( ) } ) - Analytics.tracker.trackEvent(SearchDateAddedFilterClickedEvent(dateAddedOption?.name.orEmpty())) + dateAddedOption?.trackAsDateAddedAnalyticsEvent() } } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFilterOptionExtension.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFilterOptionExtension.kt new file mode 100644 index 0000000000..bdaf9908b4 --- /dev/null +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchFilterOptionExtension.kt @@ -0,0 +1,71 @@ +package mega.privacy.android.app.presentation.search + +import mega.privacy.android.analytics.Analytics +import mega.privacy.android.domain.entity.search.DateFilterOption +import mega.privacy.android.domain.entity.search.TypeFilterOption +import mega.privacy.mobile.analytics.event.SearchDateAddedLastSevenDaysClickedEvent +import mega.privacy.mobile.analytics.event.SearchDateAddedLastThirtyDaysClickedEvent +import mega.privacy.mobile.analytics.event.SearchDateAddedLastYearClickedEvent +import mega.privacy.mobile.analytics.event.SearchDateAddedOlderClickedEvent +import mega.privacy.mobile.analytics.event.SearchDateAddedThisYearClickedEvent +import mega.privacy.mobile.analytics.event.SearchDateAddedTodayClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeAudioOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeDocumentsOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeFolderOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeImagesOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeOtherOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypePdfOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypePresentationOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeSpreadsheetOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchFileTypeVideoOptionClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedLastSevenDaysClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedLastThirtyDaysClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedLastYearClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedOlderClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedThisYearClickedEvent +import mega.privacy.mobile.analytics.event.SearchLastModifiedTodayClickedEvent + +/** + * Track the correct event on each file type filter option + */ +internal fun TypeFilterOption.trackAsAnalyticsEvent() = Analytics.tracker.trackEvent( + when (this) { + TypeFilterOption.Images -> SearchFileTypeImagesOptionClickedEvent + TypeFilterOption.Documents -> SearchFileTypeDocumentsOptionClickedEvent + TypeFilterOption.Audio -> SearchFileTypeAudioOptionClickedEvent + TypeFilterOption.Video -> SearchFileTypeVideoOptionClickedEvent + TypeFilterOption.Pdf -> SearchFileTypePdfOptionClickedEvent + TypeFilterOption.Presentation -> SearchFileTypePresentationOptionClickedEvent + TypeFilterOption.Spreadsheet -> SearchFileTypeSpreadsheetOptionClickedEvent + TypeFilterOption.Folder -> SearchFileTypeFolderOptionClickedEvent + TypeFilterOption.Other -> SearchFileTypeOtherOptionClickedEvent + } +) + +/** + * Track the correct event on each last modified filter option + */ +internal fun DateFilterOption.trackAsLastModifiedAnalyticsEvent() = Analytics.tracker.trackEvent( + when (this) { + DateFilterOption.Today -> SearchLastModifiedTodayClickedEvent + DateFilterOption.Last7Days -> SearchLastModifiedLastSevenDaysClickedEvent + DateFilterOption.Last30Days -> SearchLastModifiedLastThirtyDaysClickedEvent + DateFilterOption.ThisYear -> SearchLastModifiedThisYearClickedEvent + DateFilterOption.LastYear -> SearchLastModifiedLastYearClickedEvent + DateFilterOption.Older -> SearchLastModifiedOlderClickedEvent + } +) + +/** + * Track the correct event on each date added filter option + */ +internal fun DateFilterOption.trackAsDateAddedAnalyticsEvent() = Analytics.tracker.trackEvent( + when (this) { + DateFilterOption.Today -> SearchDateAddedTodayClickedEvent + DateFilterOption.Last7Days -> SearchDateAddedLastSevenDaysClickedEvent + DateFilterOption.Last30Days -> SearchDateAddedLastThirtyDaysClickedEvent + DateFilterOption.ThisYear -> SearchDateAddedThisYearClickedEvent + DateFilterOption.LastYear -> SearchDateAddedLastYearClickedEvent + DateFilterOption.Older -> SearchDateAddedOlderClickedEvent + } +) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 52a1c82283..52e6142446 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -71,7 +71,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:20240510.025619" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240520.234058" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.5.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From efaa1f95e5cea61ec0dc6d823b0ae4f135d1bc25 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 21 May 2024 09:06:33 +0700 Subject: [PATCH 124/261] AND-18791: Fix getMyChatFilesFolder non-fatal exception --- .../SendToChatToolbarMenuItem.kt | 19 ++++++++++++------- .../repository/FileSystemRepositoryImpl.kt | 6 +++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt b/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt index b28a5c873c..11f3953bdf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt @@ -12,6 +12,7 @@ import mega.privacy.android.core.ui.model.MenuActionWithIcon import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.usecase.chat.GetNodeToAttachUseCase +import timber.log.Timber import javax.inject.Inject /** @@ -41,14 +42,18 @@ class SendToChatToolbarMenuItem @Inject constructor( ): () -> Unit = { onDismiss() parentScope.launch { - withContext(NonCancellable) { - val attachableNodes = selectedNodes.mapNotNull { - if (it is TypedFileNode) { - getNodeToAttachUseCase(it) - } else null + runCatching { + withContext(NonCancellable) { + val attachableNodes = selectedNodes.mapNotNull { + if (it is TypedFileNode) { + getNodeToAttachUseCase(it) + } else null + } + parentScope.ensureActive() + actionHandler(menuAction, attachableNodes) } - parentScope.ensureActive() - actionHandler(menuAction, attachableNodes) + }.onFailure { + Timber.e(it, "Error getting node to attach") } } } diff --git a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt index c80e883a5e..d1a41cbf49 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt @@ -273,7 +273,11 @@ internal class FileSystemRepositoryImpl @Inject constructor( .catch { Timber.e(it) } .flowOn(ioDispatcher) .collect { - getMyChatsFilesFolderIdFromGateway() + runCatching { + getMyChatsFilesFolderIdFromGateway() + }.onFailure { + Timber.e(it) + } } } } From 09e03167c834c108e7075b9ab488b9a00fd032c4 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 21 May 2024 09:42:50 +0700 Subject: [PATCH 125/261] AND-18791: Fix getMyChatFilesFolder non-fatal exception --- .../app/presentation/imagepreview/ImagePreviewViewModel.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt index d5d50266b0..8646605309 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewViewModel.kt @@ -77,7 +77,6 @@ import timber.log.Timber import java.io.File import java.lang.ref.WeakReference import javax.inject.Inject - @HiltViewModel class ImagePreviewViewModel @Inject constructor( private val savedStateHandle: SavedStateHandle, @@ -872,13 +871,13 @@ class ImagePreviewViewModel @Inject constructor( ) } - private suspend fun isHidingActionAllowed(): Boolean = + private suspend fun isHidingActionAllowed(): Boolean = runCatching { (getParentNodeUseCase(NodeId(currentImageNodeIdValue))?.id?.longValue ?: 0) !in listOf( getPrimarySyncHandleUseCase(), getSecondarySyncHandleUseCase(), getMyChatsFilesFolderIdUseCase(), ) - + }.getOrElse { false } companion object { const val IMAGE_NODE_FETCHER_SOURCE = "image_node_fetcher_source" @@ -888,3 +887,4 @@ class ImagePreviewViewModel @Inject constructor( const val IMAGE_PREVIEW_IS_FOREIGN = "image_preview_is_foreign" } } + From 7bfb79977b999462bb0131fc52d6ce93afe41169 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 21 May 2024 09:06:33 +0700 Subject: [PATCH 126/261] AND-18791: Fix getMyChatFilesFolder non-fatal exception --- .../SendToChatToolbarMenuItem.kt | 19 ++++++++++++------- .../repository/FileSystemRepositoryImpl.kt | 6 +++++- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt b/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt index b28a5c873c..11f3953bdf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/node/model/toolbarmenuitems/SendToChatToolbarMenuItem.kt @@ -12,6 +12,7 @@ import mega.privacy.android.core.ui.model.MenuActionWithIcon import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.entity.node.TypedNode import mega.privacy.android.domain.usecase.chat.GetNodeToAttachUseCase +import timber.log.Timber import javax.inject.Inject /** @@ -41,14 +42,18 @@ class SendToChatToolbarMenuItem @Inject constructor( ): () -> Unit = { onDismiss() parentScope.launch { - withContext(NonCancellable) { - val attachableNodes = selectedNodes.mapNotNull { - if (it is TypedFileNode) { - getNodeToAttachUseCase(it) - } else null + runCatching { + withContext(NonCancellable) { + val attachableNodes = selectedNodes.mapNotNull { + if (it is TypedFileNode) { + getNodeToAttachUseCase(it) + } else null + } + parentScope.ensureActive() + actionHandler(menuAction, attachableNodes) } - parentScope.ensureActive() - actionHandler(menuAction, attachableNodes) + }.onFailure { + Timber.e(it, "Error getting node to attach") } } } diff --git a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt index c80e883a5e..d1a41cbf49 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt @@ -273,7 +273,11 @@ internal class FileSystemRepositoryImpl @Inject constructor( .catch { Timber.e(it) } .flowOn(ioDispatcher) .collect { - getMyChatsFilesFolderIdFromGateway() + runCatching { + getMyChatsFilesFolderIdFromGateway() + }.onFailure { + Timber.e(it) + } } } } From 9991c805ea7671eb50a169b91866e1495c79aaee Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Tue, 21 May 2024 15:52:53 +1200 Subject: [PATCH 127/261] AND-15164: Fix getMyChatFilesFolder no fatal exception --- .../bottomsheet/NodeOptionsViewModel.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsViewModel.kt index 2d21ff4f38..6a49ccd00b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/bottomsheet/NodeOptionsViewModel.kt @@ -111,14 +111,16 @@ class NodeOptionsViewModel @Inject constructor( } viewModelScope.launch { - val isHiddenNodesOnboarded = isHiddenNodesOnboardedUseCase() - val isHidingActionAllowed = isHidingActionAllowed(_state.value.node?.handle ?: 0) - _state.update { - it.copy( - isHiddenNodesOnboarded = isHiddenNodesOnboarded, - isHidingActionAllowed = isHidingActionAllowed, - ) - } + runCatching { + val isHiddenNodesOnboarded = isHiddenNodesOnboardedUseCase() + val isHidingActionAllowed = isHidingActionAllowed(_state.value.node?.handle ?: 0) + _state.update { + it.copy( + isHiddenNodesOnboarded = isHiddenNodesOnboarded, + isHidingActionAllowed = isHidingActionAllowed, + ) + } + }.onFailure { Timber.e(it) } } } From c2f4375fa54647294dbee471b87fee56d746472e Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Tue, 21 May 2024 12:24:14 +0530 Subject: [PATCH 128/261] SAO-1232: T16099306 fix ui issue in file info page --- .../offlinefileinfocompose/view/OfflineFileInfoScreen.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/offline/offlinefileinfocompose/view/OfflineFileInfoScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/offline/offlinefileinfocompose/view/OfflineFileInfoScreen.kt index dd76fa999f..97abc7e0c7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/offline/offlinefileinfocompose/view/OfflineFileInfoScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/offline/offlinefileinfocompose/view/OfflineFileInfoScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp import mega.privacy.android.app.MimeTypeThumbnail import mega.privacy.android.app.R import mega.privacy.android.app.presentation.fileinfo.view.FileInfoHeader @@ -76,7 +77,8 @@ internal fun OfflineFileInfoScreen( iconResource = iconResource, accessPermissionDescription = null, ) - } + }, + headerSpacerHeight = if (iconResource != null) (MAX_HEADER_HEIGHT + APP_BAR_HEIGHT).dp else MAX_HEADER_HEIGHT.dp, ) { OfflineFileInfoContent(uiState = uiState, onRemoveFromOffline = { showRemoveFromOfflineDialog = true @@ -154,3 +156,6 @@ internal class OfflineFileInfoViewStatePreviewsProvider : ) } } + +private const val MAX_HEADER_HEIGHT = 96 +private const val APP_BAR_HEIGHT = 56 From 5c2870394b90056c913fbfbb9e7dfedc43cd745a Mon Sep 17 00:00:00 2001 From: Sougandh Mp Date: Tue, 21 May 2024 18:12:55 +0530 Subject: [PATCH 129/261] SAO-1232: T16099304 fix ui issue in file info page --- .../android/app/presentation/filelink/view/FileLinkView.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/filelink/view/FileLinkView.kt b/app/src/main/java/mega/privacy/android/app/presentation/filelink/view/FileLinkView.kt index 551b45b2ef..70bb720d98 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/filelink/view/FileLinkView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/filelink/view/FileLinkView.kt @@ -163,6 +163,7 @@ internal fun FileLinkView( ) } }, + headerSpacerHeight = if (viewState.iconResource != null) (MAX_HEADER_HEIGHT + APP_BAR_HEIGHT).dp else MAX_HEADER_HEIGHT.dp, modifier = modifier, ) { FileLinkContent( @@ -296,3 +297,5 @@ private fun PreviewFileLinkView() { internal const val animationDuration = 300 internal const val animationScale = 0.2f internal val animationSpecs = TweenSpec(durationMillis = animationDuration) +private const val MAX_HEADER_HEIGHT = 96 +private const val APP_BAR_HEIGHT = 56 From 1fd5efa620a227edb040d6d8e7aae0dbb897e95b Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Wed, 22 May 2024 17:27:44 +1200 Subject: [PATCH 130/261] AP-1154: Fix for checking on the Pro Flexi Account in My Account Screen --- .../presentation/myaccount/MyAccountHomeViewModel.kt | 2 +- .../presentation/myaccount/view/MyAccountHomeView.kt | 11 +++++------ .../myaccount/MyAccountHomeViewModelTest.kt | 2 +- .../presentation/myaccount/MyAccountHomeViewTest.kt | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModel.kt index 2a789d6934..acd870a826 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModel.kt @@ -188,7 +188,7 @@ class MyAccountHomeViewModel @Inject constructor( it.copy( accountType = accountDetails.accountTypeIdentifier, isBusinessAccount = accountDetails.isBusinessAccount && accountDetails.accountTypeIdentifier == AccountType.BUSINESS, - isProFlexiAccount = accountDetails.isBusinessAccount && accountDetails.accountTypeIdentifier == AccountType.PRO_FLEXI, + isProFlexiAccount = accountDetails.accountTypeIdentifier == AccountType.PRO_FLEXI, isMasterBusinessAccount = accountDetails.isMasterBusinessAccount, ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/myaccount/view/MyAccountHomeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/myaccount/view/MyAccountHomeView.kt index 703dcd50a5..807a3571c2 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/myaccount/view/MyAccountHomeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/myaccount/view/MyAccountHomeView.kt @@ -486,6 +486,7 @@ private fun AccountInfoSection( var showChangeApiServerDialog by rememberSaveable { mutableStateOf(false) } var showChangeSFUIdDialog by rememberSaveable { mutableStateOf(false) } + val isUpgradeButtonEnabled = (uiState.isBusinessAccount || uiState.isProFlexiAccount).not() Column( modifier = modifier @@ -499,11 +500,9 @@ private fun AccountInfoSection( .wrapContentHeight() .padding(start = 14.dp, end = 14.dp, top = 12.dp, bottom = 8.dp), accountType = uiState.accountType, - showButton = (uiState.isBusinessAccount || uiState.isProFlexiAccount).not(), + showUpgradeButton = isUpgradeButtonEnabled, onButtonClickListener = { - if (uiState.isBusinessAccount.not()) { - uiActions.onUpgradeAccount() - } + uiActions.onUpgradeAccount() } ) @@ -680,7 +679,7 @@ private fun getAccountDescriptionResId(accountType: AccountType?): Int = @Composable internal fun AccountTypeSection( accountType: AccountType?, - showButton: Boolean, + showUpgradeButton: Boolean, onButtonClickListener: () -> Unit, modifier: Modifier = Modifier, ) { @@ -734,7 +733,7 @@ internal fun AccountTypeSection( color = MaterialTheme.colors.textColorPrimary, ) - if (showButton) { + if (showUpgradeButton) { RaisedDefaultMegaButton( textId = R.string.my_account_upgrade_pro, onClick = onButtonClickListener, diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModelTest.kt index 1213aa095a..8b55fbb8e7 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewModelTest.kt @@ -291,7 +291,7 @@ class MyAccountHomeViewModelTest { underTest.uiState.test { val state = awaitItem() assertThat(state.accountType).isEqualTo(expected.accountTypeIdentifier) - assertThat(state.isProFlexiAccount).isEqualTo(expected.isBusinessAccount && expected.accountTypeIdentifier == AccountType.PRO_FLEXI) + assertThat(state.isProFlexiAccount).isEqualTo(expected.accountTypeIdentifier == AccountType.PRO_FLEXI) assertThat(state.isBusinessProFlexiStatusActive).isTrue() } } diff --git a/app/src/testDebug/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewTest.kt b/app/src/testDebug/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewTest.kt index 33f43e35a9..5177bbbcbb 100644 --- a/app/src/testDebug/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewTest.kt +++ b/app/src/testDebug/java/test/mega/privacy/android/app/presentation/myaccount/MyAccountHomeViewTest.kt @@ -524,7 +524,7 @@ class MyAccountHomeViewTest { composeTestRule.setContent { AccountTypeSection( accountType = accountType, - showButton = true, + showUpgradeButton = true, onButtonClickListener = {} ) } From d2a849a0e66e488d477636a641a71fe5dc511b13 Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Fri, 24 May 2024 12:23:13 +1200 Subject: [PATCH 131/261] AND-18845: Fix DefaultGetNodeListByIds Null point exception --- .../android/app/domain/usecase/DefaultGetNodeListByIds.kt | 4 ++-- .../photos/albums/albumcontent/AlbumContentViewModel.kt | 6 ++++-- .../photos/mediadiscovery/MediaDiscoveryViewModel.kt | 3 ++- .../photos/timeline/viewmodel/TimelineViewModel.kt | 4 +++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/domain/usecase/DefaultGetNodeListByIds.kt b/app/src/main/java/mega/privacy/android/app/domain/usecase/DefaultGetNodeListByIds.kt index 56da6b5a1f..c920b8b793 100644 --- a/app/src/main/java/mega/privacy/android/app/domain/usecase/DefaultGetNodeListByIds.kt +++ b/app/src/main/java/mega/privacy/android/app/domain/usecase/DefaultGetNodeListByIds.kt @@ -12,8 +12,8 @@ class DefaultGetNodeListByIds @Inject constructor( ) : GetNodeListByIds { override suspend fun invoke(ids: List): List = withContext(ioDispatcher) { - ids.map { - getNodeByHandle(it)!! + ids.mapNotNull { + getNodeByHandle(it) } } } \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentViewModel.kt index f76e0bed74..608c7cd48e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/albums/albumcontent/AlbumContentViewModel.kt @@ -457,8 +457,10 @@ internal class AlbumContentViewModel @Inject constructor( } suspend fun getSelectedNodes(): List { - val selectedPhotoIds = _state.value.selectedPhotos.map { it.id } - return getNodeListByIds(selectedPhotoIds) + return runCatching { + val selectedPhotoIds = _state.value.selectedPhotos.map { it.id } + getNodeListByIds(selectedPhotoIds) + }.onFailure { Timber.e(it) }.getOrDefault(emptyList()) } fun updateAlbumName(title: String, albumNames: List) = viewModelScope.launch { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryViewModel.kt index bde52f7f44..266d3b5e4c 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryViewModel.kt @@ -441,12 +441,13 @@ class MediaDiscoveryViewModel @Inject constructor( suspend fun getSelectedNodes() = getNodesByIds(_state.value.selectedPhotoIds.toList()) - private suspend fun getNodesByIds(ids: List) = + private suspend fun getNodesByIds(ids: List) = runCatching { if (fromFolderLink == true) { getPublicNodeListByIds(ids) } else { getNodeListByIds(ids) } + }.onFailure { Timber.e(it) }.getOrDefault(emptyList()) fun setCurrentSort(sort: Sort) { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/viewmodel/TimelineViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/viewmodel/TimelineViewModel.kt index d03d68162c..10e80fa9a9 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/viewmodel/TimelineViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/viewmodel/TimelineViewModel.kt @@ -555,8 +555,10 @@ class TimelineViewModel @Inject constructor( * * @return a list of Nodes */ - suspend fun getSelectedNodes(): List = + suspend fun getSelectedNodes(): List = runCatching { getNodeListByIds(selectedPhotosIds.toList()) + }.onFailure { Timber.e(it) }.getOrDefault(emptyList()) + /** * Establishes the initial Camera Uploads preferences From 3d7d43121e3f9bce0533dd0f43e6a763dd986103 Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Fri, 24 May 2024 13:05:41 +1200 Subject: [PATCH 132/261] update latest string release/v13.2 --- app/src/main/res/values-ar/strings.xml | 55 +++++----------- .../values-ar/strings_document_scanner.xml | 6 +- .../main/res/values-ar/strings_sdk_errors.xml | 4 +- app/src/main/res/values-de/strings.xml | 35 ++--------- .../main/res/values-de/strings_sdk_errors.xml | 4 +- app/src/main/res/values-es/strings.xml | 37 ++--------- .../main/res/values-es/strings_sdk_errors.xml | 4 +- app/src/main/res/values-fr/strings.xml | 29 +-------- .../values-fr/strings_document_scanner.xml | 4 +- .../main/res/values-fr/strings_sdk_errors.xml | 4 +- app/src/main/res/values-in/strings.xml | 46 +++----------- .../values-in/strings_document_scanner.xml | 4 +- .../main/res/values-in/strings_sdk_errors.xml | 4 +- app/src/main/res/values-it/strings.xml | 63 ++++++------------- .../values-it/strings_document_scanner.xml | 2 +- .../main/res/values-it/strings_sdk_errors.xml | 4 +- app/src/main/res/values-ja/strings.xml | 29 +-------- .../values-ja/strings_document_scanner.xml | 6 +- .../main/res/values-ja/strings_sdk_errors.xml | 4 +- app/src/main/res/values-ko/strings.xml | 41 +++--------- .../values-ko/strings_document_scanner.xml | 4 +- .../main/res/values-ko/strings_sdk_errors.xml | 4 +- app/src/main/res/values-nl/strings.xml | 41 +++--------- .../values-nl/strings_document_scanner.xml | 8 +-- .../main/res/values-nl/strings_sdk_errors.xml | 4 +- app/src/main/res/values-pl/strings.xml | 35 ++--------- .../values-pl/strings_document_scanner.xml | 2 +- .../main/res/values-pl/strings_sdk_errors.xml | 4 +- app/src/main/res/values-pt/strings.xml | 29 +-------- .../values-pt/strings_document_scanner.xml | 2 +- .../main/res/values-pt/strings_sdk_errors.xml | 4 +- app/src/main/res/values-ro/strings.xml | 45 +++---------- .../values-ro/strings_document_scanner.xml | 4 +- .../main/res/values-ro/strings_sdk_errors.xml | 4 +- app/src/main/res/values-ru/strings.xml | 29 +-------- .../main/res/values-ru/strings_sdk_errors.xml | 4 +- app/src/main/res/values-th/strings.xml | 33 +--------- .../main/res/values-th/strings_sdk_errors.xml | 4 +- app/src/main/res/values-vi/strings.xml | 35 ++--------- .../values-vi/strings_document_scanner.xml | 8 +-- .../main/res/values-vi/strings_sdk_errors.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 39 ++---------- .../strings_document_scanner.xml | 2 +- .../res/values-zh-rCN/strings_sdk_errors.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 35 ++--------- .../strings_document_scanner.xml | 2 +- .../res/values-zh-rTW/strings_sdk_errors.xml | 4 +- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 6 +- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 12 ++-- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 8 +-- .../strings_device_center_feature.xml | 4 +- .../strings_device_center_feature.xml | 8 +-- .../strings_device_center_feature.xml | 2 +- .../strings_device_center_feature.xml | 12 ++-- .../strings_device_center_feature.xml | 12 ++-- .../strings_device_center_feature.xml | 14 ++--- .../strings_device_center_feature.xml | 6 +- .../strings_device_center_feature.xml | 6 +- .../strings_device_center_feature.xml | 10 +-- .../strings_device_center_feature.xml | 14 ++--- .../strings_device_center_feature.xml | 14 ++--- .../res/values-ar/strings_sync_feature.xml | 14 ----- .../res/values-de/strings_sync_feature.xml | 14 ----- .../res/values-es/strings_sync_feature.xml | 14 ----- .../res/values-fr/strings_sync_feature.xml | 14 ----- .../res/values-in/strings_sync_feature.xml | 14 ----- .../res/values-it/strings_sync_feature.xml | 14 ----- .../res/values-ja/strings_sync_feature.xml | 14 ----- .../res/values-ko/strings_sync_feature.xml | 14 ----- .../res/values-nl/strings_sync_feature.xml | 16 +---- .../res/values-pl/strings_sync_feature.xml | 16 +---- .../res/values-pt/strings_sync_feature.xml | 16 +---- .../res/values-ro/strings_sync_feature.xml | 16 +---- .../res/values-ru/strings_sync_feature.xml | 14 ----- .../res/values-th/strings_sync_feature.xml | 14 ----- .../res/values-vi/strings_sync_feature.xml | 14 ----- .../values-zh-rCN/strings_sync_feature.xml | 14 ----- .../values-zh-rTW/strings_sync_feature.xml | 18 +----- .../src/main/res/values-ar/strings_shared.xml | 36 +++++++++-- .../src/main/res/values-de/strings_shared.xml | 28 ++++++++- .../src/main/res/values-es/strings_shared.xml | 28 ++++++++- .../src/main/res/values-fr/strings_shared.xml | 30 ++++++++- .../src/main/res/values-in/strings_shared.xml | 30 ++++++++- .../src/main/res/values-it/strings_shared.xml | 42 ++++++++++--- .../src/main/res/values-ja/strings_shared.xml | 28 ++++++++- .../src/main/res/values-ko/strings_shared.xml | 28 ++++++++- .../src/main/res/values-nl/strings_shared.xml | 30 ++++++++- .../src/main/res/values-pl/strings_shared.xml | 28 ++++++++- .../src/main/res/values-pt/strings_shared.xml | 30 ++++++++- .../src/main/res/values-ro/strings_shared.xml | 34 ++++++++-- .../src/main/res/values-ru/strings_shared.xml | 30 ++++++++- .../src/main/res/values-th/strings_shared.xml | 28 ++++++++- .../src/main/res/values-vi/strings_shared.xml | 30 ++++++++- .../main/res/values-zh-rCN/strings_shared.xml | 28 ++++++++- .../main/res/values-zh-rTW/strings_shared.xml | 34 ++++++++-- .../src/main/res/values/strings_shared.xml | 28 ++++++++- 99 files changed, 724 insertions(+), 988 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 4e8882c259..666b648c4c 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -131,7 +131,7 @@ لا تظهر مرة أخرى - هل أنت متأكد من أنك تريد إلغاء عملية تسجيل الدخول الحالية؟ + Are you sure you want to cancel the current login process? تسجيل الدخول @@ -608,16 +608,6 @@ رمز خاطئ. يرجى المحاولة مرة أخرى أو إعادة الإرسال. تم التحقق من رقم هاتفك - - - ذاكرة داخلية - ذاكرة خارجية - - - - اكتب بريد المستخدم الالكتروني - استيراد من جهاز - تفعيل ترفيعات الكاميرا @@ -628,19 +618,8 @@ تعطيل ترفيعات الوسائط المتعددة اختر مجلد - - - شبكة الواي فاي Wi-Fi أو بيانات الموبايل - شبكة الواي فاي Wi-Fi فقط - رفع ملف - - - الصور فقط - ملفات فيديو فقط - الصور و ملفات الفيديو - تشمل علامات الموقع @@ -863,7 +842,7 @@ تأكيد كلمة المرور - قيد المعالجة... + قيد المعالجة… إدارة الرابط @@ -1112,7 +1091,7 @@ [A] تسجيل خروج[/A] للتبديل بين حسابات ميغا MEGA - هل أنت متأكد أنك تريد تسجيل الخروج من الحساب الحالي؟ + Are you sure you want to log out of the current account? تم حذف هذه الرسالة من قبل %1$s @@ -1170,12 +1149,12 @@ لا توجد سجل للمحادثات - %1$s [A] يقوم بالكتابة...[/A] - %1$s [A] يقوم بالكتابة...[/A] - %1$s [A] يقوما بالكتابة...[/A] - %1$s [A] يقومون بالكتابة...[/A] - %1$s [A] يقومون بالكتابة...[/A] - %1$s [A] يقومون بالكتابة...[/A] + %1$s [A] يقوم بالكتابة…[/A] + %1$s [A] يقوم بالكتابة…[/A] + %1$s [A] يقوما بالكتابة…[/A] + %1$s [A] يقومون بالكتابة…[/A] + %1$s [A] يقومون بالكتابة…[/A] + %1$s [A] يقومون بالكتابة…[/A] %1$s [A]وأكثر يكتبون…[/A] @@ -1825,8 +1804,6 @@ جودة الفيديو جودة الفيديو - - تحتاج ترفيعات الكاميرا صلاحية الوصول إلى الصور والوسائط الأخرى الموجودة على جهازك. يرجى الذهاب إلى صفحة الإعدادات ومنح الإذن. منخفضة @@ -3476,7 +3453,7 @@ تغيير الإسم - إضافة صورة + تغيير صورة الملف الشخصي إضافة رقم هاتف @@ -3554,8 +3531,6 @@ تم تشغيل الكاميرا خاصتك. تم إيقاف تشغيل الكاميرا خاصتك. - - تعليق مكبر الصوت @@ -5201,7 +5176,7 @@ ايقاف - أضف ترجمات... + أضف ترجمات… خيارات عرض الشرائح @@ -5609,7 +5584,7 @@ حفظ في السواقة السحابية - جاري الحفظ... + جاري الحفظ… تم حفظ ”%1$s“ في السواقة السحابية. @@ -6026,11 +6001,11 @@ MEGA Pro plans include: - Ultimate storage flexibility + مرونة تخزين فائقة Starting from %1$s, find the perfect fit for your storage needs. - Upgrade to Pro today + قم بالترقية إلى برو Pro اليوم %1$s يقوم بالتقديم @@ -6129,8 +6104,6 @@ لقد تم كتم صوتك من قِبل %s تفاصيل الاشتراك - - يتم تجديد الاشتراكات تلقائيًا لفترات اشتراك متتالية من نفس المدة وبنفس سعر الفترة الأولية المختارة. يمكنك إيقاف التجديد التلقائي لاشتراك ميغا برو MEGA Pro الخاص بك في موعد لا يتجاوز 24 ساعة قبل استحقاق دفعة الاشتراك التالية عبر الاشتراكات في [A]غوغل بلاي Google Play[/A]. Allow access to your Gallery diff --git a/app/src/main/res/values-ar/strings_document_scanner.xml b/app/src/main/res/values-ar/strings_document_scanner.xml index 49558bd653..8d33afb45c 100644 --- a/app/src/main/res/values-ar/strings_document_scanner.xml +++ b/app/src/main/res/values-ar/strings_document_scanner.xml @@ -7,7 +7,7 @@ اضافة - حفظ + احفظ إعادة إلتقاط @@ -21,7 +21,7 @@ عالية - متوسطة + متوسط منخفضة @@ -41,7 +41,7 @@ الاسم غير صالح - عناصر غير صالحة + محارف غير صالحة قم بتصحيح اسم الملف الخاص بك قبل المتابعة diff --git a/app/src/main/res/values-ar/strings_sdk_errors.xml b/app/src/main/res/values-ar/strings_sdk_errors.xml index c7c615b1a6..4a13cfeb72 100644 --- a/app/src/main/res/values-ar/strings_sdk_errors.xml +++ b/app/src/main/res/values-ar/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + لا يوجد خطأ @@ -34,8 +34,6 @@ خطأ في فك التشفير معرف جلسة غير صالح - - لا يمكن الوصول إليه لأنه ينتهك شروط الخدمة الخاصة بنا محظور diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1236efba33..5c39b28aec 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -123,7 +123,7 @@ Nicht nochmal anzeigen - Wollen Sie den Loginvorgang abbrechen? + Are you sure you want to cancel the current login process? Anmelden @@ -576,16 +576,6 @@ Falscher Code. Bitte geben Sie ihn erneut ein oder fordern Sie einen neuen an. Ihre Telefonnummer wurde bestätigt - - - Interner Speicher - Externer Speicher - - - - E-Mail des Benutzers eingeben - Vom Gerät importieren - Kamera-Uploads aktivieren @@ -596,19 +586,8 @@ Zweitmedienuploads deaktivieren Ordner auswählen - - - WLAN oder Mobildaten - Nur via WLAN - Dateiupload - - - Nur Fotos - Nur Videos - Fotos und Videos - Ortsinformationen @@ -1048,7 +1027,7 @@ [A]Ausloggen[/A], um zu einem anderen MEGA-Account zu wechseln - Sind Sie sicher, dass Sie sich ausloggen möchten? + Are you sure you want to log out of the current account? Diese Nachricht wurde von %1$s gelöscht @@ -1677,8 +1656,6 @@ Chat-Videokompression Videoqualität - - Kamera-Uploads benötigt Zugriff auf Ihre Fotos und Mediendateien. Bitte gewähren Sie der App dieses Zugriffsrecht in den Einstellungen. Niedrig @@ -2449,7 +2426,7 @@ %d Versionen nicht gelöscht - Sie haben noch keine MEGA-Kontakte. Bitte laden Sie Freunde, Bekannte oder Kollegen über über den Bereich Kontakte ein. + Sie haben noch keine MEGA-Kontakte. Bitte laden Sie Freunde, Bekannte oder Kollegen über den Bereich Kontakte ein. Sie sind der alleinige Inhaber Ihrer Schlüssel @@ -3124,7 +3101,7 @@ Namen ändern - Foto hinzufügen + Profilbild ändern Telefonnummer hinzufügen @@ -3190,8 +3167,6 @@ Ihre Kamera ist eingeschaltet. Ihre Kamera ist ausgeschaltet. - - Halten Lautsprecher @@ -5201,8 +5176,6 @@ Sie wurden von %s stummgeschaltet Abonnementdetails - - Abonnements werden automatisch für den ursprünglich gewählten Abonnementzeitraum und zum gleichen Preis verlängert. Sie können die automatische Verlängerung Ihres MEGA-Pro-Abonnements bis spätestens 24 Stunden vor Fälligkeit Ihrer nächsten Abonnementzahlung in [A]Google Play[/A] unter Abonnements deaktivieren. Gewähren Sie Zugriff auf Ihre Galerie diff --git a/app/src/main/res/values-de/strings_sdk_errors.xml b/app/src/main/res/values-de/strings_sdk_errors.xml index e3e196cc95..01d732045a 100644 --- a/app/src/main/res/values-de/strings_sdk_errors.xml +++ b/app/src/main/res/values-de/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Kein Fehler @@ -34,8 +34,6 @@ Fehler bei der Entschlüsselung Ungültige Session-ID - - Kein Zugriff aufgrund eines Verstoßes gegen unsere Nutzungsbedingungen Blockiert diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 17e8b38966..80ce9ed92f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -43,7 +43,7 @@ Cargando - Añadiendo... + Añadiendo… Reenviando @@ -125,7 +125,7 @@ No volver a mostrar - ¿Confirmas que quieres cancelar el proceso de inicio de sesión? + Are you sure you want to cancel the current login process? Iniciar sesión @@ -584,16 +584,6 @@ Código erróneo. Prueba de nuevo o vuelve a enviarlo. Tu número de teléfono ha sido verificado - - - Almacenamiento interno - Almacenamiento externo - - - - Introduce la dirección de correo electrónico del usuario - Importar desde el dispositivo - Activar las Subidas de la cámara @@ -604,19 +594,8 @@ Desactivar subida multimedia secundaria Elige carpeta - - - Wi-Fi o plan de datos - Solo Wi-Fi - Subir archivos - - - Solo fotos - Solo vídeos - Fotos y vídeos - Incluir etiquetas de ubicación @@ -1064,7 +1043,7 @@ [A]Cierra sesión[/A] para usar otra cuenta de MEGA - ¿Confirmas que desea cerrar sesión y salir de tu cuenta? + Are you sure you want to log out of the current account? %1$s ha eliminado el mensaje @@ -1714,8 +1693,6 @@ Calidad de vídeo Calidad de vídeo - - Subidas de la cámara necesita acceder a tus fotos y otros archivos multimedia del dispositivo. Ve a los ajustes y permite el acceso. Baja @@ -3212,7 +3189,7 @@ Cambiar nombre - Añadir foto + Cambiar imagen del perfil Añadir número de teléfono @@ -3281,8 +3258,6 @@ La cámara está encendida. La cámara está apagada. - - En espera Altavoz @@ -3312,7 +3287,7 @@ Enlace de la reunión - Únete como invitado + Unirse a una reunión como invitado Estás invitado a una reunión. @@ -5433,8 +5408,6 @@ %s te ha silenciado Información sobre la suscripción - - La suscripción se renueva automáticamente con la misma duración y precio elegidos inicialmente. Puedes desactivar la renovación automática de la suscripción a MEGA Pro en la página de suscripciones de [A]Google Play[/A] hasta 24 horas antes de la renovación programada. Permite el acceso a la galería diff --git a/app/src/main/res/values-es/strings_sdk_errors.xml b/app/src/main/res/values-es/strings_sdk_errors.xml index b578cc75cc..8dd6174d42 100644 --- a/app/src/main/res/values-es/strings_sdk_errors.xml +++ b/app/src/main/res/values-es/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Ningún error @@ -34,8 +34,6 @@ Error de descifrado Identificador de sesión erróneo - - Eliminado por infringir nuestros Términos de servicio Bloqueado diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 045236aa7b..5f578ad992 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -584,16 +584,6 @@ Le code est erroné. Veuillez essayer et envoyer de nouveau. Votre numéro de téléphone a été confirmé - - - Mémoire interne - Mémoire externe - - - - Saisir l’adresse courriel de l’utilisateur - Importer de l’appareil - Activer les Téléversements de l’appareil photo @@ -604,19 +594,8 @@ Désactiver les téléversements secondaires de médias Choisir un dossier - - - Wi-Fi ou données mobiles - Wi-Fi seulement - Téléversement de fichiers - - - Photos seulement - Vidéos seulement - Photos et vidéos - Inclure des géomarques @@ -1714,8 +1693,6 @@ Qualité des vidéos Qualité des vidéos - - Les Téléversements de l’appareil photo doivent accéder à vos photos et autres médias sur votre appareil. Veuillez vous rendre dans les paramètres et accorder l’autorisation. Basse @@ -3212,7 +3189,7 @@ Changer le nom - Ajouter une photo + Changer votre image de profil Ajouter un numéro de téléphone @@ -3281,8 +3258,6 @@ Votre caméra est activée. Votre caméra est désactivée. - - Pause Haut-parleur @@ -5433,8 +5408,6 @@ Votre micro a été coupé par %s Détails de l’abonnement - - Les abonnements sont renouvelés automatiquement pour des périodes d’abonnement successives de même durée et au même prix que la période initiale choisie. Vous pouvez désactiver le renouvellement automatique de votre abonnement MEGA Pro au plus tard 24 heures avant la date de paiement de votre prochain abonnement dans Abonnements de [A]Google Play[/A]. Autoriser l’accès à votre Galerie diff --git a/app/src/main/res/values-fr/strings_document_scanner.xml b/app/src/main/res/values-fr/strings_document_scanner.xml index a7554a9133..1c198a3883 100644 --- a/app/src/main/res/values-fr/strings_document_scanner.xml +++ b/app/src/main/res/values-fr/strings_document_scanner.xml @@ -21,7 +21,7 @@ Haute - Moyenne + Moyen Basse @@ -31,7 +31,7 @@ Abandonner toutes les numérisations ? - Le présent document sera perdue + Le présent document sera perdu Abandonner diff --git a/app/src/main/res/values-fr/strings_sdk_errors.xml b/app/src/main/res/values-fr/strings_sdk_errors.xml index 220af325af..574490c6a4 100644 --- a/app/src/main/res/values-fr/strings_sdk_errors.xml +++ b/app/src/main/res/values-fr/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Aucune erreur @@ -34,8 +34,6 @@ Erreur de déchiffrement L’ID de session est erroné - - Non accessible pour non-respect des Conditions générales d’utilisation Bloqué diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 4a2278c0f6..4cc0b2fcb4 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -121,7 +121,7 @@ Jangan tampilkan lagi - Anda yakin ingin membatalkan proses masuk saat ini? + Apakah anda yakin ingin membatalkan proses login saat ini? Masuk @@ -568,16 +568,6 @@ Salah kode. Silakan coba lagi atau kirim ulang. Nomor telepon anda telah diverifikasi - - - Penyimpanan internal - Penyimpanan luar - - - - Tulis email pengguna - Impor dari perangkat - Aktifkan Unggahan camera @@ -588,19 +578,8 @@ Nonaktifkan unggahan media sekunder Pilih folder - - - Wi-Fi atau data plan - Hanya Wi-Fi - Unggah file - - - Hanya foto - Hanya video - Foto dan video - Sertakan tag lokasi @@ -1640,8 +1619,6 @@ Kualitas video Kualitas video - - Unggah Kamera perlu mengakses foto dan media lain di perangkat anda. Silakan buka halaman pengaturan dan berikan izin. Rendah @@ -3036,7 +3013,7 @@ Ganti nama - Tambahkan foto + Ubah gambar profil Tambahkan nomor telepon @@ -3099,8 +3076,6 @@ Kamera anda nyala. Kamera anda mati. - - Tahan Suara @@ -4969,8 +4944,6 @@ Anda telah dibisukan oleh %s Detail langganan - - Langganan diperpanjang secara otomatis untuk periode berlangganan berturut-turut dengan durasi yang sama dan dengan harga yang sama dengan periode awal yang dipilih. Anda dapat mematikan perpanjangan otomatis langganan MEGA   Pro anda selambat-lambatnya 24 jam sebelum pembayaran langganan berikutnya jatuh tempo melalui Langganan di [A]Google Play[/A]. Izinkan akses ke Galeri anda @@ -5154,22 +5127,21 @@ Selebihnya - Raise hand + Angkat tangan - Lower hand + Turunkan tangan - Put call on hold + Tahan panggilan - Swap calls + Tukar panggilan Lanjutkan panggilan - New feature: Raise hand + Fitur baru: Angkat tangan - You raised your hand + Anda mengangkat tangan - You and %1$d other raised your hands - You and %1$d others raised your hands + Anda dan %1$d orang lain mengangkat tangan \ No newline at end of file diff --git a/app/src/main/res/values-in/strings_document_scanner.xml b/app/src/main/res/values-in/strings_document_scanner.xml index 07287dbab5..9ceb01616f 100644 --- a/app/src/main/res/values-in/strings_document_scanner.xml +++ b/app/src/main/res/values-in/strings_document_scanner.xml @@ -11,7 +11,7 @@ Ambil kembali - Nama file + Nama File Jenis file @@ -21,7 +21,7 @@ Tinggi - Menengah + Sedang Rendah diff --git a/app/src/main/res/values-in/strings_sdk_errors.xml b/app/src/main/res/values-in/strings_sdk_errors.xml index 5fc6836366..ea219aa075 100644 --- a/app/src/main/res/values-in/strings_sdk_errors.xml +++ b/app/src/main/res/values-in/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Tidak ada kesalahan @@ -34,8 +34,6 @@ Kesalahan dekripsi Sesi ID buruk - - Tidak dapat diakses karena melanggar Persyaratan Layanan kami Terblokir diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 2f82b7ef55..16bb29ec25 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -125,7 +125,7 @@ Non mostrare più - Sei sicuro di voler annullare il processo di login corrente? + Are you sure you want to cancel the current login process? Entra @@ -584,16 +584,6 @@ Codice errato. Per favore, ritenta o chiedi che ti venga mandato nuovamente. Il tuo numero di telefono è stato verificato - - - Spazio di archiviazione interno - Spazio di archiviazione esterno - - - - Scrivi l’email dell’utente - Importa dal dispositivo - Attiva i Caricamenti da fotocamera @@ -604,19 +594,8 @@ Disattiva i caricamenti secondari dei media Scegli cartella - - - Wi-Fi o connessione dati - Solo Wi-Fi - Carica file - - - Solo foto - Solo video - Foto e video - Includi i tag della posizione @@ -802,7 +781,7 @@ Fai crescere il tuo cloud.[A]Ottieni un aumento del tuo spazio di archiviazione e della tua banda di trasferimento con un account Pro. - Indirizzo email già in uso. Inserisci un\’altra email. + Indirizzo email già in uso. Inserisci un altro indirizzo email. Hai già richiesto un link di conferma per quell’indirizzo e-mail. @@ -1064,7 +1043,7 @@ [A]Effettua il logout[/A] per cambiare account MEGA - Sei sicuro di voler effettuare il logout dall’account corrente? + Are you sure you want to log out of the current account? Questo messaggio è stato eliminato da %1$s @@ -1714,8 +1693,6 @@ Qualità dei video Qualità dei video - - I Caricamenti da fotocamera hanno bisogno dell’accesso alle tue foto e agli altri media sul tuo dispositivo. Per favore, vai nella pagina delle Impostazioni e garantisci questo permesso. Bassa @@ -3212,7 +3189,7 @@ Cambia nome - Aggiungi foto + Cambia l\’immagine del profilo Aggiungi numero di telefono @@ -3281,8 +3258,6 @@ La tua fotocamera è accesa. La tua fotocamera è spenta. - - In attesa Altoparlante @@ -5433,8 +5408,6 @@ %s ti ha mutato Dettagli dell\’abbonamento - - Gli abbonamenti vengono rinnovati automaticamente per periodi di abbonamento successivi della stessa durata e allo stesso prezzo del periodo iniziale scelto. Puoi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro entro 24 ore prima della scadenza del prossimo pagamento dell\’abbonamento tramite Abbonamenti nel [A]Google Play[/A]. Permetti l\’accesso alla tua Galleria @@ -5448,9 +5421,9 @@ Chiudi - Scegli host per abbandonare la chiamata + Scegli host prima di abbandonare la chiamata - Sei l\’unico host nella chiamata. Scegli un altro host del gruppo prima di abbandonare, in modo che un altro utente possa avere i permessi da host. Rimarrai host del gruppo. + Sei l\’unico host nella chiamata. Scegli un altro host del gruppo prima di abbandonare, in modo che un altro utente possa avere i permessi da host. Rimarrai come host all\’interno del gruppo. Scegli e abbandona @@ -5460,7 +5433,7 @@ Upload paused due to no internet connection - Upload paused as battery is below %1$d%% + Caricamento sospeso perché la batteria è minore del %1$d%% I Caricamenti da fotocamera hanno smesso di funzionare. Prova a riattivare i Caricamenti da fotocamera per risolvere il problema. Se il problema persiste, contatta il supporto. @@ -5496,11 +5469,11 @@ [A]Il tuo piano gratuito prevede un limite di 60 minuti per i meeting. Gli utenti Pro hanno chiamate illimitate e fino a 1000 partecipanti.[/A] [B]Effettua l\’upgrade adesso.[/B] - Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese al costo di %2$s al mese. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese al costo di %2$s al mese. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. - Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 12 mesi al costo di %2$s all\’anno. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 12 mesi al costo di %2$s all\’anno. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. - L\’addebito avverrà immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese. Il tuo account Google Play riceverà un addebito per il rinnovo entro le 24 ore precedenti la fine del periodo di fatturazione. Per annullare il tuo abbonamento, devi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di Servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + L\’addebito avverrà immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese. Il tuo account Google Play riceverà un addebito per il rinnovo entro le 24 ore precedenti la fine del periodo di fatturazione. Per annullare il tuo abbonamento, devi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di Servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. L\’addebito avverrà immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 12 mesi. Il tuo account Google Play riceverà un addebito per il rinnovo entro le 24 ore precedenti la fine del periodo di fatturazione. Per annullare il tuo abbonamento, devi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di Servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. @@ -5590,7 +5563,7 @@ Documenti - Data aggiunta + Data di aggiunta Ultima modifica @@ -5604,7 +5577,7 @@ Ultimo anno - Vecchio + Più vecchio Problemi con il login? @@ -5626,19 +5599,19 @@ Altro - Raise hand + Alza la mano - Lower hand + Abbassa la mano - Put call on hold + Metti la chiamata in attesa - Swap calls + Scambia le telefonate Riprendi chiamata - New feature: Raise hand + Nuova opzione: Alza la mano - You raised your hand + Hai alzato la tua mano You and %1$d other raised your hands diff --git a/app/src/main/res/values-it/strings_document_scanner.xml b/app/src/main/res/values-it/strings_document_scanner.xml index ffebb6b315..024a33af1a 100644 --- a/app/src/main/res/values-it/strings_document_scanner.xml +++ b/app/src/main/res/values-it/strings_document_scanner.xml @@ -9,7 +9,7 @@ Salva - Rifai + Riprova Nome del file diff --git a/app/src/main/res/values-it/strings_sdk_errors.xml b/app/src/main/res/values-it/strings_sdk_errors.xml index 222f63444f..6b64542b47 100644 --- a/app/src/main/res/values-it/strings_sdk_errors.xml +++ b/app/src/main/res/values-it/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Nessun errore @@ -34,8 +34,6 @@ Errore di decrittazione ID di sessione invalido - - Non accessibile in quanto violava i nostri Termini di Servizio Bloccato diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 81e4d4f756..a1c7cc69bb 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -568,16 +568,6 @@ 不正なコードです。もう一度やり直すか、再送信してください。 あなたの電話番号が認証されました - - - 内部ストレージ - 外部ストレージ - - - - ユーザーのメールアドレスを書く - 端末からインポート - カメラアップロードを有効にする @@ -588,19 +578,8 @@ セカンダリメディアのアップロードを無効にする フォルダを選択 - - - Wi-Fiまたはモバイルデータ - Wi-Fiのみ - ファイルアップロード - - - 写真のみ - 動画のみ - 写真と動画 - 場所タグを含める @@ -1640,8 +1619,6 @@ 動画の品質 動画の品質 - - カメラアップロードは、あなたの端末上の写真や他のメディアにアクセスする必要があります。設定ページに行き、許可を与えてください。 低い @@ -3036,7 +3013,7 @@ 名前を変更 - 写真を追加 + プロファイル画像を変更する 電話番号を追加 @@ -3099,8 +3076,6 @@ カメラがオンになっています。 カメラがオフになっています。 - - 保留 スピーカー @@ -4969,8 +4944,6 @@ %sさんにミュートされました サブスクリプションの詳細 - - サブスクリプションは、最初に選択した期間と同じ期間および同じ価格で、連続するサブスクリプション期間に対して自動的に更新されます。次のサブスクリプションのお支払い期日の24時間前までに、MEGA Proサブスクリプションの自動更新をオフに切り替えることができます。これは、[A]Google Play[/A]の「サブスクリプション」から実行できます。 ギャラリーへのアクセスを許可する diff --git a/app/src/main/res/values-ja/strings_document_scanner.xml b/app/src/main/res/values-ja/strings_document_scanner.xml index 7be3d94cde..29c9ad59f1 100644 --- a/app/src/main/res/values-ja/strings_document_scanner.xml +++ b/app/src/main/res/values-ja/strings_document_scanner.xml @@ -19,11 +19,11 @@ 保存先 - + 高い - + 普通 - + 低い スキャンを破棄しますか? diff --git a/app/src/main/res/values-ja/strings_sdk_errors.xml b/app/src/main/res/values-ja/strings_sdk_errors.xml index a022fd91b0..2c434d1600 100644 --- a/app/src/main/res/values-ja/strings_sdk_errors.xml +++ b/app/src/main/res/values-ja/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + エラーなし @@ -34,8 +34,6 @@ 復号化エラー セッションIDが正しくありません - - ご利用規約に違反するため、アクセスできません。 ブロックされています diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 95c25a92d6..83a617a0f8 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -43,7 +43,7 @@ 불러오는 중 - 추가 중... + 추가 중… 전달중 @@ -121,7 +121,7 @@ 다시 보여주지 마세요 - 현재 로그인 과정을 취소 하시겠습니까? + Are you sure you want to cancel the current login process? 로그인 @@ -568,16 +568,6 @@ 잘못된 코드. 다시 시도하거나 재발송하세요. 당신의 휴대 전화 번호는 인증되었습니다. - - - 내부 저장소 - 외부 저장소 - - - - Write the user’s email - 장치에서 들여오기 - 카메라 업로드 활성화 @@ -588,19 +578,8 @@ 보조 미디어 업로드 비활성화 폴더 선택 - - - 와이파이 또는 모바일 데이터 - 와이파이 전용 - 파일 올리기 - - - 사진만 - 동영상만 - 사진과 동영상 - 위치 태그 포함 @@ -1032,7 +1011,7 @@ MEGA 계정을 전환하려면 [A]로그아웃[/A]하세요 - 현재 계정에서 로그아웃 하시겠습니까? + Are you sure you want to log out of the current account? 이 메시지는 %1$s님에 의해 삭제되었습니다 @@ -1640,8 +1619,6 @@ 동영상 품질 동영상 품질 - - 카메라 업로드는 당신의 기기의 사진과 다른 미디어에 대한 접근을 필요로 합니다. 설정 페이지에 가서 권한을 부여해주세요. 낮음 @@ -3036,7 +3013,7 @@ 이름 변경 - 사진 추가 + Change profile image 전화번호 추가 @@ -3099,8 +3076,6 @@ 카메라 켜짐. 카메라 꺼짐. - - 보류 스피커 @@ -3396,7 +3371,7 @@ 애플리케이션을 닫지 마세요. - 스캔 중... + 스캔 중… 전송 취소 @@ -4256,7 +4231,7 @@ - 자막 추가... + 자막 추가… 슬라이드쇼 옵션 @@ -4544,7 +4519,7 @@ 클라우드 드라이브에 저장 - 저장 중... + 저장 중… “%1$s”을/를 클라우드 드라이브에 저장했습니다 @@ -4969,8 +4944,6 @@ %s 님에 의해 음소거 되었습니다 구독 세부정보 - - 구독은 처음 선택한 기간과 같은 기간 그리고 같은 가격으로 연속적으로 자동 갱신 됩니다. MEGA Pro 구독 자동 갱신을 [A]Google Play[/A]의 구독을 통해 다음 구독의 결제 24시간 전에 취소할 수 있습니다. 갤러리에 접근 허용 diff --git a/app/src/main/res/values-ko/strings_document_scanner.xml b/app/src/main/res/values-ko/strings_document_scanner.xml index 200c511561..7a016c481a 100644 --- a/app/src/main/res/values-ko/strings_document_scanner.xml +++ b/app/src/main/res/values-ko/strings_document_scanner.xml @@ -21,7 +21,7 @@ 높음 - 중간 + 보통 낮음 @@ -33,7 +33,7 @@ 현재 문서를 잃게 됩니다 - 취소 + 폐기 현재 스캔을 삭제할까요? diff --git a/app/src/main/res/values-ko/strings_sdk_errors.xml b/app/src/main/res/values-ko/strings_sdk_errors.xml index ee9de07d8c..9c32e329e9 100644 --- a/app/src/main/res/values-ko/strings_sdk_errors.xml +++ b/app/src/main/res/values-ko/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + 오류 없음 @@ -34,8 +34,6 @@ 복호화 오류 세션 ID 오류 - - 이용 약관 위반으로 인하여 접근할 수 없습니다 차단됨 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 6d4f132135..c99cce807b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -123,7 +123,7 @@ Laat niet opnieuw zien - Weet u zeker dat u het huidige aanmeldingsproces wilt annuleren? + Are you sure you want to cancel the current login process? Log in @@ -576,16 +576,6 @@ Onjuiste code. Probeer nogmaals of verstuur opnieuw. Uw telefoonnummer is geverifieerd - - - Interne opslag - Externe opslag - - - - Schrijf de gebruikers email - Importeren vanuit apparaat - Camera uploads Inschakelen @@ -596,19 +586,8 @@ Secundaire media uploads uitschakelen Map kiezen - - - Wi-Fi of mobiele data - Alleen Wi-Fi - Bestandsupload - - - Alleen foto’s - Alleen video’s - Foto’s en video’s - Inclusief locatie labels @@ -1048,7 +1027,7 @@ [A]Uitloggen [/A] om MEGA accounts te switchen - Weet u zeker dat u zich wilt afmelden bij het huidige account? + Are you sure you want to log out of the current account? Dit bericht werd verwijderd door %1$s @@ -1094,8 +1073,8 @@ Geen gespreksgeschiedenis - %1$s [A]is aan het typen...[/A] - %1$s [A]zijn aan het typen...[/A] + %1$s [A]is aan het typen…[/A] + %1$s [A]zijn aan het typen…[/A] %1$s [A] en meer zijn aan het schrijven…[/A] @@ -1677,8 +1656,6 @@ Video kwaliteit Video Kwaliteit - - Camera uploads heeft toegang nodig tot uw foto’s en andere media op uw apparaat. Ga naar de instellingen pagina en geef toestemming. Laag @@ -3124,7 +3101,7 @@ Wijzig naam - Foto toevoegen + Profielafbeelding wijzigen Telefoonnummer toevoegen @@ -3190,8 +3167,6 @@ Uw camera is ingeschakeld. Uw camera is uitgeschakeld. - - Wacht Luidspreker @@ -4445,7 +4420,7 @@ Uit - Ondertiteling toevoegen... + Ondertiteling toevoegen… Opties voor diavoorstelling @@ -4757,7 +4732,7 @@ Opslaan op de Cloud schijf - Opslaan... + Opslaan… “%1$s” Opgeslagen op Cloud schijf @@ -5201,8 +5176,6 @@ U bent gedempt door %s Abonnement details - - Abonnementen worden automatisch verlengd voor opeenvolgende abonnementsperioden van dezelfde duur en tegen dezelfde prijs als de gekozen initiële periode. U kunt de automatische verlenging van uw MEGA   Pro-abonnement uiterlijk 24 uur voordat uw volgende abonnementsbetaling verschuldigd is, uitschakelen via Abonnementen in [A]Google Play[/A]. Geef toegang tot uw galerij diff --git a/app/src/main/res/values-nl/strings_document_scanner.xml b/app/src/main/res/values-nl/strings_document_scanner.xml index f4acc40bde..11b4a47302 100644 --- a/app/src/main/res/values-nl/strings_document_scanner.xml +++ b/app/src/main/res/values-nl/strings_document_scanner.xml @@ -5,7 +5,7 @@ Scan opslaan - Toevoegen + Voeg toe Opslaan @@ -21,7 +21,7 @@ Hoog - Medium + Gemiddeld Laag @@ -45,7 +45,7 @@ Corrigeer uw bestandsnaam voordat u verder gaat - %1$sVoorbereiden. Wacht alstublieft… + %1$s voorbereiden. Wacht alstublieft… - De volgende karakters zijn niet toegestaan: %1$s + De volgende tekens zijn niet toegestaan: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings_sdk_errors.xml b/app/src/main/res/values-nl/strings_sdk_errors.xml index 28e781efb4..400283ddd8 100644 --- a/app/src/main/res/values-nl/strings_sdk_errors.xml +++ b/app/src/main/res/values-nl/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Geen fout @@ -34,8 +34,6 @@ Decoderingsfout Slechte sessie ID - - Niet toegankelijk omdat het onze Algemene Voorwaarden schendt Geblokkeerd diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 480248c636..b6b3f1b12e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -592,16 +592,6 @@ Niepoprawny kod. Spróbuj ponownie lub wyślij ponownie. Twój numer telefonu został zweryfikowany - - - Wewnętrzna pamięć - Zwenętrzna pamięć - - - - Wpisz adres e-mail użytkownika - Importuj z urządzenia - Włącz Przesyłanie z kamery @@ -612,19 +602,8 @@ Wyłącz kopię przesyłanych zdjęć i filmów Wybierz katalog - - - Wi-Fi lub komórkowa transmisja danych - Tylko Wi-Fi - Wgraj plik - - - Tylko zdjęcia - Tylko filmy - Zdjęcia i filmy - Dołącz tagi lokalizacji @@ -1080,7 +1059,7 @@ [A]Wyloguj się[/A], aby zmienić konto MEGA - Czy na pewno chcesz się wylogować z bieżącego konta? + Czy na pewno chcesz wylogować się z bieżącego konto? Ta wiadomość została usunięta przez %1$s @@ -1751,8 +1730,6 @@ Jakość wideo Jakość wideo - - Przesyłanie z kamery musi mieć dostęp do zdjęć i innych multimediów w urządzeniu. Przejdź do strony ustawień i udziel pozwolenia. Niska @@ -3300,7 +3277,7 @@ Zmień nazwę - Dodaj zdjęcie + Zmień zdjęcie profilu Dodaj numer telefonu @@ -3372,8 +3349,6 @@ Kamera jest włączona. Kamera jest wyłączona. - - Zawieś Głośnik @@ -4823,7 +4798,7 @@ Wyłącz - Dodaj napisy... + Dodaj napisy… Opcje pokazu slajdów @@ -5183,7 +5158,7 @@ Zapisz do dysku w chmurze - Zapisywanie... + Zapisywanie… “%1$s” zapisane na Dysku w chmurze @@ -5665,8 +5640,6 @@ Zostałeś wyciszony przez %s Szczegóły subskrypcji - - Subskrypcje są odnawiane automatycznie na kolejne okresy subskrypcji o tym samym czasie trwania i w tej samej cenie, co wybrany okres początkowy. Użytkownik może wyłączyć automatyczne odnawianie subskrypcji MEGA Pro nie później niż 24 godziny przed terminem płatności kolejnej subskrypcji za pośrednictwem Subskrypcji w [A]Google Play[/A]. Zezwalaj na dostęp do swojej galerii diff --git a/app/src/main/res/values-pl/strings_document_scanner.xml b/app/src/main/res/values-pl/strings_document_scanner.xml index f7ad731131..a72afac281 100644 --- a/app/src/main/res/values-pl/strings_document_scanner.xml +++ b/app/src/main/res/values-pl/strings_document_scanner.xml @@ -21,7 +21,7 @@ Wysoka - Średnia + Średnie Niska diff --git a/app/src/main/res/values-pl/strings_sdk_errors.xml b/app/src/main/res/values-pl/strings_sdk_errors.xml index f380c2c0fa..0a479f13e6 100644 --- a/app/src/main/res/values-pl/strings_sdk_errors.xml +++ b/app/src/main/res/values-pl/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Brak błędów @@ -34,8 +34,6 @@ Błąd opisu Zły numer sesji - - Brak dostępu, ponieważ narusza to nasze warunki korzystania z usługi Zablokowane diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index def24e00b3..e817d44cfd 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -584,16 +584,6 @@ Código incorreto, tente novamente. O seu número de telefone foi verificado - - - Armazenamento interno - Armazenamento externo - - - - Digite o email do usuário - Importar do dispositivo - Ativar Uploads da câmera @@ -604,19 +594,8 @@ Desativar upload secundário de mídia Escolher pasta - - - Wi-Fi ou dados móveis - Somente Wi-Fi - Upload de arquivo - - - Somente fotos - Somente vídeos - Fotos e vídeos - Incluir etiquetas de localização @@ -1714,8 +1693,6 @@ Qualidade dos vídeos Qualidade dos vídeos - - A função Uploads da câmera precisa acessar as suas fotos e outras arquivos multimídia no seu dispositivo. Por favor, acesse as configurações do seu dispositivo e conceda permissão. Baixa @@ -3212,7 +3189,7 @@ Alterar nome - Adicionar foto + Alterar a imagem de perfil Adicionar número de telefone @@ -3281,8 +3258,6 @@ A sua câmera está ativada. A sua câmera está desativada. - - Em espera Som @@ -5433,8 +5408,6 @@ Você foi silenciado por %s Informações da assinatura - - As assinaturas serão renovadas automaticamente por períodos sucessivos com a mesma duração e pelo mesmo preço do período inicial. Você pode desativar a renovação automática da sua assinatura Pro do MEGA até 24 horas antes do vencimento do próximo pagamento nas Assinaturas da [A]Google Play[/A]. Permitir o acesso à sua Galeria diff --git a/app/src/main/res/values-pt/strings_document_scanner.xml b/app/src/main/res/values-pt/strings_document_scanner.xml index c6aa545ea8..9874c37f01 100644 --- a/app/src/main/res/values-pt/strings_document_scanner.xml +++ b/app/src/main/res/values-pt/strings_document_scanner.xml @@ -45,7 +45,7 @@ Corrija o nome do arquivo antes de continuar - Preparando %1$s. Por favor, aguarde… + Preparando %1$s. Por favor, espere... Os seguintes caracteres não são permitidos: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings_sdk_errors.xml b/app/src/main/res/values-pt/strings_sdk_errors.xml index e1a6887898..4042590ac7 100644 --- a/app/src/main/res/values-pt/strings_sdk_errors.xml +++ b/app/src/main/res/values-pt/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Nenhum erro @@ -34,8 +34,6 @@ Erro de decodificação ID de sessão inválido - - Não acessível por infringir os nossos Termos de serviço Bloqueado diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index c8ab460829..bb94e462ad 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -125,7 +125,7 @@ Nu afișa din nou - Sigur vrei să anulezi procesul actual de autentificare? + Sigur vreți să anulați procesul actual de autentificare? Autentifică-te @@ -431,7 +431,7 @@ Trimite - Îți mulțumim pentru feedback. Sigur vrei să anulezi abonamentul MEGA? + Vă mulțumim pentru feedback. Sigur vreți să vă anulați abonamentul MEGA? Abonamentul dvs. nu a fost anulat. Oferiți un motiv pentru anulare @@ -499,7 +499,7 @@ Numai Wi-Fi - Wi-Fi sau plan de date + Wi-Fi sau date mobile Încărcări cameră în curs @@ -584,16 +584,6 @@ Cod greșit. Vă rugăm să încercați din nou sau să retrimiteți. Numărul dvs. de telefon a fost confirmat - - - Stocare internă - Stocare externă - - - - Scrie e-mailul utilizatorului - Importă de pe dispozitiv - Activează Încărcări cameră @@ -604,19 +594,8 @@ Dezactivează încărcări media secundare Alege un folder - - - Wi-Fi sau plan de date - Numai Wi-Fi - Încărcarea de fișiere - - - Numai fotografii - Numai videoclipuri - Fotografii și videoclipuri - Include etichetele locațiilor @@ -1064,7 +1043,7 @@ [A]Deconectează-te[/A] pentru a comuta între conturile MEGA - Sigur vrei să te deconectezi din contul actual? + Sigur vreți să deconectați de la contul curent? Acest mesaj a fost șters de %1$s @@ -1714,8 +1693,6 @@ Calitate video Calitate video - - Încărcări camere trebuie să acceseze fotografiile și alte suporturi media de pe dispozitiv. Accesați pagina de setări și acordați permisiunea. Scăzută @@ -2114,7 +2091,7 @@ [A]%1$s [/A][B]din %2$s folosiți[/B] - Sunteți sigur că doriți să treceți la un server de testare? Contul dvs. poate suferi probleme ireversibile. + Sigur vreți să treceți la un server de testare? Contul dvs. poate suferi probleme ireversibile. Deschizi camera? @@ -2916,7 +2893,7 @@ Șterge automat mesajele mai vechi de: - Sigur vrei să ștergi istoricul complet al mesajelor din această conversație? + Sigur vreți să ștergeți istoricul complet al mesajelor din această conversație? 1 an @@ -3212,7 +3189,7 @@ Modifică numele - Adaugă o fotografie + Schimbați imaginea profilului Adaugă un număr de telefon @@ -3281,8 +3258,6 @@ Camera este pornită. Camera este oprită. - - Pune în așteptare Difuzor @@ -3444,7 +3419,7 @@ Permite folosirea datelor mobile pentru a încărca imagini de înaltă rezoluție la previzualizare. Dacă opțiunea este dezactivată, imaginea originală va fi încărcată numai când faci zoom in. - Ștergi folderul de backupuri. Acest lucru va elimina toate backupurile pe care le-ai setat. Sigur vrei să faci acest lucru? + Ștergeți folderul de backupuri. Aceasta va elimina toate backup-urile pe care le-ați setat. Sigur vreți să faceți asta? Mută „%1s” în Coșul de gunoi @@ -4972,7 +4947,7 @@ Se salvează… - „%1$s” salvat în Unitatea cloud + „%1$s” a fost salvat în Unitatea cloud „%1$s” nu poate fi salvat pe Unitatea cloud. Încercați din nou mai târziu și dacă problema continuă, contactați persoana care a partajat linkul cu dvs. @@ -5433,8 +5408,6 @@ Microfonul dvs. a fost dezactivat de %s Detaliile abonamentului - - Abonamentele sunt reînnoite automat pentru perioade succesive de abonament cu aceeași durată și la același preț ca perioada inițială aleasă. Puteți dezactiva reînnoirea automată a abonamentului MEGA Pro cu cel mult 24 de ore înainte de scadența următoarei plăți a abonamentului prin Abonamente în [A]Google Play[/A]. Permiteți accesul la Galeria dvs. diff --git a/app/src/main/res/values-ro/strings_document_scanner.xml b/app/src/main/res/values-ro/strings_document_scanner.xml index 8b02fc3c88..8ad875eaf1 100644 --- a/app/src/main/res/values-ro/strings_document_scanner.xml +++ b/app/src/main/res/values-ro/strings_document_scanner.xml @@ -11,7 +11,7 @@ Refă - File name + Numele fișierului Tipul fișierului @@ -19,7 +19,7 @@ Destinație - Superioară + Ridicată Medie diff --git a/app/src/main/res/values-ro/strings_sdk_errors.xml b/app/src/main/res/values-ro/strings_sdk_errors.xml index b5dcef942b..3766fafa9d 100644 --- a/app/src/main/res/values-ro/strings_sdk_errors.xml +++ b/app/src/main/res/values-ro/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Nicio eroare @@ -34,8 +34,6 @@ Eroare la decriptare ID-ul sesiunii greșit - - Indisponibil deoarece a încălcat Termenii de utilizare a serviciului Blocat diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 36c79d4a0f..4db3065aff 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -592,16 +592,6 @@ Неправильный код. Пожалуйста, попробуйте ещё раз или отправьте повторно. Ваш номер телефона подтверждён - - - Внутреннее хранилище - Внешнее хранилище - - - - Эл. почта пользователя - Импорт с устройства - Включить Загрузки из камеры @@ -612,19 +602,8 @@ Отключить дополнительную загрузку медиа Выбрать папку - - - Wi-Fi или мобильные данные - Только Wi-Fi - Загрузка файла - - - Только фото - Только видео - Фото и видео - Включить метки местоположения @@ -1751,8 +1730,6 @@ Качество видео Качество видео - - Для загрузок из камеры требуется доступ к фотографиям и другим медиафайлам на устройстве. Пожалуйста, разрешите его в настройках. Низкое @@ -3300,7 +3277,7 @@ Изменить имя - Добавить фото + Изменение изображения профиля Добавить номер телефона @@ -3372,8 +3349,6 @@ Ваша камера включена. Ваша камера отключена. - - Удержать Динамик @@ -5665,8 +5640,6 @@ Пользователь %s пришлушил вас Подробная информация о подписке - - Подписки продлеваются автоматически на последующие периоды той же продолжительности и по той же цене, что и первоначально выбранный период. Вы можете отключить автоматическое продление подписки MEGA Pro не позднее чем за 24 часа до следующего платежа за подписку на странице «Подписки» в [A]Google Play[/A]. Разрешите доступ к «Галерее» diff --git a/app/src/main/res/values-ru/strings_sdk_errors.xml b/app/src/main/res/values-ru/strings_sdk_errors.xml index 943384fe7f..984ef9d295 100644 --- a/app/src/main/res/values-ru/strings_sdk_errors.xml +++ b/app/src/main/res/values-ru/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Ошибок нет @@ -34,8 +34,6 @@ Ошибка расшифровки Неверный идентификатор сессии - - Недоступно из-за нарушения наших условий использования Заблокировано diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 665d8b486a..d66ec638bc 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -121,7 +121,7 @@ ไม่ต้องแสดงในครั้งต่อไป - คุณแน่ใจหรือไม่ว่าต้องการยกเลิกกระบวนการล็อกอินปัจจุบัน + Are you sure you want to cancel the current login process? เข้าสู่ระบบ @@ -568,16 +568,6 @@ รหัสไม่ถูกต้อง กรุณาลองใหม่หรือส่งอีกครั้ง หมายเลขโทรศัพท์ของคุณถูกตรวจสอบเรียบร้อยแล้ว - - - พื้นที่เก็บข้อมูลภายใน - พื้นที่เก็บข้อมูลภายนอก - - - - เขียนอีเมลผู้ใช้ - นำเข้าจากอุปกรณ์ - เปิดใช้งานอัปโหลดกล้อง @@ -588,19 +578,8 @@ ปิดใช้งานการอัปโหลดสื่อจากโฟลเดอร์อื่น เลือกโฟลเดอร์ - - - WiFi หรือข้อมูลมือถือ - Wi-Fi เท่านั้น - อัปโหลดไฟล์ - - - รูปถ่ายเท่านั้น - วิดีโอเท่านั้น - รูปถ่ายและวิดีโอ - รวมแท็กตำแหน่งที่ตั้ง @@ -1032,7 +1011,7 @@ [A]ออกจากระบบ[/A]เพื่อใช้ MEGA กับบัญชีอื่น - คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบบัญชีปัจจุบันนี้ + Are you sure you want to log out of the current account? ข้อความนี้ถูกลบโดย %1$s @@ -1640,8 +1619,6 @@ คุณภาพวีดีโอ คุณภาพวีดีโอ - - การอัปโหลดจากกล้องจำเป็นต้องเข้าถึงภาพถ่ายและสื่ออื่น ๆ บนอุปกรณ์ของคุณ กรุณาไปที่หน้าการตั้งค่าและการให้สิทธิ์ ต่ำ @@ -3036,7 +3013,7 @@ เปลี่ยนชื่อ - เพิ่มรูปภาพ + เปลี่ยนรูปโปรไฟล์ เพิ่มหมายเลขโทรศัพท์ @@ -3099,8 +3076,6 @@ กล้องของคุณเปิดอยู่ กล้องของคุณปิดอยู่ - - พักสาย ลำโพง @@ -4969,8 +4944,6 @@ %s ได้ปิดเสียงคุณ รายละเอียดการสมัครใช้งาน - - เมื่อสมัครใช้งานแล้ว ระบบจะต่ออายุสมาชิกให้อัตโนมัติตามระยะเวลาและราคาเดิมที่เลือกไว้ คุณสามารถยกเลิกการต่ออายุสมาชิก MEGA Pro อัตโนมัติได้ไม่เกิน 24 ชั่วโมงก่อนวันครบกำหนดชำระค่าสมาชิกครั้งต่อไปผ่านระบบสมาชิกใน [A]Google Play[/A] อนุญาตให้เข้าถึงแกลเลอรี่ของคุณ diff --git a/app/src/main/res/values-th/strings_sdk_errors.xml b/app/src/main/res/values-th/strings_sdk_errors.xml index 30e30b0c62..b70b7cf2d3 100644 --- a/app/src/main/res/values-th/strings_sdk_errors.xml +++ b/app/src/main/res/values-th/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + ไม่มีข้อผิดพลาด @@ -34,8 +34,6 @@ ข้อผิดพลาดในการถอดรหัสลับ ID เซสชั่นไม่ถูกต้อง - - ไม่สามารถเข้าถึงได้เนื่องจากละเมิดเงื่อนไขการให้บริการของเรา บล็อกแล้ว diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index ef9684ce51..76148293cf 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -121,7 +121,7 @@ Đừng hiện lại nữa - Có chắc muốn hủy bỏ quá trình đăng nhập hiện tại không? + Are you sure you want to cancel the current login process? Đăng nhập @@ -568,16 +568,6 @@ Mã không đúng. Xin thử lại hoặc lấy cái mới. Số điện thoại của bạn đã được xác thực - - - Bộ nhớ nội bộ - Bộ nhớ ngoài - - - - Bằng địa chỉ email của người muốn mời - Chuyển từ danh bạ của điện thoại - Bật Đăng Tải Camêra @@ -588,19 +578,8 @@ Tắt đăng tải thư mục phương tiện số bổ sung Chọn thư mục - - - Dùng Wi-Fi hay mạng di động - Chỉ khi dùng Wi-Fi - Tải lên tệp tin - - - Chỉ chọn ảnh - Chỉ video - Ảnh và video - Bao gồm vị trí địa lý @@ -1032,7 +1011,7 @@ [A]Đăng xuất[/A] để đổi sang tài khoản MEGA khác - Bạn co chắc muốn đăng xuất khỏi tài khoản hiện tại? + Are you sure you want to log out of the current account? Tin nhắn này đã bị xóa bởi %1$s @@ -1640,8 +1619,6 @@ Chất lượng video Chất Lượng Video - - Đăng Tải Camêra cần quyền truy cập vào hình ảnh và các nội dung phương tiện số trên thiết bị. Xin đi vào phần cài đặt và cấp quyền truy cập cho MEGA. Thấp @@ -3036,7 +3013,7 @@ Đổi tên - Thêm ảnh + Đổi ảnh đại diện Thêm số điện thoại @@ -3099,8 +3076,6 @@ Camêra hiện đang được bật. Camêra hiện đang bị tắt. - - Tạm dừng Loa ngoài @@ -4969,8 +4944,6 @@ Bạn đã bị tắt tiếng bởi %s Chi tiết gói đăng ký - - Các gói đăng ký được tự động gia hạn cho khoảng thời gian đăng ký kế tiếp có cùng thời lượng và ở cùng mức giá như khoảng thời gian ban đầu đã chọn. Bạn có thể tắt tự động gia hạn gói đăng ký MEGA Pro của mình không được ít hơn 24 giờ trước khi đến kỳ hạn thanh toán cho gói đăng ký tiếp theo thông qua trang Gói thuê bao trong [A]Google Play[/A]. Cho phép truy cập vào Thư viện Hình ảnh của bạn @@ -4996,7 +4969,7 @@ Tải lên bị tạm dừng do không có kết nối internet - Upload paused as battery is below %1$d%% + Tải lên bị tạm dừng vì pin ở dưới %1$d%% Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với bộ phận hỗ trợ. diff --git a/app/src/main/res/values-vi/strings_document_scanner.xml b/app/src/main/res/values-vi/strings_document_scanner.xml index 0751de3f8b..99a97d5710 100644 --- a/app/src/main/res/values-vi/strings_document_scanner.xml +++ b/app/src/main/res/values-vi/strings_document_scanner.xml @@ -11,7 +11,7 @@ Quét lại - Tên tệp + Tên tệp tin Dạng tệp @@ -33,13 +33,13 @@ Tài liệu này sẽ bị mất - Loại bỏ + Hủy bỏ Xóa hình quét hiện tại? Cần quyền hạn sử dụng Camêra để quét tài liệu - Tên không hợp lệ + Tên không hợp lệ Ký tự không hợp lệ @@ -47,5 +47,5 @@ Đang chuẩn bị %1$s. Xin chờ… - Các ký tự này không được phép sử dụng: %1$s + Các ký tự này không được phép sử dụng: %1$s \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings_sdk_errors.xml b/app/src/main/res/values-vi/strings_sdk_errors.xml index d43e5778f1..9aabdb8661 100644 --- a/app/src/main/res/values-vi/strings_sdk_errors.xml +++ b/app/src/main/res/values-vi/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + Không có lỗi @@ -34,8 +34,6 @@ Lỗi giải mã Bad session ID - - Không truy cập được do vi phạm Điều Khoản Dịch Vụ Bị chặn diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4ac58e0a38..7dbdfd47d7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -121,7 +121,7 @@ 不再显示 - 您确定要取消当前登录吗? + 您确定要取消当前的登入吗? 登 入 @@ -568,16 +568,6 @@ 验证码错误。请再试一次或重新发送。 您的电话号码已经通过验证 - - - 内部存储 - 外部存储 - - - - 请填写用户的电子邮件地址 - 从设备导入 - 启用相机上传 @@ -588,19 +578,8 @@ 关闭辅助媒体上传 选择文件夹 - - - Wi-Fi或移动数据 - 仅限Wi-Fi - 上传文件 - - - 仅照片 - 仅视频 - 照片和视频 - 包含位置标签 @@ -1075,7 +1054,7 @@ 无聊天记录 - %1$s[A]正在输入...[/A] + %1$s[A]正在输入…[/A] %1$s [A]和其他人正在输入…[/A] @@ -1640,8 +1619,6 @@ 视频质量 视频画质 - - 相机上传需要访问您设备上的照片和其他媒体内容。请转到设置页面开启权限。 较低 @@ -3036,7 +3013,7 @@ 更改名字 - 添加照片 + 更改个人资料图片 添加手机号 @@ -3099,8 +3076,6 @@ 您的摄像头已开启。 您的摄像头已关闭。 - - 通话保持 扬声器 @@ -4256,7 +4231,7 @@ 关闭 - 添加字幕... + 添加字幕… 幻灯片选项 @@ -4442,9 +4417,9 @@ 无法打开文件 - This folder has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + 根据我们的[A]删除指导政策[/A],此文件夹已被删除。如果您认为我们犯了一个错误,您可以对这次删除提出异议。 - This file has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + 根据我们的[A]删除指导政策[/A],此文件已被删除。如果您认为我们犯了一个错误,您可以对这次删除提出异议。 仅限Pro会员 @@ -4969,8 +4944,6 @@ 您已被%s静音 订阅详情 - - 订阅将自动续订,续订周期与初始选择的周期相同,并且以相同的价格进行续订。您可以在下一次订阅付款到期前24小时以内,通过[A]Google Play[/A]订阅界面关闭MEGA Pro订阅的自动续订功能。 允许访问您的图库 diff --git a/app/src/main/res/values-zh-rCN/strings_document_scanner.xml b/app/src/main/res/values-zh-rCN/strings_document_scanner.xml index 6182c879c0..87efe61b26 100644 --- a/app/src/main/res/values-zh-rCN/strings_document_scanner.xml +++ b/app/src/main/res/values-zh-rCN/strings_document_scanner.xml @@ -11,7 +11,7 @@ 重新扫描 - 文件名称 + 文件名 文件类型 diff --git a/app/src/main/res/values-zh-rCN/strings_sdk_errors.xml b/app/src/main/res/values-zh-rCN/strings_sdk_errors.xml index b17e0456fb..c825936f87 100644 --- a/app/src/main/res/values-zh-rCN/strings_sdk_errors.xml +++ b/app/src/main/res/values-zh-rCN/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + 无错误 @@ -34,8 +34,6 @@ 解密错误 恶意会话ID - - 因违反我们的服务条款而无法访问 已锁定 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5d797b9701..5c084551a5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -121,7 +121,7 @@ 請別再顯示 - 您確定要取消目前的登入嗎? + Are you sure you want to cancel the current login process? 登入 @@ -568,16 +568,6 @@ 驗證碼錯誤。請重試或重新傳送。 您的手機號碼已通過驗證 - - - 內部儲存 - 外部儲存 - - - - 填入使用者email - 從裝置匯入 - 啟用相機上傳 @@ -588,19 +578,8 @@ 停用次要體上傳功能 選擇資料夾 - - - Wi-Fi或行動網路 - 只在WiFi連線 - 檔案上傳 - - - 只有照片 - 只有影片 - 照片和影片 - 包含位置標籤 @@ -1032,7 +1011,7 @@ [A]登出[/A]以切換MEGA帳戶 - 您確定要登出目前帳戶嗎? + Are you sure you want to log out of the current account? 此訊息已被%1$s刪除 @@ -1640,8 +1619,6 @@ 影片品質 影片品質 - - 相機上傳需存取您裝置裡的相片與其他媒體內容,請到設定頁面並且允許其權限。 @@ -3036,7 +3013,7 @@ 更改名稱 - 新增大頭照 + 更改個人資料相片 新增電話號碼 @@ -3099,8 +3076,6 @@ 您的相機己開啟。 您的相機己關閉。 - - 保留 喇叭 @@ -4969,8 +4944,6 @@ %s已將您設為靜音 訂閱詳情 - - 訂閱會自動續訂,續訂的訂閱期間與初始選擇的周期相同,價格也相同。您可以在下次訂閱付款到期前24小時內,透過[A]Google Play[/A]中的訂閱關閉MEGA Pro訂閱的自動續訂功能。 允許存取您的相簿 @@ -5169,6 +5142,6 @@ 您舉起手 - 您和其他%1$d個人舉起了手 + 您和其他%1$d個人舉起手 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings_document_scanner.xml b/app/src/main/res/values-zh-rTW/strings_document_scanner.xml index d8941ae6ee..b793d30263 100644 --- a/app/src/main/res/values-zh-rTW/strings_document_scanner.xml +++ b/app/src/main/res/values-zh-rTW/strings_document_scanner.xml @@ -41,7 +41,7 @@ 無效的名稱 - 無效字元 + 無效的字元 在繼續操作前,請更正您的檔案名稱 diff --git a/app/src/main/res/values-zh-rTW/strings_sdk_errors.xml b/app/src/main/res/values-zh-rTW/strings_sdk_errors.xml index 24da5bcbad..8ca3490d4b 100644 --- a/app/src/main/res/values-zh-rTW/strings_sdk_errors.xml +++ b/app/src/main/res/values-zh-rTW/strings_sdk_errors.xml @@ -1,5 +1,5 @@ - + 無誤 @@ -34,8 +34,6 @@ 解密錯誤 惡意session ID - - 因違反我們的服務條款而無法存取 封鎖 diff --git a/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml index 90a508f5e0..cc68021651 100644 --- a/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ar/strings_device_center_feature.xml @@ -17,7 +17,7 @@ لا يوجد تحديثات - جاري التهيئة.... + جاري التهيئة…. جاري الفحص… diff --git a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml index 7e68bc15fd..5394cf883c 100644 --- a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml @@ -17,11 +17,11 @@ Vollständig synchronisiert - Initialisierung.... + Initialisierung… - Scan läuft… + Wird gescannt… - Aktualisierung erfolgt… + Wird aktualisiert… %1$d%% wird aktualisiert… diff --git a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml index 6766a788b7..d1bb49a9ad 100644 --- a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml @@ -23,7 +23,7 @@ Actualizando… - %1$d%% Actualizando... + %1$d%% actualizando… No hay subidas de la cámara diff --git a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml index b1f42d73f4..1d4c1a7be0 100644 --- a/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-fr/strings_device_center_feature.xml @@ -23,7 +23,7 @@ Mise à jour… - %1$d %% Mise à jour… + %1$d %% mise à jour… Aucun téléversement de l’appareil photo @@ -35,7 +35,7 @@ La sauvegarde est arrêtée - Quota épuisé + Le quota est épuisé Erreur @@ -57,7 +57,7 @@ Afficher dans le Disque nuagique - No sync error + Aucune erreur de synchronisation MEGA ne peut ni synchroniser ni sauvegarder ce dossier, car le système de fichiers de votre appareil n’est pas pris en charge @@ -93,7 +93,7 @@ La synchronisation ou la sauvegarde a été arrêtée, car il semble que vous vous êtes déconnecté de l’appli pour ordinateur. Reconnectez-vous dans l’appli pour ordinateur et reprenez la synchronisation ou la sauvegarde. - N/A + n.d. Impossible de trouver le fichier sur le lecteur externe. @@ -115,7 +115,7 @@ Impossible de lire l’emplacement de la synchronisation. Vérifiez que l’emplacement est accessible et que les droits ont été accordés pour l’emplacement du dossier. - Unable to open state cache database + Impossible d’ouvrir la base de données d’état du cache Il n’y a pas suffisamment d’espace pour télécharger. @@ -123,7 +123,7 @@ Erreur inconnue - Something went wrong. + Un problème est survenu Le dossier ne peut ni être synchronisé ni sauvegardé, car le dossier MEGA est dans la Corbeille diff --git a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml index e71dfc17cb..e8df68bca3 100644 --- a/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-in/strings_device_center_feature.xml @@ -17,7 +17,7 @@ Terkini - Memulai ... + Memulai… Memindai… diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index 5a3f9cd1d7..4225035fad 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -27,7 +27,7 @@ Nessun caricamento da fotocamera - Disattivato + Disattivata Offline @@ -35,7 +35,7 @@ Backup fermato - Oltre il limite + Banda di trasferimento esaurita Errore @@ -57,7 +57,7 @@ Mostra nel Cloud drive - No sync error + Nessun errore di sincronizzazione MEGA non può sincronizzare o effettuare il backup di questa cartella perché il filesystem sul tuo dispositivo non è supportato @@ -123,7 +123,7 @@ Errore sconosciuto. - Something went wrong. + Qualcosa è andato storto. La cartella non può essere sincronizzata o effettuare il backup in quanto la cartella corrispettiva su MEGA è nel Cestino diff --git a/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml index 62a2d0b9dd..e4450224d7 100644 --- a/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ja/strings_device_center_feature.xml @@ -17,7 +17,7 @@ 最新版 - 初期化中\u2026 + 初期化中… スキャン中… @@ -180,7 +180,7 @@ - %1$d個のフォルダ ・  + %1$d個のフォルダ ·  追加済み diff --git a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml index c4214c3332..fde7524a7d 100644 --- a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml @@ -17,17 +17,17 @@ 최신 - 초기화중\u2026 + 초기화중… - 스캔 중... + 스캔 중… 업데이트 중… - %1$d%% 업데이트 중... + %1$d%% 업데이트 중… 카메라 업로드 없음 - 해제됨 + 비활성화됨 오프라인 diff --git a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml index f8af303c99..c5949a2ace 100644 --- a/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-nl/strings_device_center_feature.xml @@ -23,7 +23,7 @@ Updaten… - %1$d%% Updaten... + %1$d%% Updaten… Geen camera uploads diff --git a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml index 46935e6ce0..7037e0fa0e 100644 --- a/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pl/strings_device_center_feature.xml @@ -17,13 +17,13 @@ Aktualne - Uruchamianie... + Uruchamianie… Skanowanie… Aktualizowanie… - %1$d%% Aktualizowanie... + %1$d%% aktualizowanie… Brak przesłanych plików z kamery @@ -57,7 +57,7 @@ Pokaż na Dysku w chmurze - No sync error + Brak błędu synchronizacji MEGA nie może zsynchronizować ani wykonać kopii zapasowej tego katalogu, ponieważ system plików na urządzeniu nie jest obsługiwany @@ -109,13 +109,13 @@ Nieprawidłowy interwał skanowania. Sprawdź ustawienia interwału skanowania i spróbuj ponownie. - Nie można nawiązać komunikacji z lokalizacją katalogu. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu.... + Nie można nawiązać komunikacji z lokalizacją katalogu. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu…. Nie można dodać obserwacji systemu plików. Upewnij się, że jest wystarczająco dużo wolnego miejsca i pamięci oraz że masz uprawnienia do lokalizacji katalogu. Nie można odczytać lokalizacji synchronizacji. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu. - Unable to open state cache database + Nie można otworzyć bazy danych pamięci podręcznej Niewystarczająca ilość miejsca do pobrania. @@ -123,7 +123,7 @@ Nieznany błąd. - Something went wrong. + Coś poszło nie tak. Nie można synchronizować ani utworzyć kopii zapasowej katalogu, ponieważ katalog MEGA znajduje się w koszu diff --git a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml index c6299331db..44c75859cb 100644 --- a/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-pt/strings_device_center_feature.xml @@ -17,7 +17,7 @@ Atualizado - Inicializando\u2026 + Inicializando… Examinando… @@ -27,7 +27,7 @@ Não há uploads da câmera - Desativada + Desativado Offline @@ -57,7 +57,7 @@ Mostrar na Nuvem de arquivos - No sync error + Não há erros de sincronização O MEGA não pode sincronizar ou fazer backup desta pasta porque o sistema de arquivos do seu dispositivo não é suportado @@ -93,7 +93,7 @@ A sincronização ou o backup foram interrompidos porque você parece ter se desconectado do aplicativo para desktop. Faça login novamente no aplicativo para desktop e para retomar a sincronização ou o backup. - N/A + Não disponível Não é possível localizar a pasta na unidade externa. @@ -115,7 +115,7 @@ Não foi possível ler a localização da sincronização. Verifique se o local está acessível e se as permissões para a localização da pasta foram concedidas. - Unable to open state cache database + Não é possível abrir o banco de dados de cache de estado Não há espaço suficiente para fazer o download. @@ -123,7 +123,7 @@ Erro desconhecido. - Something went wrong. + Algo deu errado. Não é possível sincronizar ou fazer backup porque a pasta no MEGA está na Lixeira diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index ddcaec0be6..844af998cb 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -17,13 +17,13 @@ La zi - Se inițializează\u2026 + Se inițializează… Se scanează… Se actualizează… - %1$d%% Actualizarea… + %1$d%% actualizarea… Niciun încărcarea de cameră @@ -57,7 +57,7 @@ Afișează în Unitatea cloud - No sync error + Nicio eroare de sincronizare MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat @@ -93,7 +93,7 @@ Sincronizarea sau backupul au fost oprite pe măsură ce parcă v-ați deconectat de la aplicația desktop. Conectați-vă din nou prin aplicația desktop și reluați sincronizarea sau backup-ul. - N/A + n.d. Folderul din unitatea externă nu poate fi localizat. @@ -115,7 +115,7 @@ Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. - Unable to open state cache database + Nu se poate deschide baza de date privind starea cache-ului Spațiu insuficient pentru descărcare. @@ -123,7 +123,7 @@ Eroare necunoscută. - Something went wrong. + Ceva a mers prost. Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi @@ -186,7 +186,7 @@ %1$d folder   %1$d foldere   - %1$d de foldere   + %1$d de foldere ·  Adăugate diff --git a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml index 6cc4300f48..81218d0c4f 100644 --- a/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ru/strings_device_center_feature.xml @@ -57,7 +57,7 @@ Показать в Облачном диске - No sync error + Ошибка: отсутствует синхронизация MEGA не может синхронизировать эту папку или сделать резервную копию, потому что файловая система на вашем устройстве не поддерживается @@ -115,7 +115,7 @@ Не удалось прочитать расположение синхронизации. Убедитесь, что расположение папки доступно и предоставлены права доступа к нему. - Unable to open state cache database + Не удалось открыть базу данных кэша состояний Недостаточно места для скачивания. @@ -123,7 +123,7 @@ Неизвестная ошибка. - Something went wrong. + Что-то пошло не так. Папку невозможно синхронизировать или создать её резервную копию, так как папка MEGA находится в Корзине diff --git a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml index d965ac1be5..0d658a74c8 100644 --- a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml @@ -17,7 +17,7 @@ ล่าสุดแล้ว - กำลังเริ่มต้น... + กำลังเริ่มต้น… กำลังสแกน… @@ -27,7 +27,7 @@ ไม่มีข้อมูลอัปโหลดจากกล้อง - ปิดใช้งาน + ปิดใช้งานแล้ว ออฟไลน์ @@ -89,7 +89,7 @@ มีปัญหาในการซิงค์หรือสำรองข้อมูลในโฟลเดอร์นี้ ลองใหม่อีกครั้งในภายหลัง หากยังประสบปัญหาอยู่ ติดต่อฝ่ายสนับสนุน - บัญชีของคุณถูกโหลดซ้ำ การเปลี่ยนแปลงที่หายไปจะไม่มีผลกับการสำรองข้อมูลหรือการซิงค์ของคุณ + โหลดข้อมูลในบัญชีใหม่แล้ว แต่การอัปเดตสำรองข้อมูลหรือการซิงค์ที่พลาดไปยังไม่ได้ถูกนำไปใช้ การซิงค์หรือสำรองข้อมูลหยุดลง เนื่องจากคุณออกจากระบบแอปเดสก์ท็อปแล้ว เข้าสู่ระบบแอปเดสก์ท็อปอีกครั้งเพื่อดำเนินการซิงค์หรือสำรองข้อมูลต่อ diff --git a/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml index 50c86fd30a..3df63d5989 100644 --- a/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-vi/strings_device_center_feature.xml @@ -27,7 +27,7 @@ Không có đăng tải camêra - Đã vô hiệu + Tắt Ngoại tuyến @@ -57,7 +57,7 @@ Hiện vị trí trong Ổ Mây - No sync error + Không có lỗi đồng bộ MEGA không thể đồng bộ hoặc sao lưu thư mục này bởi vì hệ thống tệp trên thiết bị của bạn không được hỗ trợ @@ -93,7 +93,7 @@ Đồng bộ hóa hoặc sao lưu đã bị dừng do có vẻ như bạn đã đăng xuất khỏi app cho máy tính. Đăng nhập vào lại app cho máy tính để tiếp tục đồng bộ hóa hoặc sao lưu. - N/A + Không thấy Không tìm thấy vị trí của thư mục trong ổ đĩa ngoài. @@ -115,7 +115,7 @@ Không thể đọc được vị trí thư mục. Kiểm tra xem vị trí có thể truy cập được hay không và quyền đi tới vị trí thư mục đã được cấp phép. - Unable to open state cache database + Không thể mở cơ sở dữ liệu bộ đệm trạng thái Không đủ dung lượng cho việc tải xuống. @@ -123,7 +123,7 @@ Lỗi không xác định được. - Something went wrong. + Đã có vấn đề xảy ra. Thư mục không thể đồng bộ hoặc sao lưu được bởi vì thư mục tương ứng trên MEGA đang nằm trong Thùng Rác diff --git a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml index ca4958238d..96d92e0ce2 100644 --- a/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rCN/strings_device_center_feature.xml @@ -15,15 +15,15 @@ 未知设备 - 最新的 + 已是最新 - 初始化... + 正在初始化… 正在扫描… 正在更新… - %1$d%%更新中... + %1$d%%更新中… 无相机上传 @@ -57,7 +57,7 @@ 在云盘中显示 - No sync error + 无同步错误 MEGA无法同步或备份此文件夹,因为不支持您设备上的文件系统 @@ -93,7 +93,7 @@ 由于您似乎已登出桌面应用程序,因此同步或备份已停止。通过桌面应用程序重新登录,然后恢复同步或备份。 - N/A + 不适用 无法定位外部驱动器中的文件夹。 @@ -115,7 +115,7 @@ 无法读取同步位置。检查该位置是否可访问以及是否已授予该文件夹位置的权限。 - Unable to open state cache database + 无法打开状态缓存数据库 空间不足,无法下载。 @@ -123,7 +123,7 @@ 未知错误。 - Something went wrong. + 出了点问题。 由于MEGA文件夹位于回收站中,文件夹无法同步或备份 diff --git a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml index 1455c29fff..64e470e589 100644 --- a/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-zh-rTW/strings_device_center_feature.xml @@ -17,7 +17,7 @@ 最新的 - 正在初始化... + 正在初始化⋯ 正在掃描⋯ @@ -33,7 +33,7 @@ 暫停 - 備份已停止 + 備份停止 超出配額 @@ -57,7 +57,7 @@ 在雲端硬碟中顯示 - No sync error + 無同步錯誤 MEGA無法同步或備份此資料夾,因為尚不支援您裝置上的檔案系統。 @@ -89,11 +89,11 @@ 同步或備份此資料夾時出現問題。稍後再試。如果問題仍然存在,請聯繫客服。 - 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 + 帳戶已重新載入。您的備份或同步的任何遺失的更新尚未套用。 由於您似乎已登出桌面應用程式,因此同步或備份已停止。使用桌面應用程式重新登入,然後恢復同步或備份。 - N/A + 不適用 無法找到外部磁碟的資料夾。 @@ -115,7 +115,7 @@ 無法讀取同步位置。檢查該位置是否可用,而且是否已授予該資料夾位置的權限。 - Unable to open state cache database + 無法開啟狀態快取資料庫 空間不足,無法下載。 @@ -123,7 +123,7 @@ 未知錯誤。 - Something went wrong. + 出了點問題。 由於MEGA資料夾位於垃圾筒中,因此資料夾無法同步或備份 diff --git a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml index 9192fa6b9d..d46e6ecfe2 100644 --- a/feature/sync/src/main/res/values-ar/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ar/strings_sync_feature.xml @@ -6,8 +6,6 @@ مزامنة مزامنة - - مزامنة [A](%1$d)[/A] MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. @@ -54,10 +52,6 @@ مسح المشكلات التي تم حلها المزامنة ثنائية الاتجاه - - Conflict A - - هناك العديد من العناصر التي تحمل الاسم نفسه على جانب واحد من المزامنة الخاصة بك والتي ستصبح جميعها نفس العنصر الفردي على الجانب الآخر من المزامنة الخاصة بك إعادة تسمية جميع العناصر @@ -84,20 +78,14 @@ لا تسمح سماح - - Allow MEGA to read, modify or delete all files on this device. لا توجد مشكلات تم حلها لا توجد مشاكل - - قم بتسمية المزامنة مجلد الأجهزة مجلد ميغا MEGA - - نوع المزامنة متوقف مؤقتاً @@ -204,6 +192,4 @@ A move or rename action was detected locally, but couldn’t be replicated in MEGA. في انتظار انتهاء الفحص لتحديد ما إذا كان الملف قد تم نقله أو حذفه. - - اختر المجلدات \ No newline at end of file diff --git a/feature/sync/src/main/res/values-de/strings_sync_feature.xml b/feature/sync/src/main/res/values-de/strings_sync_feature.xml index 2b422fc1f1..a782ec8c51 100644 --- a/feature/sync/src/main/res/values-de/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-de/strings_sync_feature.xml @@ -6,8 +6,6 @@ Synchronisierung Synchronisierung - - Synchronisierungen [A](%1$d)[/A] Um Ihren lokalen Ordner zu synchronisieren, muss MEGA auf Ihren Gerätespeicher zugreifen. Tippen Sie hier, um Zugriff zu gewähren. @@ -38,10 +36,6 @@ Gelöste Probleme entfernen Zwei-Wege-Synchronisierung - - Conflict A - - Mehrere Elemente mit demselben Namen auf der einen Seite Ihrer Synchronisierung würden einem einzigen Element auf der anderen Seite der Synchronisierung entsprechen Alle Elemente umbenennen @@ -68,20 +62,14 @@ Nicht erlauben Erlauben - - Allow MEGA to read, modify or delete all files on this device. Keine gelösten Probleme Keine Probleme - - Synchronisierung benennen Geräteordner MEGA-Ordner - - Synchronisierungstyp Angehalten @@ -188,6 +176,4 @@ Ein Verschiebe- oder Umbenennungsvorgang wurde lokal erkannt, konnte jedoch auf MEGA nicht repliziert werden. Abschluss des Scanvorgangs wird abgewartet, um zu bestimmen, ob die Datei verschoben oder gelöscht wurde. - - Ordner auswählen \ No newline at end of file diff --git a/feature/sync/src/main/res/values-es/strings_sync_feature.xml b/feature/sync/src/main/res/values-es/strings_sync_feature.xml index 77761c833a..33451d7e9d 100644 --- a/feature/sync/src/main/res/values-es/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-es/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sincronizar Sincronizar - - Sincronizaciones [A](%1$d)[/A] MEGA necesita acceder al almacenamiento de tu dispositivo para poder sincronizar tu carpeta local. Pulsa aquí para permitir el acceso. @@ -42,10 +40,6 @@ Limpiar los problemas resueltos Sincronización bidireccional - - Conflict A - - There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Renombrar todos los elementos @@ -72,20 +66,14 @@ Denegar Permitir - - Allow MEGA to read, modify or delete all files on this device. No hay problemas resueltos No hay problemas - - Asignar nombre a la sincronización Carpeta del dispositivo Carpeta en MEGA - - Tipo de sincronización En pausa @@ -192,6 +180,4 @@ Se ha detectado un movimiento o cambio de nombre en tu dispositivo, pero no se ha podido replicar en MEGA. Esperando a que finalice el análisis para determinar si el archivo se ha movido o eliminado. - - Elegir carpetas \ No newline at end of file diff --git a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml index efbfe2335e..c85dc3c54e 100644 --- a/feature/sync/src/main/res/values-fr/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-fr/strings_sync_feature.xml @@ -6,8 +6,6 @@ Synchronisations Synchronisations - - Synchronisations [A](%1$d)[/A] MEGA a besoin d’accéder à la mémoire de votre appareil pour synchroniser votre dossier local. Touchez ici pour autoriser l’accès. @@ -42,10 +40,6 @@ Effacer les problèmes résolus Synchronisation bidirectionnelle - - Conflict A - - Plusieurs éléments du même nom d’un côté de votre synchronisation deviendraient le même élément de l’autre côté de votre synchronisation Renommer tous les éléments @@ -72,20 +66,14 @@ Ne pas autoriser Autoriser - - Allow MEGA to read, modify or delete all files on this device. Aucun problème résolu Aucun blocage - - Nommer la synchronisation Dossier sur l’appareil Dossier sur MEGA - - Type de synchronisation En pause @@ -192,6 +180,4 @@ Un déplacement ou un renommage a été détecté localement, mais n’a pas pu être reproduit sur MEGA. Attente de la fin de l’analyse pour déterminer si le fichier a été déplacé ou supprimé. - - Choisir les dossiers \ No newline at end of file diff --git a/feature/sync/src/main/res/values-in/strings_sync_feature.xml b/feature/sync/src/main/res/values-in/strings_sync_feature.xml index ea5a53875e..ce53a44d37 100644 --- a/feature/sync/src/main/res/values-in/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-in/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sinkronkan Sinkronkan - - Syncs [A](%1$d)[/A] MEGA needs to access your device storage in order to sync your local folder. Tap here to allow access. @@ -34,10 +32,6 @@ Clear resolved issues Two-way sync - - Conflict A - - There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Rename all items @@ -64,20 +58,14 @@ Jangan izinkan Izinkan - - Allow MEGA to read, modify or delete all files on this device. No resolved issues No issues - - Name the sync Device folder Folder MEGA - - Sync type Berhenti sementara @@ -184,6 +172,4 @@ A move or rename action was detected locally, but couldn’t be replicated in MEGA. Waiting for scan to finish to determine if the file was moved or deleted. - - Choose folders \ No newline at end of file diff --git a/feature/sync/src/main/res/values-it/strings_sync_feature.xml b/feature/sync/src/main/res/values-it/strings_sync_feature.xml index e6751b58f5..e8f5628b3e 100644 --- a/feature/sync/src/main/res/values-it/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-it/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sincronizza Sincronizza - - Sincronizzazioni [A](%1$d)[/A] MEGA ha bisogno dell\’accesso alla memoria del tuo dispositivo per poter sincronizzare la tua cartella locale. Tocca qui per garantire l\’accesso. @@ -42,10 +40,6 @@ Svuota i problemi risolti Sincronizzazione a doppio senso - - Conflict A - - Ci sono più oggetti con lo stesso nome da un lato della sincronizzazione che diverrebbero tutti lo stesso oggetto dall\’altro lato della sincronizzazione Rinomina tutti gli oggetti @@ -72,20 +66,14 @@ Non permettere Permetti - - Allow MEGA to read, modify or delete all files on this device. Nessun problema risolto Nessun problema - - Dai un nome alla sincronizzazione Cartella sul dispositivo Cartella MEGA - - Tipo della sincronizzazione In pausa @@ -192,6 +180,4 @@ È stata riscontrata un\’azione locale di spostamento o di rinominazione, ma non riesce a ripeterla su MEGA. In attesa del completamento della scansione per determinare se il file è stato spostato o eliminato. - - Scegli cartelle \ No newline at end of file diff --git a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml index f7652444d2..fa49492e27 100644 --- a/feature/sync/src/main/res/values-ja/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ja/strings_sync_feature.xml @@ -6,8 +6,6 @@ 同期 同期 - - 同期 [A](%1$d)[/A] ローカルフォルダを同期するには、MEGAはお使いのデバイスのストレージにアクセスする必要があります。こちらをタップしてアクセスを許可してください。 @@ -34,10 +32,6 @@ 解決済みの問題をクリア 双方向同期 - - Conflict A - - 同期の一方の側に同じ名前の複数の項目がありますが、同期のもう一方の側ではすべて同じ1つの項目になります。 すべての項目の名前を変更する @@ -64,20 +58,14 @@ 許可しない 許可 - - Allow MEGA to read, modify or delete all files on this device. 解決済みの問題はありません 問題はありません - - 同期に名前を付ける デバイスフォルダ MEGAフォルダ - - 同期タイプ 一時停止中 @@ -184,6 +172,4 @@ 移動または名前変更アクションがローカルで検出されましたが、MEGAで複製できませんでした。 ファイルが移動または削除されたかどうかを判断するために、スキャンが完了するのを待っています。 - - フォルダを選択 \ No newline at end of file diff --git a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml index 2da881bec3..1f7af18cca 100644 --- a/feature/sync/src/main/res/values-ko/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ko/strings_sync_feature.xml @@ -6,8 +6,6 @@ 동기화 동기화 - - 동기화 [A](%1$d)[/A] 당신의 로컬 폴더를 동기화하기 위해 MEGA가 장치 저장소에 접근이 필요합니다. 접근을 승인하려면 여기를 탭하세요 @@ -34,10 +32,6 @@ 해결된 문제 지우기 양방향 동기화 - - Conflict A - - 동기화의 한쪽에서 같은 이름을 다신 여러 항목이 있지만 동기화의 다른 쪽에서 같은 하나의 항목이 될 것입니다 모든 항목 이름 변경 @@ -64,20 +58,14 @@ 허용하지 않음 허용 - - Allow MEGA to read, modify or delete all files on this device. 해결된 문제 없음 문제 없음 - - 동기화 이름을 만드세요 장치 폴더 MEGA 폴더 - - 동기화 유형 일시정지 중 @@ -184,6 +172,4 @@ 로컬에서 이동 또는 이름 변경을 감지하였지만, MEGA에 반영할 수 없었습니다. 파일이 이동되거나 삭제되었는지 확인하기 위해 스캔이 완료되기를 기다리는 중입니다. - - 폴더 선택 \ No newline at end of file diff --git a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml index 3264c2fd4b..ce43010c95 100644 --- a/feature/sync/src/main/res/values-nl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-nl/strings_sync_feature.xml @@ -6,8 +6,6 @@ Synchroniseren Synchroniseren - - Synchronisaties [A](%1$d)[/A] MEGA heeft toegang nodig tot de opslag van uw apparaat om uw lokale map te kunnen synchroniseren. Tik hier om toegang toe te staan. @@ -38,10 +36,6 @@ Opgeloste problemen oplossen Tweezijdige synchronisatie - - Conflict A - - Er zijn meerdere items met dezelfde naam aan één kant van uw synchronisatie die allemaal één dezelfde bestand worden aan de andere kant van uw synchronisatie Hernoem alle items @@ -68,24 +62,18 @@ Niet toestaan Toestaan - - Allow MEGA to read, modify or delete all files on this device. Geen opgeloste problemen Geen problemen - - Geef de synchronisatie een naam Apparaat map MEGA map - - Synchronisatie type Gepauzeerd - Synchroniseren... + Synchroniseren… Gestopt @@ -188,6 +176,4 @@ Er is lokaal een actie voor het verplaatsen of hernoemen van de naam gedetecteerd, maar deze kon niet worden gerepliceerd in MEGA. Wacht tot de scan is voltooid om te bepalen of het bestand is verplaatst of verwijderd. - - Kies mappen \ No newline at end of file diff --git a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml index 1ff3fa917b..32d65acff0 100644 --- a/feature/sync/src/main/res/values-pl/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pl/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sync Sync - - Synchronizacja [A](%1$d)[/A] MEGA musi uzyskać dostęp do pamięci urządzenia, aby zsynchronizować katalog lokalny. Kliknij tutaj, aby zezwolić na dostęp. @@ -46,10 +44,6 @@ Wyczyść rozwiązane problemy Synchronizacja dwukierunkowa - - Conflict A - - Istnieje wiele elementów o tej samej nazwie po jednej stronie synchronizacji, które stały się tym samym pojedynczym elementem po drugiej stronie synchronizacji Zmień nazwę wszystkich elementów @@ -76,24 +70,18 @@ Nie zezwalaj Zezwól - - Allow MEGA to read, modify or delete all files on this device. Brak rozwiązanych problemów Brak problemów - - Nazwa synchronizacji Katalog urządzeń MEGA katalog - - Typ synchronizacji Zatrzymane - Synchronizacja... + Synchronizacja… Zatrzymane @@ -196,6 +184,4 @@ Akcja przeniesienia lub zmiany nazwy została wykryta lokalnie, ale nie można jej powtórzyć w MEGA. Oczekiwanie na zakończenie skanowania w celu ustalenia, czy plik został przeniesiony lub usunięty. - - Wybierz katalogi \ No newline at end of file diff --git a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml index 1070132a54..d83a8bc0af 100644 --- a/feature/sync/src/main/res/values-pt/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-pt/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sincronizar Sincronizar - - Sincronizações [A](%1$d)[/A] O MEGA precisa acessar o armazenamento do seu dispositivo para sincronizar a sua pasta local. Toque aqui para permitir o acesso @@ -42,10 +40,6 @@ Deletar os problemas solucionados Sincronização bidirecional - - Conflict A - - Há vários itens com o mesmo nome em um lado da sincronização que se tornariam todos o mesmo item no outro lado da sincronização. Renomear todos os itens @@ -72,24 +66,18 @@ Não permitir Permitir - - Allow MEGA to read, modify or delete all files on this device. Não há problemas solucionados Não há problemas - - Nomeie a sincronização Pasta no dispositivo Pasta no MEGA - - Tipo de sincronização Pausado - Sincronizando... + Sincronizando… Interrompida @@ -192,6 +180,4 @@ Foi detectada no dispositivo local uma ação para mover ou renomear, mas não foi possível replicá-la no MEGA. Esperando terminar de escanear para comprovar se o arquivo foi movido ou deletado. - - Escolher pastas \ No newline at end of file diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index 6685a69b56..d392572ba0 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -6,8 +6,6 @@ Sincronizează Sincronizează - - Sincronizări [A](%1$d)[/A] MEGA trebuie să acceseze spațiul de stocare al dispozitivului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. @@ -42,10 +40,6 @@ Ștergeți problemele rezolvate Sincronizarea bidirecțională - - Conflict A - - Există mai multe elemente cu același nume pe o parte a sincronizării dvs. care ar deveni toate același element unic pe cealaltă parte a sincronizării Redenumiți toate elementele @@ -72,20 +66,14 @@ Nu permiteți Permite - - Allow MEGA to read, modify or delete all files on this device. Nicio problemă rezolvată Nicio problemă - - Denumiți sincronizarea Folderul dispozitivului Folder MEGA - - Tipul de sincronizare Pus pe pauză @@ -107,7 +95,7 @@ Elimină - Wi-Fi sau plan de date + Wi-Fi sau date mobile Numai Wi-Fi @@ -192,6 +180,4 @@ O mutare sau redenumire a fost detectată local, dar nu a putut fi replicată în MEGA. Așteptarea finalizării scanării pentru a determina dacă fișierul a fost mutat sau șters. - - Alegeți foldere \ No newline at end of file diff --git a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml index c99ebfd865..15c546918f 100644 --- a/feature/sync/src/main/res/values-ru/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ru/strings_sync_feature.xml @@ -6,8 +6,6 @@ Синхронизация Синхронизация - - Синхронизации [A](%1$d)[/A] MEGA нужен доступ к памяти устройства, чтобы синхронизировать локальную папку. Нажмите здесь, чтобы предоставить доступ. @@ -46,10 +44,6 @@ Удалить исправленные ошибки Двухсторонняя синхронизация - - Conflict A - - На одной стороне синхронизации есть несколько элементов с одинаковым названием, которые на другой стороне синхронизации станут одним и тем же элементом Переименовать все элементы @@ -76,20 +70,14 @@ Не разрешать Разрешить - - Allow MEGA to read, modify or delete all files on this device. Нет исправленных ошибок Нет ошибок - - Назовите синхронизацию Папка на устройстве MEGA-папка - - Тип синхронизации На паузе @@ -196,6 +184,4 @@ Обнаружена локальная операция перемещения или переименования, но её не удалось воспроизвести в MEGA. Ожидание завершения сканирования, чтобы определить, был ли файл перемещён или удалён. - - Выбор папок \ No newline at end of file diff --git a/feature/sync/src/main/res/values-th/strings_sync_feature.xml b/feature/sync/src/main/res/values-th/strings_sync_feature.xml index b699fd73ab..5391cea833 100644 --- a/feature/sync/src/main/res/values-th/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-th/strings_sync_feature.xml @@ -6,8 +6,6 @@ ซิงค์ ซิงค์ - - ซิงค์ [A](%1$d)[/A] MEGA ต้องการเข้าถึงพื้นที่เก็บข้อมูลในอุปกรณ์เพื่อซิงค์โฟลเดอร์ในเครื่องของคุณ แตะที่นี่เพื่ออนุญาตให้เข้าถึง @@ -34,10 +32,6 @@ ล้างรายการที่แก้ไขปัญหาเสร็จแล้ว ซิงค์แบบสองทาง - - Conflict A - - พบหลายรายการที่มีชื่อซ้ำกันหลายชื่อ แต่จะมีการรวมชื่อที่ซ้ำกันให้เป็นชื่อเดียว เปลี่ยนชื่อรายการทั้งหมด @@ -64,20 +58,14 @@ ไม่อนุญาต อนุญาต - - Allow MEGA to read, modify or delete all files on this device. ปัญหาทั้งหมดได้รับการแก้ไขแล้ว ยังไม่พบปัญหาใด ๆ - - ชื่อการซิงค์ โฟลเดอร์อุปกรณ์ โฟลเดอร์ MEGA - - ประเภทการซิงค์ พักแล้ว @@ -184,6 +172,4 @@ ตรวจพบการย้ายหรือเปลี่ยนชื่อไฟล์ในอุปกรณ์ แต่ไม่สามารถอัปเดตรายการใน MEGA ให้ตรงกันได้ กำลังรอการสแกนเพื่อดูว่าไฟล์ถูกย้ายหรือลบไปหรือไม่ - - เลือกโฟลเดอร์ \ No newline at end of file diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 5f78fe90a8..aea78f06a3 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -6,8 +6,6 @@ Đồng bộ Đồng bộ - - Đồng bộ [A](%1$d)[/A] MEGA cần truy cập bộ nhớ thiết bị để đồng bộ hóa thư mục cục bộ của bạn. Chạm vào đây để cho phép quyền truy cập. @@ -34,10 +32,6 @@ Dọn các vấn đề đã giải quyết Đồng bộ hai chiều - - Conflict A - - There are multiple items with the same name on one side of your sync that would all become the same single item on the other side of your sync Đổi tên tất cả các mục @@ -64,20 +58,14 @@ Không cho phép Cho phép - - Allow MEGA to read, modify or delete all files on this device. Không có vấn đề đã giải quyết Không có vấn đề - - Đặt tên cho việc đồng bộ Thư mục thiết bị Thư mục trên MEGA - - Kiểu đồng bộ Đã tạm dừng @@ -184,6 +172,4 @@ Một việc di chuyển hoặc đổi tên đã được phát hiện tại cục bộ, nhưng không thể phỏng y theo trên MEGA. Đang chờ cho quá trình quét kết thúc để xác định xem có tệp tin nào đã di chuyển hay bị xóa. - - Chọn các thư mục \ No newline at end of file diff --git a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml index 82a02f86cb..31e6ea5a70 100644 --- a/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rCN/strings_sync_feature.xml @@ -6,8 +6,6 @@ 同步 同步 - - 同步[A](%1$d)[/A] MEGA需要访问您设备的存储空间,以便同步您的本地文件夹。点按此处以允许访问。 @@ -34,10 +32,6 @@ 清除已解决的问题 双向同步 - - Conflict A - - 同步的一侧具有多个相同名称的项目,这些项目在同步的另一侧都将成为相同的单一项目 重命名所有项目 @@ -64,20 +58,14 @@ 不允许 允许 - - Allow MEGA to read, modify or delete all files on this device. 没有已解决的问题 没问题 - - 为同步命名 设备文件夹 MEGA文件夹 - - 同步类型 已暂停 @@ -184,6 +172,4 @@ 在本地检测到移动或重命名操作,但无法在MEGA中复制。 等待扫描完成以确定文件是否已移动或删除。 - - 选择文件夹 \ No newline at end of file diff --git a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml index 676a2993ec..9550abd9f7 100644 --- a/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-zh-rTW/strings_sync_feature.xml @@ -6,8 +6,6 @@ 同步 同步 - - 同步[A](%1$d)[/A] MEGA需要存取您裝置的儲存空間,以便同步您的本地資料夾。點選此處以允許存取。 @@ -34,10 +32,6 @@ 清除已解決的問題 雙向同步 - - Conflict A - - 同步的一側有多個具有相同名稱的項目,這些項目在同步的另一側都將成為相同的單一項目 重新命名所有項目 @@ -64,20 +58,14 @@ 不允許 允許 - - Allow MEGA to read, modify or delete all files on this device. 沒有已解決的問題 沒有問題 - - 為同步命名 裝置資料夾 MEGA資料夾 - - 同步類型 暫停 @@ -117,7 +105,7 @@ 無法移動或重新命名 - Delete or move action is waiting for scan + 刪除或移動操作正在等待掃描 還無法刪除 @@ -157,7 +145,7 @@ 選擇 - An item has an issue that needs your decision to resolve it + 一個項目存在需要您的決定才能解決的問題 正在等待其它程序完成 @@ -184,6 +172,4 @@ 在本地偵測到移動或重新命名操作,但無法在MEGA中複製。 等待掃描完成以確定檔案是否已移動或刪除。 - - 選擇資料夾 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 637f4c7805..772ddfd635 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -85,13 +85,13 @@ Syncing paused, battery level too low. Charge battery to resume syncing. - Easy, secure file sharing + مشاركة ملفات سهلة وآمنة - Share large files thanks to a generous transfer quota and ensure security with password-protected links. + يمكنك مشاركة الملفات الكبيرة بفضل حجم تراسل المعطيات السخي وضمان الأمان باستخدام الروابط المحمية بكلمة مرور. - Never lose data again + لا تفقد البيانات مرة أخرى - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -99,7 +99,7 @@ مكالمات واجتماعات غير مقيدة - Message, video call, and meet in total privacy with unlimited participants. + أرسل رسالة ومكالمة فيديو واجتمع في خصوصية تامة مع عدد غير محدود من المشاركين. النوع @@ -316,4 +316,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + Solved issues + + You can’t sync folders that are currently synced folders. + + الوصف + + إضافة وصف + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index eb81c10888..08a6a37f55 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -91,7 +91,7 @@ Nie mehr Datenverlust - Sichern und synchronisieren Sie Ihre Daten, um sich stets auf ihre Verfügbarkeit verlassen zu können. Mit der Rewind-Funktion können Sie Ordner zudem auf einen früheren Stand (bis zu 180 Tage) zurücksetzen. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -296,4 +296,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + Gelöste Probleme + + You can’t sync folders that are currently synced folders. + + Beschreibung + + Beschreibung hinzufügen + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index b937547583..8d90980578 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -91,7 +91,7 @@ No vuelva a perder datos - Sincroniza y haz backups de tus datos para disfrutar de una tranquilidad absoluta. Además, puedes usar el Rebobinado para restaurar carpetas hasta 180 días. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -304,4 +304,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + Solved issues + + You can’t sync folders that are currently synced folders. + + Descripción + + Añadir descripción + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 92d940bd79..181e6a7694 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -91,7 +91,7 @@ Ne plus jamais perdre de données - Ayez l’esprit tranquille en sauvegardant et synchronisant vos données. De plus, le Retour en arrière vous permet de rétablir n’importe quelle version antérieure de vos dossiers, jusqu’à 180 jours. + Retournez en arrière pour restaurer les dossiers à une date antérieure jusqu’à 180 jours. Ainsi, vos données sont protégées contre les accidents et les manipulations, inviolables. RPV MEGA VPN @@ -297,11 +297,37 @@ Le compte est désactivé - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Votre compte Pro Flexi a été désactivé pour défaut de paiement. Vous ne pourrez plus accéder aux données stockées dans votre compte.\nPour effectuer un paiement et réactiver votre abonnement, connectez-vous à MEGA dans un navigateur. Starter Basic Essential + + Les téléversements seront mis en pause jusqu’à ce votre appareil soit en charge. Les téléversements resteront en pause si le niveau de votre batterie est inférieur à 20 %. + + Aucune synchronisation n’est configurée + + Synchronisez un dossier local sur votre appareil avec un dossier sur MEGA. + + Ajouter une nouvelle synchronisation + + Problèmes résolus + + You can’t sync folders that are currently synced folders. + + Description + + Ajoutez une description + + Une description a été ajoutée + + La description a été mise à jour + + Et l’accès à ces avantages intéressants : + + • RPV MEGA VPN\n• Réunions et appels illimités\n• Synchronisation automatiquement des dossiers de votre appareil mobile\n• Sans publicités + + • RPV MEGA VPN\n• Réunions et appels illimités\n• Synchronisation automatiquement des dossiers de votre appareil mobile \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 89c7e7194b..ce79ad04e3 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -91,7 +91,7 @@ Jangan pernah kehilangan data lagi - Cadangkan dan sinkronkan data anda untuk kepercayaan penuh. Dan, gunakan Rewind untuk mengembalikan folder ke tanggal apa pun hingga 180 hari. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -175,7 +175,7 @@ Hapus - No playlists found + Tidak ada daftar putar yang ditemukan Delete playlist @@ -292,4 +292,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + Solved issues + + You can’t sync folders that are currently synced folders. + + Deskripsi + + Tambah deskripsi + + Description added + + Description updated + + Ditambah akses ke manfaat besar ini: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 939ae93e5d..5db1a4a219 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -91,7 +91,7 @@ Non perdere mai più dati - Effettua il backup e la sincronizzazione dei dati per la massima sicurezza. Inoltre, utilizza il Riavvolgimento per ripristinare le cartelle a qualsiasi data fino a 180 giorni. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -267,7 +267,7 @@ Solo questa volta - Always download here + Scarica sempre qui Chiedi sempre la posizione del download @@ -275,11 +275,11 @@ TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + A partire da %1$s %2$s, trova la soluzione perfetta per le tue esigenze di archiviazione. Spazio di archiviazione insufficiente - The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. + Le dimensioni di questa cartella porteranno il tuo account MEGA a superare il limite di spazio di archiviazione. Per poterla sincronizzare, dovrai liberare dello spazio o effettuare l\’upgrade del tuo account MEGA. Vedi i piani @@ -287,21 +287,47 @@ Se hai scritto male il tuo indirizzo e-mail, correggilo e poi tocca su [A]Reinvia[/A]. - Syncing paused, your MEGA plan has run out of storage + Sincronizzazione in pausa, hai terminato lo spazio di archiviazione disponibile per il tuo piano MEGA Effettua l’upgrade - Upload paused, phone is not charging + Caricamento in pausa, il dispositivo non è in carica - No syncs set up + Nessuna sincronizzazione configurata Account disattivato - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Il tuo account Pro Flexi è stato disattivato a causa di un mancato pagamento oppure perché hai disattivato il tuo abbonamento. Non potrai accedere ai dati archiviati nel tuo account.\nPer effettuare un pagamento e riattivare l\’abbonamento, accedi a MEGA tramite un browser. Starter Basic Essential + + I caricamenti verranno sospesi fino a quando non inizierai a caricare il dispositivo. I caricamenti rimarranno comunque in pausa se la batteria è inferiore al 20%. + + Nessuna sincronizzazione configurata + + Sincronizza una cartella locale sul tuo dispositivo con una cartella su MEGA. + + Aggiungi una nuova sincronizzazione + + Problemi risolti + + You can’t sync folders that are currently synced folders. + + Descrizione + + Aggiungi descrizione + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 717e80ea0b..8cfda47d47 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -91,7 +91,7 @@ 二度とデータを失わない - データをバックアップして同期すると、完全に自信が持てます。さらに、巻き戻しを使用すると、フォルダを最大180日以内の任意の日付に復元できます。 + 巻き戻してフォルダを最大180日までの任意の日付に復元できるため、データの事故や改ざんが防止されます。 MEGA VPN @@ -288,4 +288,30 @@ Basic Essential + + デバイスの充電を開始するまで、アップロードは一時停止されます。バッテリー残量が20 %未満の場合も、アップロードは一時停止されたままになります。 + + 同期が設定されていません + + デバイス上のローカルフォルダをMEGA上のフォルダと同期します。 + + 新しい同期を追加する + + 解決済みの問題 + + You can’t sync folders that are currently synced folders. + + 説明 + + 説明を追加 + + 説明が追加されました + + 説明が更新されました + + さらに、以下の素晴らしい特典もご利用いただけます: + + • MEGA VPN \n• 無制限の通話とミーティング \n• モバイルデバイス上のフォルダを自動的に同期 \n• 広告なし + + • MEGA VPN \n• 無制限の通話とミーティング \n• モバイルデバイス上のフォルダを自動的に同期 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 6d9c608f4c..18cd7b0da0 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -91,7 +91,7 @@ 다시는 데이터를 잃지 마세요 - 완벽한 확신을 위해 데이터를 백업하고 동기화하세요. 또한, 되돌리기를 이용하여 폴더를 최대 180일까지 원하는 날짜로 복원하세요. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -288,4 +288,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + 해결된 문제 + + You can’t sync folders that are currently synced folders. + + 설명 + + 설명 추가 + + 설명 추가됨 + + 설명 수정됨 + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 4d84b2827f..a928d03c9d 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -91,7 +91,7 @@ Verlies nooit meer gegevens - Maak een back-up van je gegevens en synchroniseer ze in alle vertrouwen. Bovendien kunt u Terugspoelen gebruiken om mappen te herstellen naar een willekeurige datum tot 180 dagen. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -289,11 +289,37 @@ Account gedeactiveerd - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Uw Pro   Flexi-account is gedeactiveerd vanwege een mislukte betaling of u heeft uw abonnement opgezegd. U hebt geen toegang tot de gegevens die zijn opgeslagen in uw account. \nOm een betaling uit te voeren en uw abonnement te her activeren, moet u via een browser bij MEGA inloggen. Starter Basic Essential + + Het uploaden wordt gepauzeerd totdat u begint met het opladen van uw apparaat. Het uploaden blijft gepauzeerd als uw batterij minder dan 20% is. + + Geen synchronisaties ingesteld + + Synchroniseer een lokale map op uw apparaat met een map op MEGA. + + Nieuwe synchronisatie toevoegen + + Opgeloste problemen + + You can’t sync folders that are currently synced folders. + + Omschrijving + + Omschrijving toevoegen + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index a618a1a422..b9d1f8d233 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -91,7 +91,7 @@ Nigdy więcej nie utrać danych - Utwórz kopię zapasową i synchronizuj dane, aby uzyskać pełną pewność. Ponadto użyj Przewiń do tyłu, aby przywróć katalog do dowolnej daty do 180 dni. + Przewiń do tyłu, aby przywrócić katalog z powrotem do dowolnej daty do 180 dni, aby Twoje dane były odporne na wypadki i manipulacje. MEGA VPN @@ -312,4 +312,30 @@ Basic Essential + + Przesyłanie zostanie wstrzymane, dopóki nie zaczniesz ładować urządzenie. Przesyłanie nadal pozostanie wstrzymane, jeśli bateria jest poniżej 20%. + + Brak ustawień synchronizacji + + Synchronizuj katalog lokalny na urządzeniu z katalogiem w MEGA. + + Dodaj nową synchronizację + + Rozwiązane problemy + + You can’t sync folders that are currently synced folders. + + Opis + + Dodaj opis + + Opis dodany + + Opis zaktualizowany + + Plus dostęp do tych wspaniałych korzyści: + + •   MEGA   VPN \n•   Nieograniczone połączenia i spotkania \n•   Automatyczna synchronizacja katalogów na urządzeniu mobilnym \n•   Brak reklam + + •   MEGA   VPN \n•   Nieograniczone połączenia i spotkania \n•   Automatyczna synchronizacja katalogów na urządzeniu mobilnym \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index c319d78553..ea1857b264 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -91,7 +91,7 @@ Nunca mais perca dados - Faça backup e sincronize os seus dados para não correr riscos. Além disso, use a função Retroceder para fazer com que as suas pastas voltem ao estado que tinham em qualquer momento dos últimos 180 dias. + Use o Retroceder para restaurar as pastas para qualquer data até 180 dias, para que seus dados fiquem à prova de acidentes e adulteração. MEGA VPN @@ -297,11 +297,37 @@ Conta desativada - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + A sua conta Pro Flexi foi desativada porque o pagamento falhou ou porque você cancelou a sua assinatura. Já não será possível acessar os dados armazenados na sua conta. \nPara fazer o pagamento e assim reativar a sua assinatura, faça login no MEGA por meio de um navegador em um computador. Starter Basic Essential + + Os uploads permanecerão pausados até você começar a carregar o seu dispositivo, e vão continuar pausados se você tiver menos de 20% de bateria. + + Não há sincronizações configuradas + + Sincronize uma pasta local no seu dispositivo com uma pasta no MEGA. + + Adicionar uma nova sincronização + + Problemas solucionados + + You can’t sync folders that are currently synced folders. + + Descrição + + Adicionar descrição + + Descrição adicionada + + Descrição atualizada + + Além de acesso a estas fantásticas vantagens: + + • MEGA VPN \n•   Chamadas e reuniões irrestritas \n•   Sincronização automática das pastas no seu dispositivo móvel \n•   Sem anúncios + + • MEGA VPN \n•   Chamadas e reuniões irrestritas \n•   Sincronização automática das pastas no seu dispositivo móvel \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index df84c39d4c..2e7d16d85c 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -91,7 +91,7 @@ Nu pierdeți niciodată datele - Fiți liniștit prin back-up și sincronizare a datelor. În plus, utilizați Derulează înapoi pentru a restabili folderele la orice dată de până la 180 de zile. + Derulează înapoi pentru a restabili folderele la orice dată până la 180 de zile, astfel încât datele dvs. să fie protejate împotriva accidentelor și a manipulării. MEGA VPN @@ -287,21 +287,47 @@ Dacă ați scris greșit adresa dvs. de e-mail, corectați-o și atingeți [A]Retrimite[/A]. - Syncing paused, your MEGA plan has run out of storage + Sincronizarea a fost întreruptă. Planul dvs. MEGA a rămas fără spațiu de stocare. Upgradează Încărcarea este întreruptă, deoarece telefonul nu se încarcă - No syncs set up + Nu este configurată nicio sincronizare Cont dezactivat - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Contul dvs. Pro Flexi a fost dezactivat din cauza neplății sau v-ați anulat abonamentul. Nu veți mai putea accesa datele stocate în contul dvs.\nPentru a efectua o plată și a vă reactiva abonamentul, conectați-vă la MEGA printr-un browser. Starter Basic Essential + + Încărcările vor fi întrerupte până când începeți să încărcați dispozitivul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. + + Nu este configurată nicio sincronizare + + Sincronizați un folder local de pe dispozitiv cu un folder de pe MEGA. + + Adăugați o nouă sincronizare + + Probleme rezolvate + + You can’t sync folders that are currently synced folders. + + Descriere + + Adaugă o descriere + + A fost adăugată o descriere + + Descriere a fost actualizată + + Și acces la aceste beneficii interesante: + + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil\n• Fără reclame + + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 2e97072428..b9a6ae4d14 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -91,7 +91,7 @@ Данные больше не потеряются - Создавайте резервные копии и синхронизируйте данные для полной уверенности. Также используйте функцию перемотки, чтобы восстановить папки до любой даты за период до 180 дней. + Перемотка позволяет восстановить папки на любую дату за период до 180 дней, чтобы ваши данные были защищены от случайного повреждения и постороннего вмешательства. MEGA VPN @@ -305,11 +305,37 @@ Аккаунт деактивирован - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Ваш аккаунт Pro Flexi был деактивирован из-за сбоя оплаты или из-за того, что вы отменили подписку. Вы не сможете получить доступ к данным, хранящимся в вашем аккаунте.\nДля оплаты и возобновления подписки войдите в MEGA через веб-браузер. Starter Basic Essential + + Загрузка будет приостановлена до тех пор, пока вы не начнете заряжать устройство. Загрузка по-прежнему будет приостановлена, если уровень заряда батареи ниже 20%. + + Синхронизация не настроена + + Синхронизируйте локальную папку на устройстве с папкой в MEGA. + + Добавить синхронизацию + + Решённые проблемы + + You can’t sync folders that are currently synced folders. + + Описание + + Добавить описание + + Описание добавлено + + Описание обновлено + + Плюс доступ к этим замечательным преимуществам: + + • MEGA VPN \n• Неограниченные звонки и встречи \n• Автоматическая синхронизация папок на мобильном устройстве \n• Без рекламы + + • MEGA VPN \n• Неограниченные звонки и встречи \n• Автоматическая синхронизация папок на мобильном устройстве \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index babc4528ab..5ff3793c97 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -91,7 +91,7 @@ ไม่มีพลาดทุกข้อมูลสำคัญของคุณ - สำรองและซิงค์ข้อมูลของคุณเพื่อความมั่นใจสูงสุด เพิ่มเติมด้วยฟีเจอร์ย้อนกลับ ที่ช่วยให้คุณกู้คืนโฟลเดอร์กลับไปยังวันที่ต้องการได้สูงสุด 180 วัน + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -288,4 +288,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + ยังไม่ได้ตั้งค่าการซิงค์ + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + แก้ไขปัญหาแล้ว + + You can’t sync folders that are currently synced folders. + + รายละเอียด + + เพิ่มคำอธิบาย + + เพิ่มคำอธิบายแล้ว + + อัปเดตคำอธิบายแล้ว + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 18d2e9066c..479da39086 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -91,7 +91,7 @@ Không bao giờ mất dữ liệu nữa - Sao lưu và đồng bộ hóa dữ liệu để bạn hoàn toàn tự tin. Ngoài ra, sử dụng Tua lại để khôi phục các thư mục về bất kỳ ngày nào trong phạm vi 180 ngày. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -281,11 +281,37 @@ Tài khoản đã bị vô hiệu hóa - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Tài khoản Pro Flexi của bạn đã bị vô hiệu hóa do việc thanh toán đã không thành công hoặc bạn đã hủy gói đăng ký dịch vụ. Bạn sẽ không thể truy cập vào dữ liệu đã được lưu trữ trong tài khoản của mình. \nĐể thanh toán và kích hoạt lại gói đăng ký của bạn, hãy đăng nhập vào MEGA bằng trình duyệt web. Starter Basic Essential + + Cá phiên tải lên sẽ bị tạm dừng cho đến khi bạn sạc thiết bị của mình. Việc tải lên sẽ vẫn tạm dừng nếu pin của bạn dưới mức 20%. + + Không có đồng bộ nào đã lập + + Đồng bộ một thư mục cục bộ trong thiết bị của bạn với một thư mục trên MEGA. + + Thêm đồng bộ mới + + Đã giải quyết + + You can’t sync folders that are currently synced folders. + + Chi tiết + + Thêm miêu tả + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 9498043673..aa35635886 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -91,7 +91,7 @@ 再也不会丢失数据 - 让您完全放心的备份和同步您的数据。另外,使用还原功能将可将文件夹恢复到任何日期,最长可达180天。 + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -288,4 +288,30 @@ Basic Essential + + 上传将暂停,直到您开始为设备充电。如果您的电池电量低于20%,上传仍将保持暂停状态。 + + 未设置同步 + + 将设备上的本地文件夹与MEGA上的文件夹同步。 + + 添加新同步 + + 已解决的问题 + + You can’t sync folders that are currently synced folders. + + 描述 + + 添加说明 + + 已添加描述 + + 描述已更新 + + 此外还可获得以下丰厚受益: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index e15e1d53b6..d49aa7cf9a 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -33,7 +33,7 @@ 同步或備份此資料夾時出現問題。稍後再試。如果問題仍然存在,請聯繫客服。 - 帳戶已重新載入。您備份或同步的任何遺失的更新尚未套用。 + 帳戶已重新載入。您的備份或同步的任何遺失的更新尚未套用。 由於您似乎已登出桌面應用程式,因此同步或備份已停止。使用桌面應用程式重新登入,然後恢復同步或備份。 @@ -91,7 +91,7 @@ 再也不會遺失資料 - 讓您完全放心的備份和同步您的資料。此外,使用回溯功能可將資料夾恢復到任何日期,最長可達180天。 + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -255,7 +255,7 @@ 總是詢問下載位置 -  GB + GB TB @@ -281,11 +281,37 @@ 帳戶已停用 - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + 由於付款失敗或您已取消訂閱,您的Pro Flexi帳戶已被停用。您將無法存取儲存在您帳戶中的資料。\n若要進行付款並重新啟用您的訂閱,請透過網頁瀏覽器登入MEGA操作。 Starter Basic Essential + + 上傳將暫停,直到您開始為裝置充電。如果您的電池電量低於20%,上傳仍將保持暫停狀態。 + + 未設定同步 + + 將裝置上的本地資料夾與MEGA上的資料夾同步。 + + 加入新的同步 + + 已解決的問題 + + You can’t sync folders that are currently synced folders. + + 說明 + + 加入說明 + + 已新增說明 + + 已更新說明 + + 此外還可獲得這些超棒的好處: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 6ec2600cec..a1b1c88b5b 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -91,7 +91,7 @@ Never lose data again - Back up and sync your data for complete confidence. Plus, use Rewind to restore folders to any date up to 180 days. + Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -296,4 +296,30 @@ Basic Essential + + Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + + No syncs set up + + Sync a local folder on your device with a folder on MEGA. + + Add new sync + + Solved issues + + You can’t sync folders that are currently synced folders. + + Description + + Add description + + Description added + + Description updated + + Plus access to these great benefits: + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + + • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \ No newline at end of file From 5bd3e452d4fe1cf4d27fd672e7d0cb6c829475bc Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Fri, 24 May 2024 06:37:45 +0700 Subject: [PATCH 133/261] CC-7276: Fix getCCPreferences Crash When No Internet --- .../android/data/repository/DefaultSettingsRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/src/main/java/mega/privacy/android/data/repository/DefaultSettingsRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/DefaultSettingsRepository.kt index 67dee20c4b..05e38f9615 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/DefaultSettingsRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/DefaultSettingsRepository.kt @@ -529,7 +529,7 @@ internal class DefaultSettingsRepository @Inject constructor( ?.getJSONObject(JSON_SENSITIVES.value) ?.getBoolean(JSON_VAL_SHOW_HIDDEN_NODES.value) ?: false - } catch (e: Exception) { + } catch (e: Throwable) { false } } From b0ff73716d9471c994198a118c750ffe50627d64 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 27 May 2024 08:18:06 +0700 Subject: [PATCH 134/261] AND-18856: Fix crash create encrypted datastore some devices (cherry picked from commit 9a12bdab21948d89fe409703c757253e504621d1) --- .../android/data/di/DataStoreModule.kt | 11 ++--- .../EncryptedPreferenceDataStoreFactory.kt | 42 ++++++++++++++----- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt b/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt index 6d067c4476..84e3a0a96c 100644 --- a/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt @@ -8,7 +8,6 @@ import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.emptyPreferences import androidx.datastore.preferences.preferencesDataStoreFile -import androidx.security.crypto.EncryptedFile import androidx.security.crypto.MasterKey import dagger.Module import dagger.Provides @@ -128,12 +127,6 @@ internal object DataStoreModule { migration: CredentialsPreferencesMigration, masterKey: MasterKey, ): DataStore { - val encryptedFile = EncryptedFile.Builder( - context, - context.preferencesDataStoreFile(credentialDataStoreName), - masterKey, - EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB - ).build() return PreferenceDataStoreFactory.createEncrypted( corruptionHandler = ReplaceFileCorruptionHandler( produceNewData = { emptyPreferences() } @@ -142,7 +135,9 @@ internal object DataStoreModule { migration ), scope = CoroutineScope(ioDispatcher), - produceFile = { encryptedFile } + masterKey = masterKey, + context = context, + fileName = credentialDataStoreName ) } } diff --git a/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt b/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt index 006e694de9..e897713ea4 100644 --- a/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt +++ b/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt @@ -2,18 +2,22 @@ package mega.privacy.android.data.preferences.base +import android.content.Context import androidx.datastore.core.DataMigration import androidx.datastore.core.DataStore import androidx.datastore.core.DataStoreFactory import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.preferencesDataStoreFile import androidx.security.crypto.EncryptedFile +import androidx.security.crypto.MasterKey import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import timber.log.Timber /** * Creates Preferences DataStore instance stored in [EncryptedFile]. @@ -33,20 +37,38 @@ import kotlinx.coroutines.sync.withLock * @see PreferenceDataStoreFactory.create */ fun PreferenceDataStoreFactory.createEncrypted( + context: Context, corruptionHandler: ReplaceFileCorruptionHandler? = null, migrations: List> = listOf(), scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), - produceFile: () -> EncryptedFile, + masterKey: MasterKey, + fileName: String, ): DataStore { - val delegate = DataStoreFactory.createEncrypted( - serializer = PreferencesSerializer, - corruptionHandler = corruptionHandler, - migrations = migrations, - scope = scope, - produceFile = produceFile, - ) - - return PreferenceDataStore(delegate) + return try { + val encryptedFile = EncryptedFile.Builder( + context, + context.preferencesDataStoreFile(fileName), + masterKey, + EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB + ).build() + val delegate = DataStoreFactory.createEncrypted( + serializer = PreferencesSerializer, + corruptionHandler = corruptionHandler, + migrations = migrations, + scope = scope, + produceFile = { encryptedFile }, + ) + PreferenceDataStore(delegate) + } catch (e: Exception) { + // rollback to unencrypted DataStore if failed to create EncryptedFile + // https://console.firebase.google.com/u/1/project/megapoc-25443/crashlytics/app/android:mega.privacy.android.app/issues/8a1e160bcab8e85c2ecc3334d19a75ea + Timber.e(e, "Failed to create EncryptedFile for $fileName") + create( + corruptionHandler = corruptionHandler, + scope = scope, + produceFile = { context.preferencesDataStoreFile(fileName) } + ) + } } internal class PreferenceDataStore(private val delegate: DataStore) : From 64ad9267b3377f0953767d4580f70a5f5d7853ab Mon Sep 17 00:00:00 2001 From: Joe Ji Date: Tue, 28 May 2024 14:35:00 +1200 Subject: [PATCH 135/261] update string release/v13.2 --- app/src/main/res/values-ar/strings.xml | 7 ++ app/src/main/res/values-de/strings.xml | 29 +++++--- app/src/main/res/values-es/strings.xml | 7 ++ app/src/main/res/values-fr/strings.xml | 14 +++- app/src/main/res/values-in/strings.xml | 7 ++ app/src/main/res/values-it/strings.xml | 7 ++ app/src/main/res/values-ja/strings.xml | 6 ++ app/src/main/res/values-ko/strings.xml | 8 +- app/src/main/res/values-nl/strings.xml | 11 ++- app/src/main/res/values-pl/strings.xml | 9 +++ app/src/main/res/values-pt/strings.xml | 8 ++ app/src/main/res/values-ro/strings.xml | 12 ++- app/src/main/res/values-ru/strings.xml | 9 +++ app/src/main/res/values-th/strings.xml | 10 ++- app/src/main/res/values-vi/strings.xml | 6 ++ app/src/main/res/values-zh-rCN/strings.xml | 6 ++ app/src/main/res/values-zh-rTW/strings.xml | 10 ++- .../strings_device_center_feature.xml | 8 +- .../strings_device_center_feature.xml | 6 +- .../src/main/res/values-ar/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-de/strings_shared.xml | 74 ++++++++++++++----- .../src/main/res/values-es/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-fr/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-in/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-it/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-ja/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-ko/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-pl/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-pt/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-ro/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-ru/strings_shared.xml | 40 ++++++++++ .../src/main/res/values-th/strings_shared.xml | 58 ++++++++++++--- .../src/main/res/values-vi/strings_shared.xml | 40 ++++++++++ .../src/main/res/values/strings_shared.xml | 42 ++++++++++- 34 files changed, 777 insertions(+), 57 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 666b648c4c..d3ab458d69 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6321,4 +6321,11 @@ You and %1$d other raised your hands You and %1$d others raised your hands + + %1$s raised their hand + + + %1$s and %2$d other raised their hands + %1$s and %2$d others raised their hands + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5c39b28aec..cda3d610cb 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -123,7 +123,7 @@ Nicht nochmal anzeigen - Are you sure you want to cancel the current login process? + Möchten Sie den aktuellen Loginvorgang wirklich abbrechen? Anmelden @@ -1027,7 +1027,7 @@ [A]Ausloggen[/A], um zu einem anderen MEGA-Account zu wechseln - Are you sure you want to log out of the current account? + Möchten Sie sich wirklich aus dem aktuellen Account ausloggen? Diese Nachricht wurde von %1$s gelöscht @@ -5201,7 +5201,7 @@ Upload-Pause wegen fehlender Internetverbindung - Upload paused as battery is below %1$d%% + Upload pausiert, da Akkuladestand unter %1$d %% Kamera-Uploads funktionieren nicht mehr. Um das Problem zu lösen, versuchen Sie, die Kamera-Uploads wieder zu aktivieren. Wenn das Problem weiterhin besteht, wenden Sie sich an den Support. @@ -5363,22 +5363,29 @@ Mehr - Raise hand + Hand heben - Lower hand + Hand senken - Put call on hold + Anruf halten - Swap calls + Anruf wechseln Gespräch fortsetzen - New feature: Raise hand + Neue Funktion: Hand heben - You raised your hand + Sie haben die Hand gehoben - You and %1$d other raised your hands - You and %1$d others raised your hands + Sie und %1$d weitere Person haben die Hand gehoben + Sie und %1$d weitere Personen haben die Hand gehoben + + + %1$s hat die Hand gehoben + + + %1$s und %2$d weitere Person haben die Hand gehoben + %1$s und %2$d weitere Personen haben die Hand gehoben \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 80ce9ed92f..91f9ccfa82 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5618,4 +5618,11 @@ Tú y %1$d personas habéis levantado la mano Tú y %1$d personas habéis levantado la mano + + %1$s raised their hand + + + %1$s and %2$d other raised their hands + %1$s and %2$d others raised their hands + \ 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 5f578ad992..261956b1f8 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5614,8 +5614,16 @@ Vous avez levé la main - Vous et %1$d autre ont levé la main - Vous et %1$d autres ont levé la main - Vous et %1$d autres ont levé la main + Vous et %1$d autre personne ont levé la main + Vous et %1$d autres personnes ont levé la main + Vous et %1$d autres personnes ont levé la main + + + %1$s a levé la main + + + %1$s et %2$d autre personne ont levé la main + %1$s et %2$d autres personnes ont levé la main + %1$s et %2$d autres personnes ont levé la main \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 4cc0b2fcb4..f58ee1ad64 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -5144,4 +5144,11 @@ Anda dan %1$d orang lain mengangkat tangan + + %1$s raised their hand + + + %1$s and %2$d other raised their hands + %1$s and %2$d others raised their hands + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 16bb29ec25..9e7eb9c5a8 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5617,4 +5617,11 @@ You and %1$d other raised your hands You and %1$d others raised your hands + + %1$s raised their hand + + + %1$s and %2$d other raised their hands + %1$s and %2$d others raised their hands + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a1c7cc69bb..486f345e44 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5144,4 +5144,10 @@ あなたとその他%1$d人が挙手しました + + %1$s人が挙手しました + + + %1$sさんとその他%2$d人が挙手しました + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 83a617a0f8..8192accd8d 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -3013,7 +3013,7 @@ 이름 변경 - Change profile image + 프로필 이미지 변경 전화번호 추가 @@ -5145,4 +5145,10 @@ You and %1$d other raised your hands You and %1$d others raised your hands + + %1$s 님이 손을 들었습니다 + + + %1$s 님 외 %2$d명이 손을 들었습니다 + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index c99cce807b..478272f28b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -123,7 +123,7 @@ Laat niet opnieuw zien - Are you sure you want to cancel the current login process? + Weet u zeker dat u het huidige inlogproces wilt annuleren? Log in @@ -1027,7 +1027,7 @@ [A]Uitloggen [/A] om MEGA accounts te switchen - Are you sure you want to log out of the current account? + Weet u zeker dat u wilt uitloggen bij het huidige account? Dit bericht werd verwijderd door %1$s @@ -5381,4 +5381,11 @@ U en %1$d andere stak en de handen op U en %1$d anderen staken de handen op + + %1$s heeft de hand opgestoken + + + %1$s en %2$d anderen staken hun hand op + %1$s en %2$d anderen staken hun hand op + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b6b3f1b12e..8fcce9c712 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5855,4 +5855,13 @@ Ty i %1$d innych podnieśli ręce Ty i %1$d innych podnieśli ręce + + %1$s podniosły rękę + + + %1$s i %2$d inni podniosili ręce + %1$s i %2$d inni podniosili ręce + %1$s i %2$d inni podniosili ręce + %1$s i %2$d inni podniosili ręce + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index e817d44cfd..886c6f5b84 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5618,4 +5618,12 @@ Você e mais %1$d de pessoas levantaram a mão Você e mais %1$d pessoas levantaram a mão + + %1$s levantou a mão + + + %1$s e mais %2$d pessoa levantaram a mão + %1$s e mais %2$d de pessoas levantaram a mão + %1$s e mais %2$d pessoas levantaram a mão + \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index bb94e462ad..bb69370fd2 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -2501,9 +2501,9 @@ Creează-ți rețeaua - Adaugă contacte, creează o rețea, colaborează și efectuează apeluri vocale și video fără să părăsești MEGA + Adăugați contacte, creați o rețea, colaborați și efectuați apeluri vocale și video fără a părăsi MEGA. - Fotografiile tale în cloud + Fotografiile dvs. în cloud Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. @@ -5618,4 +5618,12 @@ Dvs. și alte %1$d persoane ați ridicat mâna Dvs. și alte %1$d de persoane ați ridicat mâna + + %1$s a ridicat mâna + + + %1$s și încă %2$d persoană au ridicat mâna + %1$s și alte %2$d persoane au ridicat mâna + %1$s și alte %2$d de persoane au ridicat mâna + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4db3065aff..495b7c0edf 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5855,4 +5855,13 @@ Вы и ещё %1$d подняли руки Вы и ещё %1$d подняли руки + + Пользователь %1$s поднял руку + + + %1$s и ещё %2$d подняли руки + %1$s и ещё %2$d подняли руки + %1$s и ещё %2$d подняли руки + %1$s и ещё %2$d подняли руки + \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index d66ec638bc..23dff02880 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -121,7 +121,7 @@ ไม่ต้องแสดงในครั้งต่อไป - Are you sure you want to cancel the current login process? + คุณแน่ใจหรือไม่ว่าต้องการยกเลิกการเข้าสู่ระบบปัจจุบัน เข้าสู่ระบบ @@ -1011,7 +1011,7 @@ [A]ออกจากระบบ[/A]เพื่อใช้ MEGA กับบัญชีอื่น - Are you sure you want to log out of the current account? + คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบบัญชีปัจจุบัน ข้อความนี้ถูกลบโดย %1$s @@ -5144,4 +5144,10 @@ คุณและคนอื่น ๆ อีก %1$d คนได้ยกมือ + + %1$s ได้ยกมือ + + + %1$s และคนอื่น ๆ อีก %2$d คนได้ยกมือ + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 76148293cf..557cddbc7a 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -5144,4 +5144,10 @@ Bạn và %1$d người khác đang giơ tay + + %1$s đang giơ tay lên + + + %1$s và %2$d người khác đang giơ tay + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 7dbdfd47d7..bef1fcdd07 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5144,4 +5144,10 @@ 您和其他%1$d个人举起了手 + + %1$s举起手 + + + %1$s和其它%2$d个人举起手 + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5c084551a5..c3e5181371 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -121,7 +121,7 @@ 請別再顯示 - Are you sure you want to cancel the current login process? + 您確定您要取消目前的登入嗎? 登入 @@ -1011,7 +1011,7 @@ [A]登出[/A]以切換MEGA帳戶 - Are you sure you want to log out of the current account? + 您確定要登出目前帳戶嗎? 此訊息已被%1$s刪除 @@ -5144,4 +5144,10 @@ 您和其他%1$d個人舉起手 + + %1$s舉起手 + + + %1$s和其他%2$d個人舉起手 + \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml index 5394cf883c..0d29bc93f0 100644 --- a/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-de/strings_device_center_feature.xml @@ -57,7 +57,7 @@ Im Cloud Drive anzeigen - No sync error + Keine Synchronisierungsfehler MEGA kann diesen Ordner nicht synchronisieren oder sichern, da das Dateisystem Ihres Geräts nicht unterstützt wird @@ -93,7 +93,7 @@ Die Synchronisierung oder das Backup wurde angehalten, da Sie sich anscheinend aus der Desktop-App ausgeloggt haben. Loggen Sie sich in die Desktop-App wieder ein und aktivieren Sie die Synchronisierung bzw. das Backup erneut. - N/A + Nicht verfügbar Ordner auf externem Laufwerk nicht gefunden. @@ -115,7 +115,7 @@ Die FSID eines Synchronisierungs-Stammordners konnte nicht abgerufen werden. - Unable to open state cache database + Statuscache-Datenbank kann nicht geöffnet werden Nicht genügend Speicherplatz für den Download. @@ -123,7 +123,7 @@ Unbekannter Fehler. - Something went wrong. + Ein Fehler ist aufgetreten. Der Ordner kann nicht synchronisiert oder gesichert werden, da sich der MEGA-Ordner im Papierkorb befindet diff --git a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml index 0d658a74c8..e841cdd43d 100644 --- a/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-th/strings_device_center_feature.xml @@ -57,7 +57,7 @@ แสดงในคลาวด์ไดร์ฟ - No sync error + ไม่มีข้อผิดพลาดในการซิงค์ MEGA ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์นี้ได้ เนื่องจากไม่สนับสนุนระบบไฟล์ในอุปกรณ์ของคุณ @@ -115,7 +115,7 @@ ไม่สามารถอ่านตำแหน่งที่ตั้งการซิงค์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ - Unable to open state cache database + ไม่สามารถเปิดฐานข้อมูลแคชสถานะได้ มีพื้นที่ไม่เพียงพอที่จะดาวน์โหลด @@ -123,7 +123,7 @@ ข้อผิดพลาดที่ไม่รู้จัก - Something went wrong. + เกิดข้อผิดพลาดบางประการ ไม่สามารถซิงค์หรือสำรองข้อมูลโฟลเดอร์ได้ เนื่องจากโฟลเดอร์ MEGA อยู่ในถังขยะ diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 772ddfd635..e423d695f4 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -342,4 +342,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + No solved issues + + انت تحتفظ بالمفاتيح + + محادثة مشفرة + + انشئ شبكتك + + تطبيق الصور الخاص بك على السحابة + + اجتماع ميغا MEGA + + نحن موجودون لتوفير الأمان، ملفاتك بأمان أكثر معنا محمية خلف آلية تشفير متينة بحيث تكون أنت فقط القادر على الولوج الى ملفاتك. + + محادثة مشفرة بالكامل مع مكالمات صوتية ومكالمات فيديو ومراسلات جماعية و مشاركة ملفات بشكل متكامل مع سواقتك السحابية. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + ترفيع صور الكاميرا هو ميزة أساسية لأي جهاز محمول و نحن نقدم لك ذلك. أنشأ حسابك الآن. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 08a6a37f55..5ee374e46f 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -91,7 +91,7 @@ Nie mehr Datenverlust - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Mit Rewind können Sie Ordner auf einen früheren Stand (bis zu 180 Tage) zurücksetzen, sodass Ihre Daten vor Missgeschicken und Manipulationen geschützt sind. MEGA VPN @@ -259,7 +259,7 @@ Nur dieses Mal - Always download here + Immer hierher herunterladen Immer nach Zielort fragen @@ -267,11 +267,11 @@ TB - Starting from %1$s %2$s, find the perfect fit for your storage needs. + Finden Sie die perfekte Lösung für Ihren Speicherbedarf – ab %1$s %2$s. Unzureichender Speicherplatz - The size of this folder will take your MEGA account over its storage limit. To be able to sync it, you will need to either free up some space or upgrade your MEGA account. + Aufgrund der Größe dieses Ordners würde das Speicherlimit Ihres MEGA-Accounts überschritten. Um ihn synchronisieren zu können, müssen Sie entweder Speicherplatz freigeben oder Ihren MEGA-Account upgraden. Pakete ansehen @@ -279,17 +279,17 @@ Wenn Sie sich bei der E-Mail-Adresse vertippt haben, korrigieren Sie diese und tippen Sie auf [A]Erneut senden[/A]. - Syncing paused, your MEGA plan has run out of storage + Synchronisierung pausiert – der Speicherplatz Ihres MEGA-Pakets ist erschöpft Upgrade - Upload paused, phone is not charging + Upload pausiert – das Telefon wird nicht geladen - No syncs set up + Keine Synchronisierungen eingerichtet Account deaktiviert - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Ihr Pro-Flexi-Account wurde aufgrund eines Zahlungsproblems deaktiviert oder Sie haben Ihr Abonnement gekündigt. Sie können auf die Daten in Ihrem Account nicht zugreifen. \nUm eine Zahlung vorzunehmen und Ihr Abonnement erneut zu aktivieren, melden Sie sich in einem Browser bei MEGA an. Starter @@ -297,13 +297,13 @@ Essential - Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + Die Uploads werden pausiert, bis Sie Ihr Gerät an ein Ladegerät anschließen. Die Uploads bleiben auch dann pausiert, wenn der Ladestand weniger als 20 % beträgt. - No syncs set up + Keine Synchronisierungen eingerichtet - Sync a local folder on your device with a folder on MEGA. + Synchronisieren Sie einen lokalen Ordner auf Ihrem Gerät mit einem Ordner auf MEGA. - Add new sync + Neue Synchronisierung hinzufügen Gelöste Probleme @@ -313,13 +313,53 @@ Beschreibung hinzufügen - Description added + Beschreibung hinzugefügt - Description updated + Beschreibung aktualisiert - Plus access to these great benefits: + Weitere großartige Vorteile: - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + • MEGA VPN \n• Keine Anruf- und Meeting-Beschränkungen \n• Automatische Synchronisierung der Ordner auf Ihrem Mobilgerät \n• Keine Werbung - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + • MEGA VPN \n• Keine Anruf- und Meeting-Beschränkungen \n• Automatische Synchronisierung der Ordner auf Ihrem Mobilgerät + + Keine gelösten Probleme + + Sie sind der alleinige Inhaber Ihrer Schlüssel + + Verschlüsselte Kommunikation + + Kontaktnetzwerk erstellen + + Ihre Fotos in der Cloud + + MEGA-Meeting + + Die Sicherheit Ihrer Daten ist unsere Existenzgrundlage. Dank Ende-zu-Ende-Verschlüsselung kontrollieren Sie alleine, wer Zugang zu ihnen erhält. + + Vollverschlüsselter Textchat, Audio- und Videoanrufe, Gruppengespräche und Integration mit Ihrem Cloud Drive. + + Fügen Sie Kontakte hinzu, tauschen Sie Dokumente aus und führen Sie Audio- und Video-Gespräche, ohne MEGA zu verlassen. + + Kamera-Uploads ist essentiell für alle Mobilgeräte, und MEGA unterstützt dies selbstverständlich. Erstellen Sie jetzt Ihren Account. + + Videomeeting mit Zero-Knowledge-Verschlüsselung. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 8d90980578..7cc2c6773f 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -330,4 +330,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + No solved issues + + Tú tienes las claves + + Chat cifrado + + Crea tu propia red + + Tus fotos en la nube + + Reuniones en MEGA + + La seguridad es la razón por la que existimos. Tus archivos están seguros con nosotros gracias a una máquina de cifrado bien engrasada que permite que solo tú puedas acceder a tus archivos. + + Chat totalmente cifrado con llamadas y videollamadas, chat de grupo y capacidad de compartir archivos con tu Cloud Drive. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + La función Subidas de la cámara es esencial para cualquier dispositivo móvil y nosotros la tenemos. Crea tu cuenta ahora. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 181e6a7694..7dc987d450 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -330,4 +330,44 @@ • RPV MEGA VPN\n• Réunions et appels illimités\n• Synchronisation automatiquement des dossiers de votre appareil mobile\n• Sans publicités • RPV MEGA VPN\n• Réunions et appels illimités\n• Synchronisation automatiquement des dossiers de votre appareil mobile + + Aucun problème résolu + + Vous détenez les clés + + Dialogue en ligne chiffré + + Créez votre réseau + + Vos photos dans le nuage + + Réunion MEGA + + La sécurité est notre raison d’être. Avec nous, vos fichiers sont en sécurité, protégés par un système de chiffrement efficace dans lequel vous seul avez accès à vos fichiers. + + Le dialogue en ligne est entièrement chiffré et offre des appels vocaux et vidéo, une messagerie de groupe et le partage de fichiers, tous intégrés à votre disque nuagique. + + Ajoutez des contacts, créez un réseau, collaborez et faites des appels vocaux ou vidéo sans jamais quitter MEGA. + + Le téléversement de l’appareil photo est une fonction essentielle de tout appareil mobile et nous nous en occupons pour vous. Créez votre compte maintenant. + + Réunion vidéo chiffrée sans divulgation de connaissance. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index ce79ad04e3..46b5a6af0c 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -318,4 +318,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + No solved issues + + Anda memegang kunci + + Obrolan terenkripsi + + Buat jaringan anda + + Foto anda di cloud + + MEGA pertemuan + + Keamanan adalah alasan kami ada, file anda aman bersama kami di belakang mesin enkripsi yang diminyaki di mana hanya anda yang dapat mengakses file anda. + + Obrolan yang sepenuhnya terenkripsi dengan panggilan suara dan video, perpesanan grup, dan integrasi berbagi file dengan Cloud Drive anda. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + Unggahan camera adalah fitur penting untuk perangkat seluler apa pun dan kami telah melindungi anda. Buat akun anda sekarang. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 5db1a4a219..bfc1a60de6 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -330,4 +330,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + Nessun problema risolto + + Tu hai le chiavi + + Chat criptata + + Crea il tuo network + + Le tue foto nel cloud + + MEGA meeting + + La sicurezza è il motivo per cui esistiamo, i tuoi file sono al sicuro con noi dietro ad una macchina di criptazione ben oliata dove solo tu puoi accedere ad i tuoi file. + + Chat interamente criptate con chiamate audio e video, messaggi di gruppo e condivisione di file integrata al tuo Cloud Drive. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + I Caricamenti da fotocamera sono una feature essenziale per qualsiasi dispositivo mobile e possiamo farlo per te. Crea il tuo account adesso. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 8cfda47d47..35e7b8538f 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -314,4 +314,44 @@ • MEGA VPN \n• 無制限の通話とミーティング \n• モバイルデバイス上のフォルダを自動的に同期 \n• 広告なし • MEGA VPN \n• 無制限の通話とミーティング \n• モバイルデバイス上のフォルダを自動的に同期 + + 解決済みの問題はありません + + あなたがキーを持っています + + 暗号化されたチャット + + ネットワークの作成 + + クラウド内のあなたの写真 + + MEGAミーティング + + セキュリティこそが私たちの存在理由です。あなたのファイルは、非常に効果的な暗号化マシンの裏側にあり、安全です。そこで、あなたのファイルにアクセスできるのは、あなただけです。 + + 音声&ビデオ通話、グループメッセージング、クラウドドライブとのファイル共有統合による完全に暗号化されたチャット。 + + 連絡先の追加、ネットワークの作成、コラボレーション、MEGAを一切離れずに音声通話とビデオ通話を行えます。 + + カメラアップロードは、あらゆるモバイル端末にとって不可欠な機能で、あなたにもご利用いただけます。今すぐアカウントを作成してください。 + + ゼロ知識暗号化によるビデオミーティングが可能です。 + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 18cd7b0da0..1927716a1c 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -314,4 +314,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + 해결된 문제 없음 + + 당신이 열쇠를 갖습니다 + + 암호화된 대화 + + 네트워크 생성 + + 클라우드 속 당신의 사진 + + MEGA meeting + + 보안은 우리의 존재 이유이며, 당신의 파일들은 당신만이 접근 할수 있도록 우리 서버에 마치 잘 관리된 암호화 기계 뒤에 있는 것처럼 매우 안전합니다. + + 완전히 암호화된 대화와 음성과 영상 통화, 그룹 대화 그리고 클라우드 드라이브와 통합된 파일 공유. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + 카메라 업로드는 어떠한 모바일 기기에서든 필요한 기능이며 우리는 이 기능이 준비되어 있습니다. 지금 계정을 만드세요. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index b9d1f8d233..65cfcac503 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -338,4 +338,44 @@ •   MEGA   VPN \n•   Nieograniczone połączenia i spotkania \n•   Automatyczna synchronizacja katalogów na urządzeniu mobilnym \n•   Brak reklam •   MEGA   VPN \n•   Nieograniczone połączenia i spotkania \n•   Automatyczna synchronizacja katalogów na urządzeniu mobilnym + + Brak rozwiązanych problemów + + Ty przechowujesz klucze + + Zaszyfrowany czat + + Stwórz swoją sieć + + Twoje zdjęcia w chmurze + + MEGA spotkanie + + Bezpieczeństwo, dlatego istniejemy, twoje pliki są bezpieczne u nas za dobrze naoliwioną maszyną szyfrującą, gdzie tylko ty masz dostęp do twoich plików. + + W pełni zaszyfrowany czat z połączeniami głosowymi i wideo, przesyłanie wiadomości grupowych i integracja udostępniania plików z dyskiem Cloud Drive. + + Dodawaj kontakty, twórz sieć, współpracuj i wykonuj połączenia głosowe i wideo bez opuszczania MEGA. + + Przesyłanie z kamery to podstawowa funkcja każdego urządzenia mobilnego, a my jesteśmy objęci. Utwórz teraz swoje konto. + + Zaszyfrowane spotkanie wideo o zerowej wiedzy. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index ea1857b264..4cba1c4e66 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -330,4 +330,44 @@ • MEGA VPN \n•   Chamadas e reuniões irrestritas \n•   Sincronização automática das pastas no seu dispositivo móvel \n•   Sem anúncios • MEGA VPN \n•   Chamadas e reuniões irrestritas \n•   Sincronização automática das pastas no seu dispositivo móvel + + Não há problemas solucionados + + Você tem a chave + + Chat criptografado + + Crie a sua rede + + As suas fotos na nuvem + + Reunião MEGA + + A segurança é a razão da nossa existência. Os seus arquivos estão protegidos por uma máquina de criptografia bem engrenada, na qual somente você pode acessá-los. + + Chat totalmente criptografado com chamadas de voz e vídeo, mensagens de grupo e compartilhamento de dados integrado com a sua Nuvem de arquivos. + + Adicione contatos, crie uma rede, colabore e faça chamadas de voz e vídeo sem sair do MEGA. + + Sabemos que os Uploads da câmera são um recurso essencial para qualquer dispositivo móvel. Crie a sua conta agora. + + Videoconferência criptografada de conhecimento zero. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 2e7d16d85c..9d3979a196 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -330,4 +330,44 @@ • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil\n• Fără reclame • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil + + Nicio problemă rezolvată + + Tu deții cheile + + Chat criptat + + Creează-ți rețeaua + + Fotografiile tale în cloud + + Întâlnire MEGA + + Securitatea este motivul pentru care existăm, fișierele tale sunt în siguranță în spatele unei mașini de criptare bine unsă, loc în care numai tu poți accesa fișierele. + + Chat complet criptat cu apeluri vocale și video, mesagerie de grup și integrare pentru partajarea de fișiere din unitatea cloud. + + Adăugați contacte, creați o rețea, colaborați și efectuați apeluri vocale și video fără a părăsi MEGA. + + Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. + + Întâlnire video criptată cu zero cunoștințe. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index b9a6ae4d14..e59cf5b57b 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -338,4 +338,44 @@ • MEGA VPN \n• Неограниченные звонки и встречи \n• Автоматическая синхронизация папок на мобильном устройстве \n• Без рекламы • MEGA VPN \n• Неограниченные звонки и встречи \n• Автоматическая синхронизация папок на мобильном устройстве + + Нет решённых проблем + + Ключи хранятся у вас + + Зашифрованный чат + + Создайте свою сеть + + Ваши фотографии в облаке + + MEGA-встреча + + Безопасность — это то, для чего существуем. Ваши файлы в безопасности за нашей хорошо смазанной шифровальной машиной, где только вы можете получить доступ к ним. + + Полностью зашифрованный чат с голосовыми и видеозвонками, групповой обмен сообщениями и интеграция файлов с вашим облачным диском. + + Добавляйте контакты, создавайте сообщество, сотрудничайте и совершайте голосовые и видеозвонки, не покидая MEGA + + Загрузки из камеры — важная функция для любого мобильного устройства, и мы о ней позаботились. Зарегистрируйтесь сейчас. + + Зашифрованная с нулевым разглашением видеовстреча. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 5ff3793c97..71d8e2568e 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -91,7 +91,7 @@ ไม่มีพลาดทุกข้อมูลสำคัญของคุณ - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + ย้อนกลับโฟลเดอร์ไปยังวันที่ใดก็ได้ในช่วง 180 วันที่ผ่านมา ช่วยให้ข้อมูลของคุณปลอดภัยจากเหตุไม่คาดคิดและการแก้ไขโดยไม่ได้รับอนุญาต MEGA VPN @@ -279,9 +279,9 @@ ยังไม่ได้ตั้งค่าการซิงค์ - บัญชีถูกปิดใช้งาน + บัญชีถูกปิดใช้งานแล้ว - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + บัญชี Pro Flexi ของคุณถูกปิดใช้งาน เนื่องจากการชำระเงินไม่สำเร็จหรือคุณได้ยกเลิกการสมัครใช้งานของคุณเอง คุณจะไม่สามารถเข้าถึงข้อมูลของคุณได้\nกรุณาเข้าสู่ระบบ MEGA ผ่านเบราว์เซอร์เพื่อดำเนินการชำระเงินและเปิดใช้การสมัครใช้งานของคุณอีกครั้ง Starter @@ -289,13 +289,13 @@ Essential - Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + การอัปโหลดจะหยุดชั่วคราวจนกว่าคุณจะเริ่มชาร์จอุปกรณ์ การอัปโหลดจะถูกหยุดไว้ชั่วคราวต่อไปแม้ว่าแบตเตอรี่ของคุณจะต่ำกว่า 20% ก็ตาม ยังไม่ได้ตั้งค่าการซิงค์ - Sync a local folder on your device with a folder on MEGA. + ซิงค์โฟลเดอร์บนอุปกรณ์ของคุณกับโฟลเดอร์บน MEGA - Add new sync + เพิ่มการซิงค์ใหม่ แก้ไขปัญหาแล้ว @@ -309,9 +309,49 @@ อัปเดตคำอธิบายแล้ว - Plus access to these great benefits: + นอกจากนี้ยังมีสิทธิพิเศษอื่น ๆ เพิ่มเติม เช่น: - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + • MEGA VPN \n• โทรและประชุมได้ไม่จำกัด\n• ซิงค์โฟลเดอร์บนอุปกรณ์มือถือของคุณโดยอัตโนมัติ \n• ไม่มีโฆษณา - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + • MEGA VPN \n• โทรและประชุมได้ไม่จำกัด\n• ซิงค์โฟลเดอร์บนอุปกรณ์มือถือของคุณโดยอัตโนมัติ + + ปัญหาทั้งหมดได้รับการแก้ไขแล้ว + + คุณคือผู้ถือกุญแจ + + เข้ารหัสแชท + + สร้างเครือข่ายของคุณ + + รูปภาพของคุณในคลาวด์ + + MEGA meeting + + ความปลอดภัยคือเหตุผลหลักที่เราดำเนินการอยู่ ไฟล์ของคุณจะมีความปลอดภัยมากยิ่งขึ้น เพราะใช้เครื่องมือเข้ารหัสที่ป้องกันไฟล์ของคุณ ซึ่งมีเพียงคุณเท่านั้นที่สามารถเข้าถึงไฟล์ได้ + + แชทที่มีการเข้ารหัสอย่างเต็มที่ไม่ว่าจะเป็นการโทรด้วยเสียงและสนทนาทางวิดีโอ การส่งข้อความแบบกลุ่มและบูรณาการไฟล์ร่วมกันกับคลาวด์ไดรฟ์ของคุณ + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + การอัปโหลดจากกล้อง เป็นฟีเจอร์สำคัญสำหรับโทรศัพท์มือถือทุกเครื่องและเราได้ให้ความสำคัญกับคุณ สร้างบัญชีของคุณเลย + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 479da39086..eb8d391815 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -314,4 +314,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + + No solved issues + + Chính bạn là người giữ chìa khóa + + Cuộc chát được mã hóa + + Tạo kết nối + + Hình Ảnh được gửi lên mây + + MEGA họp mặt + + Bảo mật là lý do chúng tôi tạo ra MEGA, các tệp tin của bạn được bảo vệ an toàn với chúng tôi với bộ máy mã hóa được hoạt động trơn tru, nơi chỉ bạn mới có thể truy cập các tệp tin của mình. + + Toàn bộ chát, tin nhắn, thoại hay video đều được mã hóa hoàn toàn và hoạt động với khả năng chia sẻ thông qua Ổ Mây. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + Đăng Tải Camêra là tính năng thiết yếu cho mọi thiết bị di động, và MEGA có cung cấp cho mọi người dùng. Tạo tài khoản ngay. + + Zero-knowledge encrypted video meeting. + + + + + + + + + + + + + + + + + + [A]New feature: Raise hand[/A] \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index a1b1c88b5b..35d8a8ca8c 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -322,4 +322,44 @@ • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device - \ No newline at end of file + + No solved issues + + You hold the keys + + Encrypted chat + + Create your network + + Your photos in the cloud + + MEGA meeting + + Security is why we exist, your files are safe with us behind a well oiled encryption machine where only you can access your files. + + Fully encrypted chat with voice and video calls, group messaging and file sharing integration with your Cloud Drive. + + Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + + Camera uploads is an essential feature for any mobile device and we have got you covered. Create your account now. + + Zero-knowledge encrypted video meeting. + + + @string/cloud_drive_tour_first_title + @string/cloud_drive_tour_second_title + @string/cloud_drive_tour_third_title + @string/cloud_drive_tour_fourth_title + @string/cloud_drive_tour_fifth_title + + + + @string/cloud_drive_tour_first_subtitle + @string/cloud_drive_tour_second_subtitle + @string/cloud_drive_tour_third_subtitle + @string/cloud_drive_tour_fourth_subtitle + @string/cloud_drive_tour_fifth_subtitle + + + [A]New feature: Raise hand[/A] + From a76ea674d549247dbf7b569dfe8c88fdb35e735a Mon Sep 17 00:00:00 2001 From: Yenel Date: Wed, 29 May 2024 13:57:11 +0200 Subject: [PATCH 136/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index ba6deee748..dae6968233 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -73,7 +73,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240527.031929" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 3fe8c3af574ea193a5f005ae417b62387b87f450 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 30 May 2024 07:08:42 +0700 Subject: [PATCH 137/261] AND-18895: Fix crash provide master key (cherry picked from commit 9765fe87b8e0f5ecc1ddb2d93ad539bac53d90bd) --- .../privacy/android/data/di/DataStoreModule.kt | 2 +- .../privacy/android/data/di/RoomDatabaseModule.kt | 15 ++++++++++----- .../base/EncryptedPreferenceDataStoreFactory.kt | 3 ++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt b/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt index 84e3a0a96c..56c0a947b1 100644 --- a/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/DataStoreModule.kt @@ -125,7 +125,7 @@ internal object DataStoreModule { @ApplicationContext context: Context, @IoDispatcher ioDispatcher: CoroutineDispatcher, migration: CredentialsPreferencesMigration, - masterKey: MasterKey, + masterKey: MasterKey?, ): DataStore { return PreferenceDataStoreFactory.createEncrypted( corruptionHandler = ReplaceFileCorruptionHandler( diff --git a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt index 2857ab65b6..ac2d71201b 100644 --- a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt @@ -155,9 +155,10 @@ internal object RoomDatabaseModule { @Singleton internal fun providePassphraseEncryptedFile( @ApplicationContext context: Context, - masterKey: MasterKey, + masterKey: MasterKey?, passphraseFile: File, ): EncryptedFile? { + masterKey ?: return null return runCatching { EncryptedFile.Builder( context, @@ -174,10 +175,14 @@ internal object RoomDatabaseModule { @Singleton internal fun provideMasterKey( @ApplicationContext context: Context, - ): MasterKey { - return MasterKey.Builder(context) - .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) - .build() + ): MasterKey? { + return runCatching { + MasterKey.Builder(context) + .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) + .build() + }.onFailure { + Timber.e(it, "Failed to create MasterKey") + }.getOrNull() } @Provides diff --git a/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt b/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt index e897713ea4..37179b1253 100644 --- a/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt +++ b/data/src/main/java/mega/privacy/android/data/preferences/base/EncryptedPreferenceDataStoreFactory.kt @@ -41,10 +41,11 @@ fun PreferenceDataStoreFactory.createEncrypted( corruptionHandler: ReplaceFileCorruptionHandler? = null, migrations: List> = listOf(), scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()), - masterKey: MasterKey, + masterKey: MasterKey?, fileName: String, ): DataStore { return try { + masterKey ?: throw IllegalArgumentException("Failed to create MasterKey") val encryptedFile = EncryptedFile.Builder( context, context.preferencesDataStoreFile(fileName), From 3aa41929166f4116c30ef8459dc46f72235afc7d Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Wed, 29 May 2024 18:16:47 +0600 Subject: [PATCH 138/261] MEET-3942: Fix AppRTCAudioManager initialisation exception --- .../globalmanagement/CallChangesObserver.kt | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/CallChangesObserver.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/CallChangesObserver.kt index 90bd0ff713..beb8b64bac 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/CallChangesObserver.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/CallChangesObserver.kt @@ -5,9 +5,11 @@ import android.content.Context import android.os.PowerManager import android.provider.Settings import com.jeremyliao.liveeventbus.LiveEventBus +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.components.ChatManagement import mega.privacy.android.app.constants.EventConstants @@ -25,6 +27,7 @@ import mega.privacy.android.domain.entity.meeting.ChatSessionStatus import mega.privacy.android.domain.entity.meeting.ChatSessionUpdatesResult import mega.privacy.android.domain.entity.meeting.EndCallReason import mega.privacy.android.domain.qualifier.ApplicationScope +import mega.privacy.android.domain.qualifier.MainImmediateDispatcher import mega.privacy.android.domain.usecase.chat.IsChatNotifiableUseCase import mega.privacy.android.domain.usecase.contact.GetMyUserHandleUseCase import mega.privacy.android.domain.usecase.meeting.GetCallHandleListUseCase @@ -60,6 +63,7 @@ class CallChangesObserver @Inject constructor( private val isChatNotifiableUseCase: IsChatNotifiableUseCase, private val getMyUserHandleUseCase: GetMyUserHandleUseCase, @ApplicationScope private val applicationScope: CoroutineScope, + @MainImmediateDispatcher private val mainImmediateDispatcher: CoroutineDispatcher, ) { private var wakeLock: PowerManager.WakeLock? = null private var openCallChatId: Long = -1 @@ -73,16 +77,18 @@ class CallChangesObserver @Inject constructor( .catch { e -> Timber.e(e, "Error listening call updates") } .collect { call -> runCatching { - val changes = call.changes.orEmpty() - when { - changes.contains(ChatCallChanges.Status) - -> onHandleCallStatusChange(call) - - changes.contains(ChatCallChanges.RingingStatus) - -> handleCallRinging(call) - - changes.contains(ChatCallChanges.CallComposition) - -> handleCallComposition(call) + withContext(mainImmediateDispatcher) { + val changes = call.changes.orEmpty() + when { + changes.contains(ChatCallChanges.Status) + -> onHandleCallStatusChange(call) + + changes.contains(ChatCallChanges.RingingStatus) + -> handleCallRinging(call) + + changes.contains(ChatCallChanges.CallComposition) + -> handleCallComposition(call) + } } }.onFailure { Timber.e(it, "Error handling call status change") @@ -451,7 +457,9 @@ class CallChangesObserver @Inject constructor( if (!chatRoom.isMeeting || !chatManagement.isOpeningMeetingLink(incomingCallChatId)) { Timber.d("It is necessary to check the number of current calls") - controlNumberOfCalls(listAllCalls, callStatus, incomingCallChatId) + withContext(mainImmediateDispatcher) { + controlNumberOfCalls(listAllCalls, callStatus, incomingCallChatId) + } } } @@ -469,4 +477,4 @@ class CallChangesObserver @Inject constructor( private fun shouldNotify(context: Context?) = Util.isAndroid10OrUpper() && !Settings.canDrawOverlays(context) -} \ No newline at end of file +} From 5b6f7de7522e27350a246c78e620f8e9d2150cfe Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Fri, 31 May 2024 16:20:36 +1200 Subject: [PATCH 139/261] AND-18904 Fix contact request bug (cherry picked from commit 97cd7d3d9e50c5f947bec06fff48ca9d50fa172e) b2331a07 AND-18904 Fix contact request bug 3838fed1 Fix tests --- .../android/app/contacts/requests/ContactRequestsFragment.kt | 5 +++-- .../app/contacts/requests/mapper/ContactRequestItemMapper.kt | 2 +- .../contacts/requests/mapper/ContactRequestItemMapperTest.kt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/contacts/requests/ContactRequestsFragment.kt b/app/src/main/java/mega/privacy/android/app/contacts/requests/ContactRequestsFragment.kt index b20db8ec70..d7bc029047 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/requests/ContactRequestsFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/requests/ContactRequestsFragment.kt @@ -14,6 +14,7 @@ import mega.privacy.android.app.R import mega.privacy.android.app.contacts.ContactsActivity import mega.privacy.android.app.contacts.requests.adapter.ContactRequestPageAdapter import mega.privacy.android.app.contacts.requests.adapter.ContactRequestPageAdapter.Tabs +import mega.privacy.android.app.data.extensions.observeOnce import mega.privacy.android.app.databinding.FragmentContactRequestsBinding import mega.privacy.android.app.utils.ColorUtils.setElevationWithColor import mega.privacy.android.app.utils.MenuUtils.setupSearchView @@ -60,8 +61,8 @@ class ContactRequestsFragment : Fragment() { } setViewPagerPosition(position) - viewModel.getDefaultPagerPosition(isOutgoing).observe(viewLifecycleOwner) { pagePosition -> - setViewPagerPosition(pagePosition) + viewModel.getDefaultPagerPosition(isOutgoing).observeOnce { pagePosition -> + pagePosition?.let { setViewPagerPosition(it) } } } } diff --git a/app/src/main/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapper.kt b/app/src/main/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapper.kt index 9cbaeb4b2d..761054e92e 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapper.kt @@ -48,7 +48,7 @@ internal class ContactRequestItemMapper( email = email, avatarUri = userImageUri, placeholder = placeholder, - createdTime = formatCreationTime(creationTime).toString(), + createdTime = formatCreationTime(creationTime * 1000).toString(), isOutgoing = isOutgoing, ) } diff --git a/app/src/test/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapperTest.kt b/app/src/test/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapperTest.kt index 3fd757a9ec..6ca8384267 100644 --- a/app/src/test/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapperTest.kt +++ b/app/src/test/java/mega/privacy/android/app/contacts/requests/mapper/ContactRequestItemMapperTest.kt @@ -125,7 +125,7 @@ class ContactRequestItemMapperTest { assertThat(actual?.handle).isEqualTo(handle) assertThat(actual?.avatarUri).isEqualTo(uri) assertThat(actual?.placeholder).isEqualTo(drawable) - assertThat(actual?.createdTime).isEqualTo(formatCreationTime(creationTime)) + assertThat(actual?.createdTime).isEqualTo(formatCreationTime(creationTime * 1000)) assertThat(actual?.isOutgoing).isEqualTo(isOutgoing) } From c2ede96f5cb5a24e7404a68946505d0a80f110e9 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Fri, 31 May 2024 17:25:11 +0600 Subject: [PATCH 140/261] MEET-3820: Fix Free plan warning for Guest Login --- .../activity/MeetingActivityViewModel.kt | 5 +- .../meeting/LeftMeetingViewModel.kt | 34 +-------- .../app/usecase/call/GetCallSoundsUseCase.kt | 74 +++++++++++-------- .../meeting/LeftMeetingViewModelTest.kt | 11 +-- 4 files changed, 49 insertions(+), 75 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt index 06031b1dfe..85faa034c9 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt @@ -118,6 +118,7 @@ import mega.privacy.android.domain.usecase.meeting.MonitorScheduledMeetingUpdate import mega.privacy.android.domain.usecase.meeting.MuteAllPeersUseCase import mega.privacy.android.domain.usecase.meeting.MutePeersUseCase import mega.privacy.android.domain.usecase.meeting.RingIndividualInACallUseCase +import mega.privacy.android.domain.usecase.meeting.StartVideoDeviceUseCase import mega.privacy.android.domain.usecase.network.IsConnectedToInternetUseCase import mega.privacy.android.domain.usecase.network.MonitorConnectivityUseCase import nz.mega.sdk.MegaApiJava @@ -931,9 +932,7 @@ class MeetingActivityViewModel @Inject constructor( ChatCallStatus.TerminatingUserParticipation, ChatCallStatus.GenericNotification -> { Timber.d("Chat call termCode: ${call.termCode}") - if (call.termCode == ChatCallTermCodeType.CallUsersLimit || call.termCode == ChatCallTermCodeType.TooManyParticipants - && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled - ) { + if (call.termCode == ChatCallTermCodeType.CallUsersLimit) { _state.update { state -> state.copy( callEndedDueToFreePlanLimits = true diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModel.kt index ba7dca59d0..6837803da8 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModel.kt @@ -2,28 +2,21 @@ package mega.privacy.android.app.presentation.meeting import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch -import mega.privacy.android.app.featuretoggle.ApiFeatures import mega.privacy.android.app.meeting.activity.MeetingActivity import mega.privacy.android.app.presentation.meeting.model.LeftMeetingState -import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase -import timber.log.Timber import javax.inject.Inject /** * LeftMeeting view model. * - * @property getFeatureFlagValueUseCase Use case for getting the value of a feature flag. * @property state Current view state as [LeftMeetingViewModel] */ @HiltViewModel class LeftMeetingViewModel @Inject constructor( - private val getFeatureFlagValueUseCase: GetFeatureFlagValueUseCase, savedStateHandle: SavedStateHandle, ) : ViewModel() { @@ -33,30 +26,7 @@ class LeftMeetingViewModel @Inject constructor( ?: false ) ) - val state: StateFlow = _state - - init { - getApiFeatureFlag() - } - - /** - * Get call unlimited pro plan api feature flag - */ - private fun getApiFeatureFlag() { - viewModelScope.launch { - runCatching { - getFeatureFlagValueUseCase(ApiFeatures.CallUnlimitedProPlan) - }.onFailure { exception -> - Timber.e(exception) - }.onSuccess { flag -> - _state.update { state -> - state.copy( - isCallUnlimitedProPlanFeatureFlagEnabled = flag, - ) - } - } - } - } + val state = _state.asStateFlow() /** * Consume show free plan participants limit dialog event diff --git a/app/src/main/java/mega/privacy/android/app/usecase/call/GetCallSoundsUseCase.kt b/app/src/main/java/mega/privacy/android/app/usecase/call/GetCallSoundsUseCase.kt index 2296eac42a..0fcee85ae0 100644 --- a/app/src/main/java/mega/privacy/android/app/usecase/call/GetCallSoundsUseCase.kt +++ b/app/src/main/java/mega/privacy/android/app/usecase/call/GetCallSoundsUseCase.kt @@ -11,11 +11,13 @@ import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.addTo import io.reactivex.rxjava3.kotlin.subscribeBy +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import kotlinx.coroutines.rx3.rxFlowable +import kotlinx.coroutines.withContext import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.components.CustomCountDownTimer import mega.privacy.android.app.constants.EventConstants @@ -31,6 +33,7 @@ import mega.privacy.android.domain.entity.CallsSoundNotifications import mega.privacy.android.domain.entity.meeting.ChatCallChanges import mega.privacy.android.domain.entity.meeting.ChatCallStatus import mega.privacy.android.domain.qualifier.ApplicationScope +import mega.privacy.android.domain.qualifier.MainImmediateDispatcher import mega.privacy.android.domain.usecase.chat.MonitorCallsReconnectingStatusUseCase import mega.privacy.android.domain.usecase.meeting.HangChatCallUseCase import mega.privacy.android.domain.usecase.meeting.MonitorChatCallUpdatesUseCase @@ -57,6 +60,7 @@ class GetCallSoundsUseCase @Inject constructor( private val monitorChatCallUpdatesUseCase: MonitorChatCallUpdatesUseCase, private val hangChatCallUseCase: HangChatCallUseCase, @ApplicationScope private val sharingScope: CoroutineScope, + @MainImmediateDispatcher private val mainImmediateDispatcher: CoroutineDispatcher, ) { companion object { @@ -133,6 +137,7 @@ class GetCallSoundsUseCase @Inject constructor( Timber.d("Session in progress") stopCountDown(call.chatid, participant) } + MegaChatSession.SESSION_STATUS_DESTROYED -> { isRecoverable?.let { isRecoverableSession -> if (isRecoverableSession) { @@ -198,7 +203,8 @@ class GetCallSoundsUseCase @Inject constructor( } waitingForOthersCountDownTimer?.start( - SECONDS_TO_WAIT_FOR_OTHERS_TO_JOIN_THE_CALL) + SECONDS_TO_WAIT_FOR_OTHERS_TO_JOIN_THE_CALL + ) } else { MegaApplication.getChatManagement() .startCounterToFinishCall(chatId) @@ -216,36 +222,38 @@ class GetCallSoundsUseCase @Inject constructor( sharingScope.launch { monitorChatCallUpdatesUseCase() .collectLatest { call -> - call.changes?.apply { - Timber.d("Monitor chat call updated, changes $this") - if (contains(ChatCallChanges.Status)) { - when (call.status) { - ChatCallStatus.TerminatingUserParticipation -> { - Timber.d("Terminating user participation") - removeWaitingForOthersCountDownTimer() - MegaApplication.getChatManagement() - .stopCounterToFinishCall() - rtcAudioManagerGateway.removeRTCAudioManager() - emitter.onNext(CallSoundType.CALL_ENDED) - } + withContext(mainImmediateDispatcher) { + call.changes?.apply { + Timber.d("Monitor chat call updated, changes $this") + if (contains(ChatCallChanges.Status)) { + when (call.status) { + ChatCallStatus.TerminatingUserParticipation -> { + Timber.d("Terminating user participation") + removeWaitingForOthersCountDownTimer() + MegaApplication.getChatManagement() + .stopCounterToFinishCall() + rtcAudioManagerGateway.removeRTCAudioManager() + emitter.onNext(CallSoundType.CALL_ENDED) + } - else -> {} + else -> {} + } } - } - if (contains(ChatCallChanges.WaitingRoomUsersEntered)) { - if (call.waitingRoom?.peers?.size == 1) { - shouldPlaySoundWhenShowWaitingRoomDialog = true - Handler(Looper.getMainLooper()).postDelayed({ - if (shouldPlaySoundWhenShowWaitingRoomDialog) { - emitter.onNext(CallSoundType.WAITING_ROOM_USERS_ENTERED) - } - }, 1000) + if (contains(ChatCallChanges.WaitingRoomUsersEntered)) { + if (call.waitingRoom?.peers?.size == 1) { + shouldPlaySoundWhenShowWaitingRoomDialog = true + Handler(Looper.getMainLooper()).postDelayed({ + if (shouldPlaySoundWhenShowWaitingRoomDialog) { + emitter.onNext(CallSoundType.WAITING_ROOM_USERS_ENTERED) + } + }, 1000) + } } - } - if (contains(ChatCallChanges.WaitingRoomUsersLeave)) { - shouldPlaySoundWhenShowWaitingRoomDialog = false + if (contains(ChatCallChanges.WaitingRoomUsersLeave)) { + shouldPlaySoundWhenShowWaitingRoomDialog = false + } } } } @@ -277,13 +285,17 @@ class GetCallSoundsUseCase @Inject constructor( ) .addTo(disposable) - LiveEventBus.get(EventConstants.EVENT_CALL_OUTGOING_RINGING_CHANGE, - MegaChatCall::class.java) + LiveEventBus.get( + EventConstants.EVENT_CALL_OUTGOING_RINGING_CHANGE, + MegaChatCall::class.java + ) .observeForever(outgoingRingingStatusObserver) emitter.setCancellable { - LiveEventBus.get(EventConstants.EVENT_CALL_OUTGOING_RINGING_CHANGE, - MegaChatCall::class.java) + LiveEventBus.get( + EventConstants.EVENT_CALL_OUTGOING_RINGING_CHANGE, + MegaChatCall::class.java + ) .removeObserver(outgoingRingingStatusObserver) removeWaitingForOthersCountDownTimer() @@ -382,4 +394,4 @@ class GetCallSoundsUseCase @Inject constructor( } waitingForOthersCountDownTimer = null } -} \ No newline at end of file +} diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModelTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModelTest.kt index 375c1ac607..22ef7a3797 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModelTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/LeftMeetingViewModelTest.kt @@ -4,13 +4,12 @@ import androidx.lifecycle.SavedStateHandle import app.cash.turbine.test import com.google.common.truth.Truth import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.setMain -import mega.privacy.android.app.featuretoggle.ApiFeatures import mega.privacy.android.app.meeting.activity.MeetingActivity import mega.privacy.android.app.presentation.meeting.LeftMeetingViewModel -import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -19,7 +18,6 @@ import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.reset import org.mockito.kotlin.whenever -import org.mockito.kotlin.wheneverBlocking @TestInstance(TestInstance.Lifecycle.PER_CLASS) internal class LeftMeetingViewModelTest { @@ -27,11 +25,11 @@ internal class LeftMeetingViewModelTest { private val callEndedDueLimit: Boolean = true private lateinit var underTest: LeftMeetingViewModel - private val getFeatureFlagValueUseCase = mock() private val savedStateHandle: SavedStateHandle = mock { on { get(MeetingActivity.MEETING_FREE_PLAN_USERS_LIMIT) } doReturn true } + @OptIn(ExperimentalCoroutinesApi::class) @BeforeAll internal fun init() { Dispatchers.setMain(UnconfinedTestDispatcher()) @@ -40,18 +38,15 @@ internal class LeftMeetingViewModelTest { @BeforeEach fun resetMocks() { reset( - getFeatureFlagValueUseCase, savedStateHandle, ) whenever(savedStateHandle.get(MeetingActivity.MEETING_FREE_PLAN_USERS_LIMIT)).thenReturn( true ) - wheneverBlocking { getFeatureFlagValueUseCase(ApiFeatures.CallUnlimitedProPlan) } doReturn true } private fun initTestClass() { underTest = LeftMeetingViewModel( - getFeatureFlagValueUseCase = getFeatureFlagValueUseCase, savedStateHandle = savedStateHandle, ) } @@ -66,6 +61,4 @@ internal class LeftMeetingViewModelTest { Truth.assertThat(awaitItem().callEndedDueToFreePlanLimits).isEqualTo(callEndedDueLimit) } } - - } From 1bb6e6a0c264d098b154a0fbeb05145b428aa3d4 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Tue, 4 Jun 2024 09:06:31 +0600 Subject: [PATCH 141/261] MEET-3820: Remove isCallUnlimitedProPlanFeatureFlagEnabled from LeftMeetingState --- .../android/app/meeting/activity/LeftMeetingActivity.kt | 8 ++++---- .../app/presentation/meeting/model/LeftMeetingState.kt | 4 ---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/LeftMeetingActivity.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/LeftMeetingActivity.kt index da6ceb716c..d059fcb98d 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/LeftMeetingActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/LeftMeetingActivity.kt @@ -3,6 +3,7 @@ package mega.privacy.android.app.meeting.activity import android.content.Intent import android.os.Bundle import androidx.activity.viewModels +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.getValue import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.core.view.isVisible @@ -58,10 +59,9 @@ class LeftMeetingActivity : BaseActivity() { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { - val isDark = Util.isDarkMode(this@LeftMeetingActivity) val state by viewModel.state.collectAsStateWithLifecycle() - if (state.callEndedDueToFreePlanLimits && state.isCallUnlimitedProPlanFeatureFlagEnabled) { - OriginalTempTheme(isDark = isDark) { + if (state.callEndedDueToFreePlanLimits) { + OriginalTempTheme(isDark = isSystemInDarkTheme()) { FreePlanLimitParticipantsDialog( onConfirm = { viewModel.onConsumeShowFreePlanParticipantsLimitDialogEvent() @@ -83,4 +83,4 @@ class LeftMeetingActivity : BaseActivity() { startActivity(createAccountIntent) finish() } -} \ No newline at end of file +} diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/model/LeftMeetingState.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/model/LeftMeetingState.kt index fe0eb68825..244753763f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/model/LeftMeetingState.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/model/LeftMeetingState.kt @@ -6,11 +6,7 @@ import mega.privacy.android.app.presentation.meeting.LeftMeetingViewModel * Data class defining the state of [LeftMeetingViewModel] * * @property callEndedDueToFreePlanLimits State event to show the force free plan limit participants dialog. - * @property isCallUnlimitedProPlanFeatureFlagEnabled True, if Call Unlimited Pro Plan feature flag enabled. False, otherwise. */ data class LeftMeetingState( val callEndedDueToFreePlanLimits: Boolean = false, - val isCallUnlimitedProPlanFeatureFlagEnabled: Boolean = false, ) - - From 9569dab9ede9128be1724a22670a2c9c3f4fbd7f Mon Sep 17 00:00:00 2001 From: Sida Qian Date: Tue, 4 Jun 2024 19:02:55 +1200 Subject: [PATCH 142/261] T16483033 Fix Paste over Limit Text # Conflicts: # app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt --- .../fileinfo/view/FileInfoDescriptionField.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt index 1caf455563..55c5b82582 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt @@ -25,8 +25,9 @@ import mega.privacy.android.app.R import mega.privacy.android.shared.original.core.ui.controls.text.MegaText import mega.privacy.android.shared.original.core.ui.controls.textfields.GenericDescriptionTextField import mega.privacy.android.shared.original.core.ui.preview.CombinedTextAndThemePreviews -import mega.privacy.android.shared.original.core.ui.theme.values.TextColor import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme +import mega.privacy.android.shared.original.core.ui.theme.values.TextColor +import mega.privacy.mobile.analytics.event.NodeInfoDescriptionCharacterLimitEvent import mega.privacy.mobile.analytics.event.NodeInfoDescriptionConfirmedEvent import mega.privacy.mobile.analytics.event.NodeInfoDescriptionEnteredEvent @@ -90,12 +91,13 @@ fun FileInfoDescriptionField( showUnderline = true, placeholderId = placeholderId, onValueChange = { - val oldLength = description.length - val newLength = it.length - if (newLength - oldLength > descriptionLimit) { + if (it.length > descriptionLimit) { + Analytics.tracker.trackEvent(NodeInfoDescriptionCharacterLimitEvent) + } + val isOverLimit = + description.length >= descriptionLimit && it.length >= description.length + if (!isOverLimit) { description = it.take(descriptionLimit) - } else if (oldLength < descriptionLimit || newLength < oldLength) { - description = it } }, ) From 1cbe763e3b0abb91ba02d9e9c77af43bb80c3eb1 Mon Sep 17 00:00:00 2001 From: sq Date: Tue, 4 Jun 2024 15:41:40 +0800 Subject: [PATCH 143/261] Revert "T16483033 Fix Paste over Limit Text" This reverts commit 9569dab9ede9128be1724a22670a2c9c3f4fbd7f. --- .../fileinfo/view/FileInfoDescriptionField.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt index 55c5b82582..1caf455563 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt @@ -25,9 +25,8 @@ import mega.privacy.android.app.R import mega.privacy.android.shared.original.core.ui.controls.text.MegaText import mega.privacy.android.shared.original.core.ui.controls.textfields.GenericDescriptionTextField import mega.privacy.android.shared.original.core.ui.preview.CombinedTextAndThemePreviews -import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import mega.privacy.android.shared.original.core.ui.theme.values.TextColor -import mega.privacy.mobile.analytics.event.NodeInfoDescriptionCharacterLimitEvent +import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import mega.privacy.mobile.analytics.event.NodeInfoDescriptionConfirmedEvent import mega.privacy.mobile.analytics.event.NodeInfoDescriptionEnteredEvent @@ -91,13 +90,12 @@ fun FileInfoDescriptionField( showUnderline = true, placeholderId = placeholderId, onValueChange = { - if (it.length > descriptionLimit) { - Analytics.tracker.trackEvent(NodeInfoDescriptionCharacterLimitEvent) - } - val isOverLimit = - description.length >= descriptionLimit && it.length >= description.length - if (!isOverLimit) { + val oldLength = description.length + val newLength = it.length + if (newLength - oldLength > descriptionLimit) { description = it.take(descriptionLimit) + } else if (oldLength < descriptionLimit || newLength < oldLength) { + description = it } }, ) From 4bdcc770a27f898f51211a7484d19a6ec2f54291 Mon Sep 17 00:00:00 2001 From: Sida Qian Date: Tue, 4 Jun 2024 19:02:55 +1200 Subject: [PATCH 144/261] T16483033 Fix Paste over Limit Text # Conflicts: # app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt --- .../fileinfo/view/FileInfoDescriptionField.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt index 1caf455563..21d680b461 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/fileinfo/view/FileInfoDescriptionField.kt @@ -25,8 +25,8 @@ import mega.privacy.android.app.R import mega.privacy.android.shared.original.core.ui.controls.text.MegaText import mega.privacy.android.shared.original.core.ui.controls.textfields.GenericDescriptionTextField import mega.privacy.android.shared.original.core.ui.preview.CombinedTextAndThemePreviews -import mega.privacy.android.shared.original.core.ui.theme.values.TextColor import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme +import mega.privacy.android.shared.original.core.ui.theme.values.TextColor import mega.privacy.mobile.analytics.event.NodeInfoDescriptionConfirmedEvent import mega.privacy.mobile.analytics.event.NodeInfoDescriptionEnteredEvent @@ -90,12 +90,10 @@ fun FileInfoDescriptionField( showUnderline = true, placeholderId = placeholderId, onValueChange = { - val oldLength = description.length - val newLength = it.length - if (newLength - oldLength > descriptionLimit) { + val isOverLimit = + description.length >= descriptionLimit && it.length >= description.length + if (!isOverLimit) { description = it.take(descriptionLimit) - } else if (oldLength < descriptionLimit || newLength < oldLength) { - description = it } }, ) From fdd8bfd221a1b9d5537b5952980a81860ddf1ed1 Mon Sep 17 00:00:00 2001 From: Yenel Date: Tue, 4 Jun 2024 10:51:58 +0200 Subject: [PATCH 145/261] Fix compilation issue because a wrong import in MeetingActivityViewModel --- .../android/app/meeting/activity/MeetingActivityViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt index 85faa034c9..fa969d2ebb 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt @@ -118,7 +118,6 @@ import mega.privacy.android.domain.usecase.meeting.MonitorScheduledMeetingUpdate import mega.privacy.android.domain.usecase.meeting.MuteAllPeersUseCase import mega.privacy.android.domain.usecase.meeting.MutePeersUseCase import mega.privacy.android.domain.usecase.meeting.RingIndividualInACallUseCase -import mega.privacy.android.domain.usecase.meeting.StartVideoDeviceUseCase import mega.privacy.android.domain.usecase.network.IsConnectedToInternetUseCase import mega.privacy.android.domain.usecase.network.MonitorConnectivityUseCase import nz.mega.sdk.MegaApiJava From 3188e9541bea621974ce333d3c8903331ff173f4 Mon Sep 17 00:00:00 2001 From: Yenel Date: Tue, 4 Jun 2024 12:49:31 +0200 Subject: [PATCH 146/261] Update strings --- app/src/main/res/values-ar/strings.xml | 7 +++ app/src/main/res/values-de/strings.xml | 7 +++ app/src/main/res/values-es/strings.xml | 9 ++- .../values-es/strings_document_scanner.xml | 4 +- app/src/main/res/values-fr/strings.xml | 7 +++ app/src/main/res/values-in/strings.xml | 7 +++ app/src/main/res/values-it/strings.xml | 13 ++++- app/src/main/res/values-ja/strings.xml | 6 ++ app/src/main/res/values-ko/strings.xml | 13 ++++- app/src/main/res/values-nl/strings.xml | 7 +++ app/src/main/res/values-pl/strings.xml | 7 +++ app/src/main/res/values-pt/strings.xml | 7 +++ app/src/main/res/values-ro/strings.xml | 7 +++ app/src/main/res/values-ru/strings.xml | 7 +++ app/src/main/res/values-th/strings.xml | 7 +++ app/src/main/res/values-vi/strings.xml | 7 +++ app/src/main/res/values-zh-rCN/strings.xml | 7 +++ app/src/main/res/values-zh-rTW/strings.xml | 6 ++ .../strings_device_center_feature.xml | 6 +- .../strings_device_center_feature.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 14 +++++ .../src/main/res/values-de/strings_shared.xml | 18 +++++- .../src/main/res/values-es/strings_shared.xml | 56 ++++++++++++------- .../src/main/res/values-fr/strings_shared.xml | 14 +++++ .../src/main/res/values-in/strings_shared.xml | 16 +++++- .../src/main/res/values-it/strings_shared.xml | 36 ++++++++---- .../src/main/res/values-ja/strings_shared.xml | 14 +++++ .../src/main/res/values-ko/strings_shared.xml | 14 +++++ .../src/main/res/values-nl/strings_shared.xml | 14 +++++ .../src/main/res/values-pl/strings_shared.xml | 14 +++++ .../src/main/res/values-pt/strings_shared.xml | 18 +++++- .../src/main/res/values-ro/strings_shared.xml | 18 +++++- .../src/main/res/values-ru/strings_shared.xml | 18 +++++- .../src/main/res/values-th/strings_shared.xml | 18 +++++- .../src/main/res/values-vi/strings_shared.xml | 14 +++++ .../main/res/values-zh-rCN/strings_shared.xml | 14 +++++ .../main/res/values-zh-rTW/strings_shared.xml | 14 +++++ 37 files changed, 411 insertions(+), 56 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 4c8d7c8541..bd6b864d24 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6340,4 +6340,11 @@ %1$s و %2$d آخرون رفعوا يدهم %1$s و %2$d آخرون رفعوا يدهم + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cda3d610cb..e55b5610d7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5388,4 +5388,11 @@ %1$s und %2$d weitere Person haben die Hand gehoben %1$s und %2$d weitere Personen haben die Hand gehoben + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 84190fcf3e..3c464dd929 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1482,7 +1482,7 @@ Adjuntar - Nombre inválido + Nombre no válido Corrige los nombres de archivo antes de continuar @@ -5626,4 +5626,11 @@ %1$s y otros %2$d han levantado la mano %1$s y otros %2$d han levantado la mano + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings_document_scanner.xml b/app/src/main/res/values-es/strings_document_scanner.xml index cf9f8d9fe3..a698bb541a 100644 --- a/app/src/main/res/values-es/strings_document_scanner.xml +++ b/app/src/main/res/values-es/strings_document_scanner.xml @@ -39,13 +39,13 @@ Se necesita el permiso de la cámara para escanear documentos - Nombre inválido + Nombre no válido Caracteres no permitidos Corrige el nombre del archivo antes de continuar - Preparando %1$s. Espera por favor… + Preparando %1$s. Espera… Los siguientes caracteres no están permitidos: %1$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 261956b1f8..e2dfdd952e 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5626,4 +5626,11 @@ %1$s et %2$d autres personnes ont levé la main %1$s et %2$d autres personnes ont levé la main + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 579df01d47..dc280cb729 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -5150,4 +5150,11 @@ %1$s dan %2$d yang lain mengangkat tangan + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 9e7eb9c5a8..62539dec24 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -125,7 +125,7 @@ Non mostrare più - Are you sure you want to cancel the current login process? + Vuoi veramente annullare il processo corrente di login? Entra @@ -1043,7 +1043,7 @@ [A]Effettua il logout[/A] per cambiare account MEGA - Are you sure you want to log out of the current account? + Vuoi veramente effettuare il logout dall\’account corrente? Questo messaggio è stato eliminato da %1$s @@ -5618,10 +5618,17 @@ You and %1$d others raised your hands - %1$s raised their hand + %1$s ha alzato la mano %1$s and %2$d other raised their hands %1$s and %2$d others raised their hands + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 486f345e44..11eb1c311b 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5150,4 +5150,10 @@ %1$sさんとその他%2$d人が挙手しました + + このアルバムには隠し項目があります。アルバムを共有すると、共有相手には非表示の項目が表示されます。それらの項目は引き続きクラウドドライブに隠されたままです。 + + + 非表示項目 + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 8192accd8d..0b115ec43f 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -121,7 +121,7 @@ 다시 보여주지 마세요 - Are you sure you want to cancel the current login process? + 현재 로그인 과정을 취소 하시겠습니까? 로그인 @@ -1011,7 +1011,7 @@ MEGA 계정을 전환하려면 [A]로그아웃[/A]하세요 - Are you sure you want to log out of the current account? + 현재 계정에서 로그아웃 하시겠습니까? 이 메시지는 %1$s님에 의해 삭제되었습니다 @@ -5127,7 +5127,7 @@ 더 보기 - Raise hand + 손을 드세요 Lower hand @@ -5151,4 +5151,11 @@ %1$s 님 외 %2$d명이 손을 들었습니다 + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 478272f28b..3b4fc5fcc2 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5388,4 +5388,11 @@ %1$s en %2$d anderen staken hun hand op %1$s en %2$d anderen staken hun hand op + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8fcce9c712..76e96021a0 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5864,4 +5864,11 @@ %1$s i %2$d inni podniosili ręce %1$s i %2$d inni podniosili ręce + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 886c6f5b84..42a9a51a40 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5626,4 +5626,11 @@ %1$s e mais %2$d de pessoas levantaram a mão %1$s e mais %2$d pessoas levantaram a mão + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index bb69370fd2..912e9eabe0 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5626,4 +5626,11 @@ %1$s și alte %2$d persoane au ridicat mâna %1$s și alte %2$d de persoane au ridicat mâna + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 495b7c0edf..a636f26130 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5864,4 +5864,11 @@ %1$s и ещё %2$d подняли руки %1$s и ещё %2$d подняли руки + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 23dff02880..a6e5be17ac 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -5150,4 +5150,11 @@ %1$s และคนอื่น ๆ อีก %2$d คนได้ยกมือ + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 7d0eda64ed..96d8730bff 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -5150,4 +5150,11 @@ %1$s và %2$d người khác đang giơ tay + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e996beefe5..f81379b52d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5150,4 +5150,11 @@ %1$s和其他%2$d个人举起手 + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + Hidden item + Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c3e5181371..f603929cbe 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -5150,4 +5150,10 @@ %1$s和其他%2$d個人舉起手 + + There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + + + 隱藏的項目 + \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml index d1bb49a9ad..2831f672de 100644 --- a/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-es/strings_device_center_feature.xml @@ -89,9 +89,9 @@ Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Vuelve a intentarlo más tarde. Si el problema persiste, ponte en contacto con el servicio de soporte. - Cuenta recargada. No se han realizado actualizaciones pendientes de tus backups o sincronizaciones. + Cuenta recargada. Las actualizaciones pendientes de tus backups o sincronizaciones no se han aplicado. - La sincronización o el backup se han detenido porque parece que has cerrado sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. + La sincronización o el backup se han detenido porque se ha cerrado la sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. N/A @@ -123,7 +123,7 @@ Error desconocido. - Something went wrong. + Algo ha salido mal Los archivos de esta carpeta no se pueden sincronizar ni se puede hacer un backup porque la carpeta de MEGA está en la Papelera diff --git a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml index 4225035fad..e89f809c88 100644 --- a/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-it/strings_device_center_feature.xml @@ -115,7 +115,7 @@ Impossibile leggere la posizione della sincronizzazione. Controlla che la posizione sia accessibile e i permessi per la cartella della posizione siano garantiti. - Unable to open state cache database + Impossibile aprire il database della cache di stato Spazio per il download insufficiente. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index aae4cdeff6..7c4c79c5fd 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -398,4 +398,18 @@ حافظ على مزامنة معلوماتك وتحديثها من خلال الترقية إلى إحدى باقات برو Pro الخاصة بنا. رق حسابك الآن + + قم بالترقية إلى برو Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + ترقية + + ليس الآن + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 73785a27a3..aaca7603fa 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -361,9 +361,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Neue Funktion: Hand heben[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Nehmen Sie ein Upgrade auf eines unserer Pro-Pakete vor, um Ihre Daten zu synchronisieren und auf dem neuesten Stand zu halten. Jetzt upgraden + + Zu Pro wechseln + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Upgrade + + Jetzt nicht + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index c2b4cf5204..84743d8817 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -33,9 +33,9 @@ Se ha producido un problema al sincronizar o hacer un backup de esta carpeta. Vuelve a intentarlo más tarde. Si el problema persiste, ponte en contacto con el servicio de soporte. - Cuenta recargada. No se han realizado actualizaciones pendientes de tus backups o sincronizaciones. + Cuenta recargada. Las actualizaciones pendientes de tus backups o sincronizaciones no se han aplicado. - La sincronización o el backup se han detenido porque parece que has cerrado sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. + La sincronización o el backup se han detenido porque se ha cerrado la sesión en la aplicación de escritorio. Vuelve a iniciar sesión a través de la aplicación de escritorio y reanuda la operación. N/A @@ -89,9 +89,9 @@ Comparte archivos de gran tamaño gracias a una generosa cuota de transferencia y garantiza la seguridad con enlaces protegidos por contraseña. - No vuelva a perder datos + No vuelvas a perder ningún dato - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Rebobina y restaura tus datos hasta un máximo de 180 días, para que estén protegidos de accidentes y cambios no deseados. MEGA VPN @@ -287,17 +287,17 @@ Si has escrito mal tu dirección de correo electrónico, corrígela y pulsa en [A]Reenviar[/A]. - Syncing paused, your MEGA plan has run out of storage + Sincronización pausada, tu plan de MEGA se ha quedado sin almacenamiento disponible Ampliar Subida en pausa, el teléfono no se está cargando. - No syncs set up + Ninguna sincronización configurada Cuenta desactivada - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + Tu cuenta Pro Flexi ha sido desactivada porque has cancelado la suscripción o porque el pago ha fallado. No podrás acceder a los datos almacenados en tu cuenta. \nPara realizar el pago y reactivar la suscripción, inicia sesión en MEGA a través de un navegador. Starter @@ -305,15 +305,15 @@ Essential - Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + Las subidas solo se realizarán cuando el dispositivo se esté cargando y la batería esté por encima del 20%. - No syncs set up + Ninguna sincronización configurada - Sync a local folder on your device with a folder on MEGA. + Sincroniza una carpeta local en tu dispositivo con una carpeta de MEGA. - Add new sync + Añadir sincronización - Solved issues + Problemas resueltos You can’t sync folders that are currently synced folders. @@ -321,17 +321,17 @@ Añadir descripción - Description added + Descripción añadida - Description updated + Descripción actualizada Además de acceso a estos fantásticos beneficios: - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + • MEGA VPN \n• Llamadas y reuniones sin restricciones \n• Sincronización automática de carpetas en tu dispositivo móvil \n• Sin anuncios - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + • MEGA VPN \n• Llamadas y reuniones sin restricciones \n• Sincronización automática de carpetas en tu dispositivo móvil - No solved issues + No hay problemas resueltos Tú tienes las claves @@ -347,11 +347,11 @@ Chat totalmente cifrado con llamadas y videollamadas, chat de grupo y capacidad de compartir archivos con tu Cloud Drive. - Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + Añade contactos, crea tu propia red, colabora y haz llamadas y videollamadas sin salir de MEGA. La función Subidas de la cámara es esencial para cualquier dispositivo móvil y nosotros la tenemos. Crea tu cuenta ahora. - Zero-knowledge encrypted video meeting. + Reunión con cifrado de conocimiento cero. @string/cloud_drive_tour_first_title @@ -369,9 +369,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Nueva función: Levantar la mano[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Mantén tu información sincronizada y al día ampliando tu cuenta a uno de nuestros planes Pro. Ampliar cuenta + + Ampliar cuenta a Pro + + Mantén tu dispositivo móvil sincronizado con la nube con nuestros planes Pro. + + Ampliar + + Ahora no + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index e7a6088aa2..eb4209597d 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -374,4 +374,18 @@ Gardez vos données synchronisés et à jour en optant pour l’un de nos abonnements Pro. Surclasser le compte maintenant + + Souscrire un abonnement Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Surclasser mon compte + + Pas maintenant + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index b84b7fc0db..1893e37688 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -293,7 +293,7 @@ Essential - Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + Unggahan akan dihentikan sementara sampai anda mulai mengisi daya perangkat anda. Unggahan akan tetap dihentikan sementara jika baterai anda di bawah 20%. No syncs set up @@ -362,4 +362,18 @@ Keep your information syncing and up to date by upgrading to one of our Pro plans. Tingkatkan sekarang + + Tingkatkan ke Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Tingkatkan + + Jangan Sekarang + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 20ac9f1ea7..9b1e359a8b 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -91,7 +91,7 @@ Non perdere mai più dati - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Riavvolgi per ripristinare le cartelle a qualsiasi data fino a 180 giorni fa, in modo che i tuoi dati siano a prova di incidenti e manomissioni. MEGA VPN @@ -321,15 +321,15 @@ Aggiungi descrizione - Description added + Descrizione aggiunta - Description updated + Descrizione aggiornata - Plus access to these great benefits: + Accesso Plus a questi fantastici vantaggi: - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + • MEGA VPN\n• Chiamate e meeting senza restrizioni\n• Sincronizzazione automatica delle cartelle sul tuo dispositivo mobile\n• Nessuna pubblicità - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + • MEGA VPN\n• Chiamate e meeting senza restrizioni\n• Sincronizzazione automatica delle cartelle sul tuo dispositivo mobile Nessun problema risolto @@ -341,17 +341,17 @@ Le tue foto nel cloud - MEGA meeting + Meeting MEGA La sicurezza è il motivo per cui esistiamo, i tuoi file sono al sicuro con noi dietro ad una macchina di criptazione ben oliata dove solo tu puoi accedere ad i tuoi file. Chat interamente criptate con chiamate audio e video, messaggi di gruppo e condivisione di file integrata al tuo Cloud Drive. - Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + Aggiungi contatti, crea un network, collabora, ed effettua chiamate audio e video senza lasciare mai MEGA. I Caricamenti da fotocamera sono una feature essenziale per qualsiasi dispositivo mobile e possiamo farlo per te. Crea il tuo account adesso. - Zero-knowledge encrypted video meeting. + Meeting video criptati con conoscenza zero. @string/cloud_drive_tour_first_title @@ -369,9 +369,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Nuova caratteristica: Alza la mano[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Mantieni le tue informazioni sincronizzate e aggiornate effettuando l\’upgrade ad uno dei nostri piani Pro. Effettua l\’upgrade ora + + Effettua l’upgrade a Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Effettua l’upgrade + + Non adesso + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 5a054b6b05..f662262e1b 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -358,4 +358,18 @@ Proプランのいずれかにアップグレードしていただくと、情報を常に同期して最新の状態に保つことができます。 今すぐアップグレード + + Proにアップグレード + + 当社のProプランをご利用いただくと、モバイルをクラウドに同期する機能をご利用いただけるようになります。 + + アップグレード + + 今はやめます + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index f1cba62d3c..d67f29de1f 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -358,4 +358,18 @@ Keep your information syncing and up to date by upgrading to one of our Pro plans. 지금 업그레이드 + + Pro로 업그레이드 + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + 업그레이드 + + 나중에 + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 7ff9a2a3a8..0f7cedc494 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -366,4 +366,18 @@ Houd uw informatie gesynchroniseerd en up-to-date door te upgraden naar een van onze Pro-abonnementen. Nu upgraden + + Upgraden naar Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Upgraden + + Niet Nu + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index a7b5251ad0..c754466489 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -382,4 +382,18 @@ Synchronizuj i aktualizuj swoje informacje, aktualizując do jednego z naszych planów Pro. Zmień teraz + + Zmień na wersję Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Zmień + + Nie teraz + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 42dc51af24..a8d0a4c2c8 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -369,9 +369,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Novo recurso: Levantar a mão[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Mantenha a sua informação sincronizada e atualizada fazendo o upgrade a um dos nossos planos Pro. Upgrade + + Fazer o upgrade a Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Upgrade + + Agora não + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 10ca9f82ba..64615c287c 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -369,9 +369,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Funcție nouă: ridicați mâna[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Păstrați-vă informațiile sincronizate și upgradate trecând la unul dintre abonamentele noastre Pro. Upgradați acum + + Upgradează la Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Upgradează + + Nu acum + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 692af5f638..92a5fa5148 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -377,9 +377,23 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]Новая функция: поднять руку[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Обеспечьте синхронизацию и актуальность информации, перейдя на один из наших планов Pro. Улучшить + + Улучшение до Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Улучшить + + Не сейчас + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 4419a4f627..716eae6085 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -327,9 +327,9 @@ การประชุม MEGA - ความปลอดภัยคือเหตุผลหลักที่เราดำเนินการอยู่ ไฟล์ของคุณจะมีความปลอดภัยมากยิ่งขึ้น เพราะใช้เครื่องมือเข้ารหัสที่ป้องกันไฟล์ของคุณ ซึ่งมีเพียงคุณเท่านั้นที่สามารถเข้าถึงไฟล์ได้ + ความปลอดภัยคือหัวใจสำคัญของเรา ข้อมูลของคุณจะถูกเก็บไว้อย่างปลอดภัยด้วยระบบการเข้ารหัสที่ล้ำสมัย เฉพาะคุณเท่านั้นที่จะสามารถเข้าถึงไฟล์ของคุณได้ - แชทที่มีการเข้ารหัสอย่างเต็มที่ไม่ว่าจะเป็นการโทรด้วยเสียงและสนทนาทางวิดีโอ การส่งข้อความแบบกลุ่มและบูรณาการไฟล์ร่วมกันกับคลาวด์ไดรฟ์ของคุณ + แชทที่เข้ารหัสเต็มรูปแบบ รองรับการโทรด้วยเสียงและวิดีโอ ส่งข้อความแบบกลุ่ม และแชร์ไฟล์ได้อย่างราบรื่น ผ่านระบบคลาวด์ไดรฟ์ของคุณ เพิ่มผู้ติดต่อ สร้างกลุ่ม ทำงานร่วมกัน และโทรทั้งแบบเสียงและวิดีโอได้ง่าย ๆ โดยไม่ต้องออกจาก MEGA เลย @@ -358,4 +358,18 @@ อัปเกรดเป็นแผน Pro ช่วยให้คุณซิงค์ข้อมูลกับอุปกรณ์ต่าง ๆ ของคุณได้อย่างราบรื่นและมั่นใจได้ว่าข้อมูลจะอัปเดตอยู่เสมอ อัปเกรดตอนนี้เลย + + อัปเกรดเป็น Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + อัปเกรด + + ไม่ใช่ตอนนี้ + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index dcd5b5baa9..012ebb9b71 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -358,4 +358,18 @@ Giữ cho thông tin của bạn được đồng bộ hóa và cập nhật bằng cách nâng cấp lên một trong các gói Pro của chúng tôi. Nâng cấp ngay + + Nâng cấp lên Pro + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + Nâng cấp + + Không phải lúc này + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 67f1a0b16d..74ab2651f1 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -358,4 +358,18 @@ 通过升级到我们的Pro方案之一,让您的信息保持同步并且是最新状态。 立即升级 + + 升级为Pro帐户 + + Unlock the power to sync your mobile to the cloud with our Pro plans. + + 升级 + + 现在不用 + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index ecefcd7cc6..4a45417437 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -358,4 +358,18 @@ 升級到我們當中一項Pro方案,讓您的資訊同步並保持最新狀態。 立即升級 + + 升級為Pro會員 + + 透過我們的Pro方案將您手機同步到雲端的功能解鎖。 + + 升級 + + 稍後再說 + + Uploads folder conflict + + Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + + Okay, got it \ No newline at end of file From 6cee379ce130a172d5e796647580378b41613ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Tue, 4 Jun 2024 23:55:08 +1200 Subject: [PATCH 147/261] Pre-release - v13.3 --- build.gradle.kts | 2 +- sdk/src/main/jni/megachat/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a7635e5ba0..9108bce687 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -85,7 +85,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "34.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240529.112710-rel" +extra["megaSdkVersion"] = "20240604.113356-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/megachat/sdk b/sdk/src/main/jni/megachat/sdk index 5a5f0b6b7b..8b47dfd757 160000 --- a/sdk/src/main/jni/megachat/sdk +++ b/sdk/src/main/jni/megachat/sdk @@ -1 +1 @@ -Subproject commit 5a5f0b6b7b81661fe2fd6c71b124e95431326221 +Subproject commit 8b47dfd757e82d3a59f29d680ee331491ad4b17f From ca6acbe886f759767fc46c4dfaf5b413f7ac2278 Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Thu, 6 Jun 2024 22:20:43 +1200 Subject: [PATCH 148/261] MEET-3820(T16483117) AND - Raise feature flag for chat monetisation app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt --- .../android/app/main/ManagerActivity.kt | 1 + .../presentation/manager/ManagerViewModel.kt | 7 +++- .../meeting/chat/model/ChatViewModel.kt | 37 +++++++++++++++---- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 62034f0cb4..3b46520ad9 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -863,6 +863,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf Timber.d("onStart") mStopped = false sortByHeaderViewModel.refreshData(isUpdatedOrderChangeState = true) + viewModel.markHandledMessage() super.onStart() } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt index 861f77e4c5..08af9d678b 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow @@ -314,6 +315,8 @@ class ManagerViewModel @Inject constructor( */ val numUnreadUserAlerts = _numUnreadUserAlerts.asStateFlow() + private var monitorCallInChatJob: Job? = null + /** * Is network connected */ @@ -398,7 +401,8 @@ class ManagerViewModel @Inject constructor( } } - viewModelScope.launch { + monitorCallInChatJob?.cancel() + monitorCallInChatJob = viewModelScope.launch { monitorChatCallUpdatesUseCase() .collect { it.apply { @@ -407,6 +411,7 @@ class ManagerViewModel @Inject constructor( if (termCode == ChatCallTermCodeType.CallUsersLimit && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled ) { + setUsersCallLimitReminder(true) _state.update { state -> state.copy(callEndedDueToFreePlanLimits = true) } } else if (termCode == ChatCallTermCodeType.CallDurationLimit && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled) { if (it.isOwnClientCaller) { diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt index 32d320bd58..58a5937bd3 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/model/ChatViewModel.kt @@ -726,18 +726,41 @@ class ChatViewModel @Inject constructor( it?.apply { when (status) { ChatCallStatus.TerminatingUserParticipation, ChatCallStatus.GenericNotification -> - if ((termCode == ChatCallTermCodeType.CallUsersLimit || termCode == ChatCallTermCodeType.TooManyParticipants) - && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled - ) { - _state.update { state -> state.copy(callEndedDueToFreePlanLimits = true) } - } else if (termCode == ChatCallTermCodeType.CallDurationLimit && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled) { - if (it.isOwnClientCaller) { + when (termCode) { + ChatCallTermCodeType.TooManyParticipants -> { + val infoToShow = + InfoToShow.SimpleString(stringId = R.string.call_error_too_many_participants) _state.update { state -> state.copy( - shouldUpgradeToProPlan = true + infoToShowEvent = triggered( + infoToShow + ) ) } } + + ChatCallTermCodeType.CallDurationLimit -> { + if (it.isOwnClientCaller && _state.value.isCallUnlimitedProPlanFeatureFlagEnabled) { + _state.update { state -> + state.copy( + shouldUpgradeToProPlan = true + ) + } + } + } + + ChatCallTermCodeType.CallUsersLimit -> { + if (_state.value.isCallUnlimitedProPlanFeatureFlagEnabled) { + setUsersCallLimitReminder(true) + _state.update { state -> + state.copy( + callEndedDueToFreePlanLimits = true + ) + } + } + } + + else -> {} } else -> {} From 3d7edee4e10dc90ca7b633e1aaacba53c6a2f298 Mon Sep 17 00:00:00 2001 From: Yenel Date: Thu, 6 Jun 2024 13:49:59 +0200 Subject: [PATCH 149/261] AND-17810 Hotfix: T16511548 Join a chatroom from a chat link --- .../meeting/chat/view/message/link/LinkContent.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/link/LinkContent.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/link/LinkContent.kt index 7bb097991a..0adb1b4524 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/link/LinkContent.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/message/link/LinkContent.kt @@ -12,11 +12,11 @@ import mega.privacy.android.app.presentation.meeting.chat.view.ChatAvatar import mega.privacy.android.app.presentation.meeting.chat.view.navigation.compose.navigateToChatViewGraph import mega.privacy.android.app.presentation.meeting.chat.view.navigation.openFileLinkActivity import mega.privacy.android.app.presentation.meeting.chat.view.navigation.openFolderLinkActivity -import mega.privacy.android.shared.original.core.ui.controls.chat.messages.ContactMessageContentView import mega.privacy.android.core.ui.mapper.FileTypeIconMapper import mega.privacy.android.domain.entity.FolderInfo import mega.privacy.android.domain.entity.contacts.ContactLink import mega.privacy.android.domain.entity.node.TypedFileNode +import mega.privacy.android.shared.original.core.ui.controls.chat.messages.ContactMessageContentView /** * Link content @@ -98,7 +98,7 @@ data class ChatGroupLinkContent( override fun onClick(context: Context, navHostController: NavHostController) { if (isChatAvailable) { - navHostController.navigateToChatViewGraph(chatId, link) + navHostController.navigateToChatViewGraph(chatId = chatId, chatLink = link) } } } From 6ce35102f4472b5deaa9bf941274c7083118c981 Mon Sep 17 00:00:00 2001 From: Yenel Date: Thu, 6 Jun 2024 14:10:38 +0200 Subject: [PATCH 150/261] Update strings --- app/src/main/res/values-ar/strings.xml | 8 +++- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 5 ++- app/src/main/res/values-fr/strings.xml | 11 ++--- app/src/main/res/values-in/strings.xml | 3 +- app/src/main/res/values-it/strings.xml | 5 ++- app/src/main/res/values-ko/strings.xml | 18 ++++---- app/src/main/res/values-nl/strings.xml | 4 +- app/src/main/res/values-pl/strings.xml | 6 ++- app/src/main/res/values-pt/strings.xml | 7 +-- app/src/main/res/values-ro/strings.xml | 17 +++---- app/src/main/res/values-ru/strings.xml | 8 ++-- app/src/main/res/values-th/strings.xml | 3 +- app/src/main/res/values-vi/strings.xml | 5 +-- app/src/main/res/values-zh-rCN/strings.xml | 3 +- .../strings_device_center_feature.xml | 6 +-- .../src/main/res/values-ar/strings_shared.xml | 14 +++--- .../src/main/res/values-de/strings_shared.xml | 14 +++--- .../src/main/res/values-es/strings_shared.xml | 12 +++-- .../src/main/res/values-fr/strings_shared.xml | 18 +++++--- .../src/main/res/values-in/strings_shared.xml | 14 +++--- .../src/main/res/values-it/strings_shared.xml | 14 +++--- .../src/main/res/values-ja/strings_shared.xml | 18 +++++--- .../src/main/res/values-ko/strings_shared.xml | 44 ++++++++++--------- .../src/main/res/values-nl/strings_shared.xml | 14 +++--- .../src/main/res/values-pl/strings_shared.xml | 14 +++--- .../src/main/res/values-pt/strings_shared.xml | 18 +++++--- .../src/main/res/values-ro/strings_shared.xml | 18 +++++--- .../src/main/res/values-ru/strings_shared.xml | 18 +++++--- .../src/main/res/values-th/strings_shared.xml | 14 +++--- .../src/main/res/values-vi/strings_shared.xml | 18 +++++--- .../main/res/values-zh-rCN/strings_shared.xml | 14 +++--- .../main/res/values-zh-rTW/strings_shared.xml | 18 +++++--- .../src/main/res/values/strings_shared.xml | 24 ++++++++-- 34 files changed, 262 insertions(+), 169 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index bd6b864d24..1ba16110ab 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6344,7 +6344,11 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e55b5610d7..3c661d712d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5392,7 +5392,7 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3c464dd929..9798de95ab 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5630,7 +5630,8 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + + \ 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 e2dfdd952e..c56ca0ce41 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -4867,7 +4867,7 @@ Annuel - Économisez 16 % avec une facturation annuelle + Économisez jusqu’à 16 % avec une facturation annuelle [B]Espace de stockage :[/B] [A]%1$s[/A] @@ -5311,7 +5311,7 @@ Les abonnements MEGA Pro comprennent : - La plus grande flexibilité en matière d’espace de stockage + La plus grande adaptabilité en matière d’espace de stockage À partir de %1$s, trouvez la réponse idéale à vos besoins de stockage. @@ -5627,10 +5627,11 @@ %1$s et %2$d autres personnes ont levé la main - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Des éléments cachés sont présents dans cet album. Partager l’album implique que les éléments cachés sont visibles par les personnes avec qui vous le partagez. Les éléments resteront cachés sur votre Disque nuagique. - Hidden item - Hidden items + Un élément est caché + Des éléments sont cachés + Des éléments sont cachés \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index dc280cb729..699c036d44 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -5154,7 +5154,6 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 62539dec24..88fee84082 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5628,7 +5628,8 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 0b115ec43f..1ed8eb6672 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -5129,21 +5129,20 @@ 손을 드세요 - Lower hand + 손 내리기 - Put call on hold + 통화를 보류하기 - Swap calls + 통화 전환 통화 재개 - New feature: Raise hand + 새로운 기능: 손 들기 - You raised your hand + 당신이 손을 들었습니다 - You and %1$d other raised your hands - You and %1$d others raised your hands + 당신과 %1$d명이 손을 들었습니다 %1$s 님이 손을 들었습니다 @@ -5152,10 +5151,9 @@ %1$s 님 외 %2$d명이 손을 들었습니다 - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + 이 사진첩에 숨겨진 항목이 있습니다. 사진첩을 공유하는 것은 숨겨진 항목이 공유하고자 하는 사람들에게 보인다는 것입니다. 항목은 클라우드 드라이브에서 숨긴 상태로 유지됩니다. - Hidden item - Hidden items + 숨겨진 항목 \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3b4fc5fcc2..d292c81dbd 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5392,7 +5392,7 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 76e96021a0..3d1938b1c0 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5868,7 +5868,9 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + + + + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 42a9a51a40..891b9d64b0 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5627,10 +5627,11 @@ %1$s e mais %2$d pessoas levantaram a mão - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Há itens ocultos neste álbum. Ao compartilhar o álbum, os itens ocultos ficarão visíveis para as pessoas com as quais você o compartilhar, mas vão permanecer ocultos na sua Nuvem de arquivos. - Hidden item - Hidden items + Item oculto + itens ocultos + itens ocultos \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 912e9eabe0..850e0c71ea 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -33,7 +33,7 @@ Exportă - OK + Bine Omite @@ -3907,7 +3907,7 @@ Setări - OK, am înțeles + Bine, am înțeles Oricine cu acest link se poate alătura întâlnirii și poate vedea chatul întâlnirii. @@ -5325,7 +5325,7 @@ Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe dispozitivul persoanei care o înregistrează. - OK, am înțeles + Bine, am înțeles Părăsește apelul @@ -5483,7 +5483,7 @@ Contul dvs. Business a fost dezactivat din cauza eșecului plății. Puteți doar să vă consultați datele dvs.\nPentru a efectua o plată și a reactiva abonamentul, conectați-vă la MEGA printr-un browser. - OK, am înțeles + Bine, am înțeles • Găzduiți apeluri și întâlniri cu participanți nelimitați și fără restricții de timp. @@ -5523,7 +5523,7 @@ La acest apel pot participa maximum 100 de persoane. Cereți persoanei care a organizat-o să ridice această limită. - OK, am înțeles + Bine, am înțeles Fișiere și foldere ascunse @@ -5627,10 +5627,11 @@ %1$s și alte %2$d de persoane au ridicat mâna - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Există elemente ascunse în acest album. Împărtășirea albumului înseamnă că elementele ascunse sunt vizibile pentru persoanele cu care îl partajați. Elementele vor rămâne ascunse în Unitatea cloud. - Hidden item - Hidden items + Un element este ascuns + Elemente ascunse + Elemente ascunse \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a636f26130..0bcbb6a0fa 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5865,10 +5865,12 @@ %1$s и ещё %2$d подняли руки - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + В этом альбоме есть скрытые элементы. Если вы поделитесь альбомом, скрытые элементы будут видны тем, с кем вы делитесь. Эти элементы по-прежнему будут скрыты на вашем Облачном диске. - Hidden item - Hidden items + Скрытый элемент + Скрытые элементы + Скрытые элементы + Скрытые элементы \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index a6e5be17ac..55add8fc7b 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -5154,7 +5154,6 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 96d8730bff..568c63112c 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -5151,10 +5151,9 @@ %1$s và %2$d người khác đang giơ tay - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Có các mục ẩn trong album này. Việc thực hiện chia sẻ album sẽ làm các mục ẩn hiển thị cho những người bạn chia sẻ. Các mục vẫn sẽ được ẩn đi trong Ổ Mây của bạn. - Hidden item - Hidden items + Các mục ẩn \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index f81379b52d..245572c37f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5154,7 +5154,6 @@ There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. - Hidden item - Hidden items + \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml index fde7524a7d..0f6179cf3e 100644 --- a/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ko/strings_device_center_feature.xml @@ -57,7 +57,7 @@ 클라우드 드라이브에서 보기 - No sync error + 동기화 오류 없음 이 폴더는 당신의 기기의 파일 시스템이 지원하지 않기 때문에 MEGA에서 동기화 하거나 백업할 수 없습니다 @@ -115,7 +115,7 @@ 동기화 위치를 읽을 수 없습니다. 위치에 접근 가능한지 여부와 폴더 위치에 대한 권한이 승인 되었는지 확인하세요. - Unable to open state cache database + 상태 캐시 데이터베이스를 열 수 없습니다 다운로드에 필요한 공간 부족 @@ -123,7 +123,7 @@ 알 수 없는 오류. - Something went wrong. + 뭔가 잘못됐습니다. MEGA 폴더가 휴지통에 있어서 폴더를 동기화 또는 백업할 수 없습니다 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 7c4c79c5fd..11f141271c 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -91,7 +91,7 @@ لا تفقد البيانات مرة أخرى - يمكنك الترجيع لاستعادة المجلدات مرة أخرى إلى أي تاريخ يصل إلى 180 يومًا بحيث تكون بياناتك مقاومة للحوادث والعبث. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -315,7 +315,7 @@ ترقية - تم إيقاف الترفيع مؤقتًا، لا يتم شحن الهاتف + Upload paused, device is not charging لم يتم إعداد عمليات المزامنة @@ -339,7 +339,7 @@ المشكلات التي تم حلها - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. الوصف @@ -401,7 +401,7 @@ قم بالترقية إلى برو Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. ترقية @@ -409,7 +409,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index aaca7603fa..8ebc4b97c6 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -91,7 +91,7 @@ Nie mehr Datenverlust - Mit Rewind können Sie Ordner auf einen früheren Stand (bis zu 180 Tage) zurücksetzen, sodass Ihre Daten vor Missgeschicken und Manipulationen geschützt sind. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -283,7 +283,7 @@ Upgrade - Upload pausiert – das Telefon wird nicht geladen + Upload paused, device is not charging Keine Synchronisierungen eingerichtet @@ -307,7 +307,7 @@ Gelöste Probleme - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Beschreibung @@ -369,7 +369,7 @@ Zu Pro wechseln - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Upgrade @@ -377,7 +377,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 84743d8817..b39f29ec98 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -291,7 +291,7 @@ Ampliar - Subida en pausa, el teléfono no se está cargando. + Upload paused, device is not charging Ninguna sincronización configurada @@ -315,7 +315,7 @@ Problemas resueltos - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Descripción @@ -377,7 +377,7 @@ Ampliar cuenta a Pro - Mantén tu dispositivo móvil sincronizado con la nube con nuestros planes Pro. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Ampliar @@ -385,7 +385,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index eb4209597d..811b06d736 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -91,7 +91,7 @@ Ne plus jamais perdre de données - Retournez en arrière pour restaurer les dossiers à une date antérieure jusqu’à 180 jours. Ainsi, vos données sont protégées contre les accidents et les manipulations, inviolables. + Retournez en arrière pour restaurer fichiers et dossiers à une date antérieure jusqu’à 180 jours. Ainsi, vos données sont protégées contre les accidents et les manipulations, inviolables. RPV MEGA VPN @@ -291,7 +291,7 @@ Surclasser mon compte - Le téléversement est en pause, car le téléphone n’est pas en charge + Le téléversement est en pause, car l’appareil n’est pas en charge Aucune synchronisation n’est configurée @@ -315,7 +315,7 @@ Problèmes résolus - You can’t sync folders that are currently synced folders. + Ce dossier ne peut pas être synchronisé. Grâce aux Téléversements de l’appareil photo, configurez-le pour qu’il soit synchronisé avec MEGA. Description @@ -377,15 +377,19 @@ Souscrire un abonnement Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Nos abonnements Pro libèrent la puissance de synchronisation de votre appareil mobile vers MEGA. Surclasser mon compte Pas maintenant - Uploads folder conflict + Conflit de dossiers de téléversement - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Le dossier des téléversements de l’appareil photo et le dossier des téléversements secondaires de médias ne peuvent pas être liés l’un à l’autre. Choisissez un autre dossier. - Okay, got it + D’accord, j’ai compris + + Aucune appli n’est installée sur cet appareil pour sélectionner les dossiers + + • Synchronisez automatiquement les dossiers de votre appareil mobile \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 1893e37688..ec277a40b9 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -91,7 +91,7 @@ Jangan pernah kehilangan data lagi - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -279,7 +279,7 @@ Tingkatkan - Upload paused, phone is not charging + Upload paused, device is not charging No syncs set up @@ -303,7 +303,7 @@ Solved issues - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Deskripsi @@ -365,7 +365,7 @@ Tingkatkan ke Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Tingkatkan @@ -373,7 +373,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 9b1e359a8b..f2f071f78d 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -91,7 +91,7 @@ Non perdere mai più dati - Riavvolgi per ripristinare le cartelle a qualsiasi data fino a 180 giorni fa, in modo che i tuoi dati siano a prova di incidenti e manomissioni. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -291,7 +291,7 @@ Effettua l’upgrade - Caricamento in pausa, il dispositivo non è in carica + Upload paused, device is not charging Nessuna sincronizzazione configurata @@ -315,7 +315,7 @@ Problemi risolti - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Descrizione @@ -377,7 +377,7 @@ Effettua l’upgrade a Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Effettua l’upgrade @@ -385,7 +385,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index f662262e1b..3341ec933f 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -91,7 +91,7 @@ 二度とデータを失わない - 巻き戻してフォルダを最大180日までの任意の日付に復元できるため、データの事故や改ざんが防止されます。 + 巻き戻してファイルとフォルダを最大180日までの任意の日付に復元できるため、データの事故や改ざんが防止されます。 MEGA VPN @@ -275,7 +275,7 @@ アップグレード - アップロードが一時停止されました、携帯電話は充電されていません + アップロードが一時停止されました、デバイスは充電されていません 同期が設定されていません @@ -299,7 +299,7 @@ 解決済みの問題 - You can’t sync folders that are currently synced folders. + このフォルダは同期できません。カメラアップロードを使用してMEGAに同期するように設定します。 説明 @@ -361,15 +361,19 @@ Proにアップグレード - 当社のProプランをご利用いただくと、モバイルをクラウドに同期する機能をご利用いただけるようになります。 + 当社のProプランをご利用いただくと、モバイルデバイスをクラウドに同期する機能をご利用いただけるようになります。 アップグレード 今はやめます - Uploads folder conflict + アップロードフォルダの競合 - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + カメラアップロードフォルダとセカンダリメディアアップロードフォルダを相互に関連付けることはできません。別のフォルダを選択してください。 - Okay, got it + はい、わかりました + + この端末には、フォルダを選択するアプリがありません + + • モバイルデバイス上のフォルダを自動的に同期します \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index d67f29de1f..7d68c140e4 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -91,7 +91,7 @@ 다시는 데이터를 잃지 마세요 - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -271,17 +271,17 @@ 만약 이메일 주소를 잘못 입력하였다면, 수정하고 [A]재발송[/A]을 탭하세요. - Syncing paused, your MEGA plan has run out of storage + 당신의 MEGA 요금제의 저장소를 다 써서, 동기화가 일시정지 되었습니다 업그레이드 - 휴대전화가 충전 중이 아니어서, 업로드가 일시정지 되었습니다 + Upload paused, device is not charging - No syncs set up + 설정된 동기화가 없습니다 계정 비활성화됨 - Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. + 당신의 Pro Flexi 계정은 결제 실패 또는 구독 취소로 인해 비활성화 되었습니다. 계정 안에 있는 데이터에 접근하지 못할 것입니다.\n결제를 하고 구독을 재활성화 하려면, 브라우저에서 MEGA에 로그인 하세요. Starter @@ -289,17 +289,17 @@ Essential - Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. + 장치 충전을 시작할 때까지 업로드가 일시정지 됩니다. 배터리가 20% 이하일 경우 업로드가 일시정지 상태로 유지됩니다. - No syncs set up + 설정된 동기화가 없습니다 - Sync a local folder on your device with a folder on MEGA. + 장치의 로컬 폴더를 MEGA의 폴더와 동기화하세요. - Add new sync + 새 동기화 추가 해결된 문제 - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. 설명 @@ -309,11 +309,11 @@ 설명 수정됨 - Plus access to these great benefits: + 추가로 이러한 훌륭한 혜택이 있습니다: - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device \n• No advertisements + • MEGA VPN\n• 무제한 통화와 회의\n• 휴대 장치의 폴더를 자동으로 동기화\n• 광고 없음 - • MEGA VPN \n• Unrestricted calls and meetings \n• Automatically sync the folders on your mobile device + • MEGA VPN\n• 무제한 통화와 회의\n• 휴대 장치의 폴더를 자동으로 동기화 해결된 문제 없음 @@ -325,17 +325,17 @@ 클라우드 속 당신의 사진 - MEGA meeting + MEGA 회의 보안은 우리의 존재 이유이며, 당신의 파일들은 당신만이 접근 할수 있도록 우리 서버에 마치 잘 관리된 암호화 기계 뒤에 있는 것처럼 매우 안전합니다. 완전히 암호화된 대화와 음성과 영상 통화, 그룹 대화 그리고 클라우드 드라이브와 통합된 파일 공유. - Add contacts, create a network, collaborate, and make voice and video calls without ever leaving MEGA. + MEGA를 떠날 필요 없이 연락처를 추가하고, 네트워크를 형성하고, 협업하고, 음성과 영상 통화를 하세요. 카메라 업로드는 어떠한 모바일 기기에서든 필요한 기능이며 우리는 이 기능이 준비되어 있습니다. 지금 계정을 만드세요. - Zero-knowledge encrypted video meeting. + 영지식 암호화 화상 회의. @string/cloud_drive_tour_first_title @@ -353,15 +353,15 @@ @string/cloud_drive_tour_fifth_subtitle - [A]New feature: Raise hand[/A] + [A]새로운 기능: 손 들기[/A] - Keep your information syncing and up to date by upgrading to one of our Pro plans. + Pro 요금제 중 하나로 업그레이드하여 정보를 동기화하고 최신 상태로 유지하세요. 지금 업그레이드 Pro로 업그레이드 - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. 업그레이드 @@ -369,7 +369,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 0f7cedc494..56b4d1fd0c 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -91,7 +91,7 @@ Verlies nooit meer gegevens - Terugspoelen om mappen tot 180 dagen terug te zetten naar een willekeurige datum, zodat uw gegevens ongevallig en fraudebestendig zijn. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -283,7 +283,7 @@ Upgraden - Het uploaden is gepauzeerd, de telefoon wordt niet opgeladen + Upload paused, device is not charging Geen synchronisaties ingesteld @@ -307,7 +307,7 @@ Opgeloste problemen - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Omschrijving @@ -369,7 +369,7 @@ Upgraden naar Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Upgraden @@ -377,7 +377,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index c754466489..369a6d7b29 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -91,7 +91,7 @@ Nigdy więcej nie utrać danych - Przewiń do tyłu, aby przywrócić katalog z powrotem do dowolnej daty do 180 dni, aby Twoje dane były odporne na wypadki i manipulacje. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -299,7 +299,7 @@ Zmień - Przesyłanie wstrzymane, telefon się nie ładuje + Upload paused, device is not charging Brak ustawień synchronizacji @@ -323,7 +323,7 @@ Rozwiązane problemy - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Opis @@ -385,7 +385,7 @@ Zmień na wersję Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Zmień @@ -393,7 +393,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index a8d0a4c2c8..9e1bb5a7ed 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -91,7 +91,7 @@ Nunca mais perca dados - Use o Retroceder para restaurar as pastas para qualquer data até 180 dias, para que seus dados fiquem à prova de acidentes e adulteração. + Use a função Retroceder para restaurar arquivos e pastas a qualquer data (até 180 dias), e assim proteger os seus dados contra acidentes e infrações. MEGA VPN @@ -291,7 +291,7 @@ Upgrade - O upload foi pausado porque o telefone não está carregando + O upload foi pausado porque o dispositivo não está carregando Não há sincronizações configuradas @@ -315,7 +315,7 @@ Problemas solucionados - You can’t sync folders that are currently synced folders. + Não foi possível sincronizar esta pasta. Para sincronizar, use os Uploads da câmera. Descrição @@ -377,15 +377,19 @@ Fazer o upgrade a Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Libere o poder de sincronização do seu dispositivo móvel na nuvem com os nossos planos Pro. Upgrade Agora não - Uploads folder conflict + Conflito nas pastas de upload - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + A pasta dos Uploads da câmera e a pasta de upload secundário de mídia não podem estar relacionadas. Escolha uma pasta diferente. - Okay, got it + Entendi + + Este dispositivo não tem um aplicativo para selecionar pastas + + • Sincronização automática das pastas no seu dispositivo móvel \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 64615c287c..192d18691e 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -91,7 +91,7 @@ Nu pierdeți niciodată datele - Derulează înapoi pentru a restabili folderele la orice dată până la 180 de zile, astfel încât datele dvs. să fie protejate împotriva accidentelor și a manipulării. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -291,7 +291,7 @@ Upgradează - Încărcarea este întreruptă, deoarece telefonul nu se încarcă + Upload paused, device is not charging Nu este configurată nicio sincronizare @@ -315,7 +315,7 @@ Probleme rezolvate - You can’t sync folders that are currently synced folders. + Acest folder nu poate fi sincronizat. Configurați-l pentru a fi sincronizat cu MEGA folosind Încărcări cameră. Descriere @@ -377,15 +377,19 @@ Upgradează la Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. Upgradează Nu acum - Uploads folder conflict + Conflictul folderului încarcă - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Folderul Încărcări cameră și folderul încărcări media secundare nu pot fi legate între ele. Alegeți un folder diferit. - Okay, got it + Bine, am înțeles + + Acest dispozitiv nu are o aplicație care să selecteze foldere + + • Sincronizați automat folderele de pe dispozitivul mobil \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 92a5fa5148..1b0e4eae24 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -91,7 +91,7 @@ Данные больше не потеряются - Перемотка позволяет восстановить папки на любую дату за период до 180 дней, чтобы ваши данные были защищены от случайного повреждения и постороннего вмешательства. + Перемотка позволяет восстанавливать файлы и папки на любую дату за период до 180 дней, чтобы ваши данные были защищены от случайного повреждения и постороннего вмешательства. MEGA VPN @@ -299,7 +299,7 @@ Улучшить - Загрузка приостановлена, телефон не заряжается + Загрузка приостановлена, устройство не заряжается Синхронизация не настроена @@ -323,7 +323,7 @@ Решённые проблемы - You can’t sync folders that are currently synced folders. + Эту папку невозможно синхронизировать. Настройте её синхронизацию с MEGA с помощью загрузок из камеры. Описание @@ -385,15 +385,19 @@ Улучшение до Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Раскройте возможности синхронизации мобильного устройства с облаком с помощью наших планов Pro. Улучшить Не сейчас - Uploads folder conflict + Конфликт между папками загрузок - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Ваша папка загрузок из камеры и дополнительная папка для загрузки медиафайлов не могут быть связаны друг с другом. Выберите другую папку. - Okay, got it + Понятно + + На этом устройстве нет приложения для выбора папок + + • Автоматическая синхронизация папок на мобильном устройстве \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 716eae6085..682f4d1e69 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -91,7 +91,7 @@ ไม่มีพลาดทุกข้อมูลสำคัญของคุณ - ย้อนกลับโฟลเดอร์ไปยังวันที่ใดก็ได้ในช่วง 180 วันที่ผ่านมา ช่วยให้ข้อมูลของคุณปลอดภัยจากเหตุไม่คาดคิดและการแก้ไขโดยไม่ได้รับอนุญาต + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -275,7 +275,7 @@ อัปเกรด - การอัปโหลดถูกหยุดชั่วคราว เนื่องจากโทรศัพท์ไม่ได้เสียบชาร์จ + Upload paused, device is not charging ยังไม่ได้ตั้งค่าการซิงค์ @@ -299,7 +299,7 @@ แก้ไขปัญหาแล้ว - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. รายละเอียด @@ -361,7 +361,7 @@ อัปเกรดเป็น Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. อัปเกรด @@ -369,7 +369,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 012ebb9b71..095ccb7119 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -91,7 +91,7 @@ Không bao giờ mất dữ liệu nữa - Tua lại để khôi phục lại các thư mục về bất kỳ ngày nào trong phạm vi lên đến 180 ngày, vì vậy dữ liệu của bạn không bị tai nạn và chống giả mạo. + Tua lại để khôi phục lại các tệp tin và thư mục về bất kỳ ngày nào trong phạm vi lên đến 180 ngày, vì vậy dữ liệu của bạn không bị tai nạn và chống giả mạo. MEGA VPN @@ -275,7 +275,7 @@ Nâng cấp - Tải lên tạm dừng, điện thoại không có sạc + Tải lên tạm dừng, thiết bị không có sạc Không có đồng bộ nào đã lập @@ -299,7 +299,7 @@ Đã giải quyết - You can’t sync folders that are currently synced folders. + Không thể đồng bộ hóa thư mục này. Thiết lập thư mục này để đồng bộ hóa với MEGA bằng cách sử dụng Đăng tải camêra. Chi tiết @@ -361,15 +361,19 @@ Nâng cấp lên Pro - Unlock the power to sync your mobile to the cloud with our Pro plans. + Mở khóa sức mạnh để đồng bộ thiết bị di động của bạn lên đám mây với các gói Pro của chúng tôi. Nâng cấp Không phải lúc này - Uploads folder conflict + Xung đột thư mục tải lên - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Thư mục Đăng tải camêra và thư mục Đăng tải phương tiện phụ của bạn không thể liên kết với nhau. Hãy chọn một thư mục khác. - Okay, got it + OK, hiểu rồi + + Thiết bị này không có ứng dụng nào để chọn thư mục + + • Tự động đồng bộ các thư mục trên thiết bị di động của bạn \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 74ab2651f1..0ae908adf7 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -91,7 +91,7 @@ 再也不会丢失数据 - 还原可将文件夹恢复到最多180天以内的任何日期,这样您的数据就不会发生意外和防止篡改。 + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -275,7 +275,7 @@ 升级 - 上传已暂停,手机未在充电 + Upload paused, device is not charging 未设置同步 @@ -299,7 +299,7 @@ 已解决的问题 - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. 描述 @@ -361,7 +361,7 @@ 升级为Pro帐户 - Unlock the power to sync your mobile to the cloud with our Pro plans. + Unlock the power to sync your mobile device to the cloud with our Pro plans. 升级 @@ -369,7 +369,11 @@ Uploads folder conflict - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 4a45417437..fda0ef09fc 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -91,7 +91,7 @@ 再也不會遺失資料 - 回溯可將資料夾還原到最多180天的任何日期,因此您的資料不會發生意外及遭到竄改。 + 回溯可將檔案和資料夾還原到最多180天的任何日期,因此您的資料不會發生意外及遭到竄改。 MEGA VPN @@ -275,7 +275,7 @@ 升級 - 上傳已暫停,手機未在充電 + 上傳暫停,裝置未在充電 未設定同步 @@ -299,7 +299,7 @@ 已解決的問題 - You can’t sync folders that are currently synced folders. + 此資料夾無法同步。將其設定為使用相機上傳同步到MEGA。 說明 @@ -361,15 +361,19 @@ 升級為Pro會員 - 透過我們的Pro方案將您手機同步到雲端的功能解鎖。 + 透過我們的Pro方案將您行動裝置同步到雲端的功能解鎖。 升級 稍後再說 - Uploads folder conflict + 上傳資料夾衝突 - Your primary camera uploads folder and secondary media uploads folder cannot be related to each other. Please choose a different folder. + 您的相機上傳資料夾和次要媒體上傳資料夾不能相互關聯。選擇不同的資料夾。 - Okay, got it + 好的,明白了 + + 此裝置沒有可用於選擇資料夾的應用程式 + + • 自動同步行動裝置上的資料夾 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index f42d409c51..f4f31f397a 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -91,7 +91,7 @@ Never lose data again - Rewind to restore folders back to any date up to 180 days, so your data is accident and tamper-proof. + Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. MEGA VPN @@ -283,7 +283,7 @@ Upgrade - Upload paused, phone is not charging + Upload paused, device is not charging No syncs set up @@ -307,7 +307,7 @@ Solved issues - You can’t sync folders that are currently synced folders. + This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. Description @@ -366,4 +366,22 @@ Keep your information syncing and up to date by upgrading to one of our Pro plans. Upgrade now + + Upgrade to Pro + + Unlock the power to sync your mobile device to the cloud with our Pro plans. + + Upgrade + + Not now + + Uploads folder conflict + + Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + + Okay, got it + + This device doesn’t have an app to select folders + + • Automatically sync the folders on your mobile device \ No newline at end of file From d3c6d491a11a0fd1391ba0b1c1a01b992ed840af Mon Sep 17 00:00:00 2001 From: HM Tamim Date: Fri, 7 Jun 2024 21:53:03 +1200 Subject: [PATCH 151/261] AP-1438: AND - Crash when calling fetchAds() --- .../advertisements/AdsViewModel.kt | 11 +++-- .../advertisements/model/AdsUIState.kt | 2 +- .../data/repository/AdsRepositoryImpl.kt | 44 ++++++++----------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/advertisements/AdsViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/advertisements/AdsViewModel.kt index 8c761fe85f..ec0aa98518 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/advertisements/AdsViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/advertisements/AdsViewModel.kt @@ -159,14 +159,17 @@ class AdsViewModel @Inject constructor( slotId: String = uiState.value.slotId, linkHandle: Long? = null, ) { + // Do not fetch ads if the job is already running, to avoid repeated SDK calls + if (fetchAdUrlJob?.isActive == true) return + if (isAdsFeatureEnabled && canConsumeAdSlot(slotId)) { val fetchAdDetailRequest = FetchAdDetailRequest(slotId, linkHandle) fetchAdUrlJob?.cancel() fetchAdUrlJob = viewModelScope.launch { runCatching { val url = fetchAdDetailUseCase(fetchAdDetailRequest)?.url - _uiState.update { state -> - state.copy( + _uiState.update { + it.copy( showAdsView = url != null && isPortrait && canConsumeAdSlot(slotId), slotId = slotId, adsBannerUrl = url.orEmpty() @@ -177,8 +180,8 @@ class AdsViewModel @Inject constructor( } } } else { - _uiState.update { state -> - state.copy(showAdsView = false, slotId = slotId, adsBannerUrl = "") + _uiState.update { + it.copy(showAdsView = false, slotId = slotId, adsBannerUrl = "") } } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/advertisements/model/AdsUIState.kt b/app/src/main/java/mega/privacy/android/app/presentation/advertisements/model/AdsUIState.kt index 07db42eea0..2b096252aa 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/advertisements/model/AdsUIState.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/advertisements/model/AdsUIState.kt @@ -1,7 +1,7 @@ package mega.privacy.android.app.presentation.advertisements.model /** - * UI state for the [AdsBannerView] + * UI state for the [AdsViewModel] * @param showAdsView UI state to change the visibility of the Ad view * @param slotId The slot ID of the currently displayed Ad in the Ads view * @param adsBannerUrl the url used to load the Ad webview banner diff --git a/data/src/main/java/mega/privacy/android/data/repository/AdsRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/AdsRepositoryImpl.kt index 971d2cc75a..1107f9bb67 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/AdsRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/AdsRepositoryImpl.kt @@ -3,17 +3,15 @@ package mega.privacy.android.data.repository import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext -import mega.privacy.android.data.extensions.failWithError +import mega.privacy.android.data.extensions.getRequestListener import mega.privacy.android.data.gateway.AdsGateway import mega.privacy.android.data.gateway.api.MegaApiGateway -import mega.privacy.android.data.listener.OptionalMegaRequestListenerInterface import mega.privacy.android.data.mapper.MegaStringListMapper import mega.privacy.android.data.mapper.advertisements.AdDetailsMapper import mega.privacy.android.domain.entity.advertisements.AdDetails import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.repository.AdsRepository import nz.mega.sdk.MegaApiJava -import nz.mega.sdk.MegaError import javax.inject.Inject /** @@ -26,32 +24,26 @@ internal class AdsRepositoryImpl @Inject constructor( private val adDetailsMapper: AdDetailsMapper, private val megaStringListMapper: MegaStringListMapper, ) : AdsRepository { + override suspend fun fetchAdDetails( adSlots: List, linkHandle: Long?, - ): List = - withContext(ioDispatcher) { - suspendCancellableCoroutine { continuation -> - val listener = OptionalMegaRequestListenerInterface( - onRequestFinish = { request, error -> - if (error.errorCode == MegaError.API_OK) { - continuation.resumeWith(Result.success(adDetailsMapper(request.megaStringMap))) - } else { - continuation.failWithError(error, "fetchAds") - } - } - ) - megaStringListMapper(adSlots)?.let { - adsGateway.fetchAds( - adFlags = MegaApiJava.ADS_DEFAULT, - adUnits = it, - publicHandle = linkHandle ?: MegaApiJava.INVALID_HANDLE, - listener = listener - ) - } - continuation.invokeOnCancellation { - megaApiGateway.removeRequestListener(listener) - } + ): List = withContext(ioDispatcher) { + val adUnits = megaStringListMapper(adSlots) + requireNotNull(adUnits) { "MegaStringListProvider is null, unable to get map adUnits" } + suspendCancellableCoroutine { continuation -> + val listener = continuation.getRequestListener("fetchAds") { request -> + adDetailsMapper(request.megaStringMap) + } + continuation.invokeOnCancellation { + megaApiGateway.removeRequestListener(listener) } + adsGateway.fetchAds( + adFlags = MegaApiJava.ADS_DEFAULT, + adUnits = adUnits, + publicHandle = linkHandle ?: MegaApiJava.INVALID_HANDLE, + listener = listener + ) } + } } \ No newline at end of file From 0d18fe9a21fab7782416f83ca8aed93ac9cfa124 Mon Sep 17 00:00:00 2001 From: Yenel Date: Fri, 7 Jun 2024 12:07:03 +0200 Subject: [PATCH 152/261] Update strings --- app/src/main/res/values-ro/strings.xml | 16 ++++++++-------- .../src/main/res/values-ar/strings_shared.xml | 8 ++++++++ .../src/main/res/values-de/strings_shared.xml | 8 ++++++++ .../src/main/res/values-es/strings_shared.xml | 8 ++++++++ .../src/main/res/values-fr/strings_shared.xml | 8 ++++++++ .../src/main/res/values-in/strings_shared.xml | 8 ++++++++ .../src/main/res/values-it/strings_shared.xml | 8 ++++++++ .../src/main/res/values-ja/strings_shared.xml | 8 ++++++++ .../src/main/res/values-ko/strings_shared.xml | 8 ++++++++ .../src/main/res/values-nl/strings_shared.xml | 8 ++++++++ .../src/main/res/values-pt/strings_shared.xml | 8 ++++++++ .../src/main/res/values-ro/strings_shared.xml | 14 +++++++++++--- .../src/main/res/values-ru/strings_shared.xml | 8 ++++++++ .../src/main/res/values-th/strings_shared.xml | 8 ++++++++ .../src/main/res/values-vi/strings_shared.xml | 8 ++++++++ .../main/res/values-zh-rCN/strings_shared.xml | 8 ++++++++ .../main/res/values-zh-rTW/strings_shared.xml | 8 ++++++++ 17 files changed, 139 insertions(+), 11 deletions(-) diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 850e0c71ea..91265175fb 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -2125,7 +2125,7 @@ Rotația cheii de criptare, activată - Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele din trecut. + Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele anterioare. Rotația cheii criptate este dezactivată pentru conversațiile cu mai mult de 100 de participanți. @@ -2161,9 +2161,9 @@ Rotația cheii de criptare - Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele din trecut. + Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele anterioare. - Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele din trecut. + Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele anterioare. Invitația către contactul %s a fost trimisă înainte și poate fi consultată în fila Cereri trimise. @@ -2527,7 +2527,7 @@ Vrei să creezi un nou chat de grup și să obții un link al chatului? - Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele din trecut. + Rotația cheii de criptare este puțin mai sigură, dar nu îți permite să creezi un link al chatului, iar noii participanți nu vor vedea mesajele anterioare. %1$d din %2$d @@ -3891,7 +3891,7 @@ Albume partajate - Întâlniri din trecut + Întâlniri anterioare Întâlnire viitoare @@ -5103,7 +5103,7 @@ Această întâlnire va fi arhivată și toți participanții vor fi anunțați. - Această întâlnire va fi plasată în cadrul Întâlnirilor din trecut și toți participanții vor fi anunțați. + Această întâlnire va fi plasată în cadrul Întâlniri anterioare și toți participanții vor fi anunțați. Nu o anula @@ -5123,7 +5123,7 @@ Aceasta este singura ocurență a întâlnirii recurente. Anularea acestei ocurențe va anula întâlnirea.\nDacă este anulată, întâlnirea va fi arhivată și toți participanții vor fi anunțați. - Aceasta este singura ocurență a întâlnirii recurente. Anularea acestei ocurențe va anula întâlnirea. \nDacă este anulată, întâlnirea va fi plasată sub Întâlniri din trecut și toți participanții vor fi anunțați. + Aceasta este singura ocurență a întâlnirii recurente. Anularea acestei ocurențe va anula întâlnirea. \nDacă este anulată, întâlnirea va fi plasată sub Întâlniri anterioare și toți participanții vor fi anunțați. Ocurență din %1$s a fost anulat @@ -5133,7 +5133,7 @@ Această întâlnire și toate ocurențe sale vor fi arhivate și toți participanții vor fi anunțați. - Această întâlnire și toate ocurențele sale vor fi plasate în Întâlniri din trecut și toți participanții vor fi anunțați. + Această întâlnire și toate ocurențele sale vor fi plasate în Întâlniri anterioare și toți participanții vor fi anunțați. Acum puteți programa întâlniri unice și recurente. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 11f141271c..73d0c7b50c 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -416,4 +416,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + موافق + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + عناصر مخفية \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 8ebc4b97c6..9648fc62b7 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -384,4 +384,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + OK + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Verborgene Elemente \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index b39f29ec98..99207aab9a 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -392,4 +392,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + Aceptar + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Elementos ocultos \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 811b06d736..4538d6dcc4 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -392,4 +392,12 @@ Aucune appli n’est installée sur cet appareil pour sélectionner les dossiers • Synchronisez automatiquement les dossiers de votre appareil mobile + + Vos synchronisations ont été interrompues. La synchronisation est une fonction des abonnements Pro. + + Valider + + La synchronisation est interrompue, car votre abonnement MEGA Pro a été annulé. Pour que la synchronisation reprenne, surclassez votre compte. + + Éléments cachés \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index ec277a40b9..78f3260331 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -380,4 +380,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + Ok + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Item tersembunyi \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index f2f071f78d..e9dd738138 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -392,4 +392,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + Ok + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Oggetti nascosti \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 3341ec933f..fd22b853c4 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -376,4 +376,12 @@ この端末には、フォルダを選択するアプリがありません • モバイルデバイス上のフォルダを自動的に同期します + + 同期が一時停止されました。同期はProプランの機能です。 + + OK + + MEGA Proプランをキャンセルされたため、同期が一時停止されています。アップグレードしていただくと、同期を継続できます。 + + 非表示項目 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 7d68c140e4..330cfaab19 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -376,4 +376,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + Ok + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + 숨겨진 항목 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 56b4d1fd0c..d397bd4b90 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -384,4 +384,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + OK + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Verborgen items \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 9e1bb5a7ed..bb9998dce5 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -392,4 +392,12 @@ Este dispositivo não tem um aplicativo para selecionar pastas • Sincronização automática das pastas no seu dispositivo móvel + + As suas sincronizações foram pausadas: sincronizar é um recurso dos planos Pro. + + Ok + + A sincronização foi pausada porque o seu plano Pro do MEGA foi cancelado. Faça upgrade para continuar sincronizando. + + Itens ocultos \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 192d18691e..210689651f 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -91,7 +91,7 @@ Nu pierdeți niciodată datele - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + Derulați înapoi pentru a restabili fișierele și folderele la orice dată de până la 180 de zile, astfel încât datele dvs. să fie protejate împotriva accidentelor și a manipulării. MEGA VPN @@ -291,7 +291,7 @@ Upgradează - Upload paused, device is not charging + Încărcarea este întreruptă, deoarece dispozitivul nu se încarcă Nu este configurată nicio sincronizare @@ -377,7 +377,7 @@ Upgradează la Pro - Unlock the power to sync your mobile device to the cloud with our Pro plans. + Abonamentele noastre Pro dezlănțuie puterea de sincronizare a dispozitivului dvs. mobil cu MEGA. Upgradează @@ -392,4 +392,12 @@ Acest dispozitiv nu are o aplicație care să selecteze foldere • Sincronizați automat folderele de pe dispozitivul mobil + + Sincronizările dvs. au fost întrerupte. Sincronizarea este o funcție a abonamentelor Pro. + + Bine + + Sincronizarea este întreruptă deoarece abonamentul MEGA Pro a fost anulat. Upgradați pentru a continua sincronizarea. + + Elemente ascunse \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 1b0e4eae24..d99b519343 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -400,4 +400,12 @@ На этом устройстве нет приложения для выбора папок • Автоматическая синхронизация папок на мобильном устройстве + + Синхронизация приостановлена. Синхронизация доступна на плане Pro. + + Ok + + Синхронизация приостановлена, так как ваша подписка на план MEGA Pro была отменена. Оформите подписку, чтобы продолжить синхронизацию. + + Скрытые элементы \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 682f4d1e69..ddd314029b 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -376,4 +376,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + ตกลง + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + รายการที่ถูกซ่อน \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 095ccb7119..b00e566578 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -376,4 +376,12 @@ Thiết bị này không có ứng dụng nào để chọn thư mục • Tự động đồng bộ các thư mục trên thiết bị di động của bạn + + Your syncs have been paused. Syncing is a Pro plan feature. + + Ok + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + Các mục ẩn \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 0ae908adf7..81b7e85afa 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -376,4 +376,12 @@ This device doesn’t have an app to select folders • Automatically sync the folders on your mobile device + + Your syncs have been paused. Syncing is a Pro plan feature. + + Ok + + Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + + 隐藏的项目 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index fda0ef09fc..45f80185ca 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -376,4 +376,12 @@ 此裝置沒有可用於選擇資料夾的應用程式 • 自動同步行動裝置上的資料夾 + + 您的同步已暫停。同步是Pro方案的功能。 + + 確認 + + 由於您的MEGA Pro方案已取消,因此同步暫停。升級以繼續同步。 + + 隱藏的項目 \ No newline at end of file From 5ce48de3fa880c29d003686e4e2e53d188e17852 Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Fri, 14 Jun 2024 11:52:52 +0800 Subject: [PATCH 153/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 4e3df01aac..fa278a3f25 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -72,7 +72,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240613.110049" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 4f63124b0c7af8eb14ac1e28687602bdfebfa6b8 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 17 Jun 2024 08:39:38 +0800 Subject: [PATCH 154/261] CC-7160: T16601495&T16601579 - The app got crash when playing mp3 file --- .../mediaplayer/service/AudioPlayerService.kt | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerService.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerService.kt index 52d6703e3b..ff5e6a7ff6 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerService.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerService.kt @@ -161,14 +161,6 @@ class AudioPlayerService : LifecycleService(), LifecycleEventObserver, MediaPlay super.onCreate() audioManager = (getSystemService(AUDIO_SERVICE) as AudioManager) audioFocusRequest = getRequest(audioFocusListener, AUDIOFOCUS_DEFAULT) - - startForegroundByVersion( - PLAYBACK_NOTIFICATION_ID, - NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_AUDIO_PLAYER_ID).build() - ).apply { - crashReporter.log("StartForeground is invoked") - } - createPlayer() if (!isNotificationCreated) { createPlayerControlNotification() @@ -180,29 +172,6 @@ class AudioPlayerService : LifecycleService(), LifecycleEventObserver, MediaPlay registerReceiver(headsetPlugReceiver, IntentFilter(Intent.ACTION_HEADSET_PLUG)) } - private fun startForegroundByVersion(notificationId: Int, notification: Notification) { - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - startForeground( - notificationId, notification, - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK - } else { - 0 - }, - ) - } else { - startForeground(notificationId, notification) - } - } catch (e: Exception) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S - && e is ForegroundServiceStartNotAllowedException - ) { - Timber.e("App not in a valid state to start foreground service: ${e.message}") - } - } - } - private fun createPlayer() { with(viewModelGateway) { val nameChangeCallback: (title: String?, artist: String?, album: String?) -> Unit = @@ -302,7 +271,26 @@ class AudioPlayerService : LifecycleService(), LifecycleEventObserver, MediaPlay onNotificationPostedCallback = { notificationId, notification, ongoing -> if (ongoing && isForeground) { // Make sure the service will not get destroyed while playing media. - startForegroundByVersion(notificationId, notification) + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + startForeground( + notificationId, notification, + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK + } else { + 0 + }, + ) + } else { + startForeground(notificationId, notification) + } + } catch (e: Exception) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + && e is ForegroundServiceStartNotAllowedException + ) { + Timber.e("App not in a valid state to start foreground service: ${e.message}") + } + } currentNotification = notification } else { // Make notification cancellable. From ea23da2d598e0207d7e297d534205f90dc3ccdea Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Mon, 17 Jun 2024 12:02:52 +1200 Subject: [PATCH 155/261] AP-389 Fix failed test-cases --- .../view/VariantAOnboardingDialogView.kt | 1 + .../view/VariantBOnboardingDialogView.kt | 1 + .../app/upgradeAccount/view/components/FeatureRow.kt | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantAOnboardingDialogView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantAOnboardingDialogView.kt index 8c77229c47..a930444522 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantAOnboardingDialogView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantAOnboardingDialogView.kt @@ -112,6 +112,7 @@ fun VariantAOnboardingDialogView( ), testTag = ADDITIONAL_FEATURES_DESCRIPTION_ROW, isLoading = isLoading, + isBulletPointListUsed = true, ) Spacer(modifier = Modifier.height(18.dp)) ButtonsRow( diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantBOnboardingDialogView.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantBOnboardingDialogView.kt index 4bf0f59cb8..c91219a612 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantBOnboardingDialogView.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/VariantBOnboardingDialogView.kt @@ -172,6 +172,7 @@ internal fun VariantBOnboardingDialogColumn( ), testTag = ADDITIONAL_FEATURES_DESCRIPTION_ROW, isLoading = isLoading, + isBulletPointListUsed = true, ) } } diff --git a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/components/FeatureRow.kt b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/components/FeatureRow.kt index ade74b15d0..88697271fb 100644 --- a/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/components/FeatureRow.kt +++ b/app/src/main/java/mega/privacy/android/app/upgradeAccount/view/components/FeatureRow.kt @@ -16,7 +16,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextIndent import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.google.accompanist.placeholder.PlaceholderHighlight import com.google.accompanist.placeholder.fade import com.google.accompanist.placeholder.placeholder @@ -40,6 +43,7 @@ internal fun FeatureRow( description: String, testTag: String, isLoading: Boolean = false, + isBulletPointListUsed: Boolean = false, ) { Row( modifier = Modifier @@ -78,10 +82,13 @@ internal fun FeatureRow( MegaText( text = description, textColor = TextColor.Secondary, - style = MaterialTheme.typography.subtitle2, + style = MaterialTheme.typography.subtitle2.copy(textIndent = TextIndent(restLine = if (isBulletPointListUsed) 8.sp else 0.sp)), modifier = Modifier .testTag("$testTag:description") - .padding(top = 2.dp) + .padding( + start = if (isBulletPointListUsed) 4.dp else 0.dp, + top = 2.dp + ) .placeholder( color = MaterialTheme.colors.grey_020_grey_900, shape = RoundedCornerShape(4.dp), From 56f38c08b41971415d6b49f645590610f76c1edf Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Tue, 18 Jun 2024 12:27:14 +0800 Subject: [PATCH 156/261] Update strings --- app/src/main/res/values-es/strings.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 30 +++++++++---------- .../src/main/res/values-de/strings_shared.xml | 2 +- .../src/main/res/values-es/strings_shared.xml | 2 +- .../src/main/res/values-fr/strings_shared.xml | 2 +- .../src/main/res/values-in/strings_shared.xml | 2 +- .../src/main/res/values-it/strings_shared.xml | 2 +- .../src/main/res/values-ja/strings_shared.xml | 12 ++++---- .../src/main/res/values-ko/strings_shared.xml | 2 +- .../src/main/res/values-nl/strings_shared.xml | 2 +- .../src/main/res/values-pl/strings_shared.xml | 2 +- .../src/main/res/values-pt/strings_shared.xml | 2 +- .../src/main/res/values-ro/strings_shared.xml | 2 +- .../src/main/res/values-ru/strings_shared.xml | 2 +- .../src/main/res/values-th/strings_shared.xml | 2 +- .../src/main/res/values-vi/strings_shared.xml | 2 +- .../main/res/values-zh-rCN/strings_shared.xml | 2 +- .../main/res/values-zh-rTW/strings_shared.xml | 2 +- .../src/main/res/values/strings_shared.xml | 2 +- 19 files changed, 38 insertions(+), 38 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 0095e6ce8f..b1a837693f 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5573,7 +5573,7 @@ %1$s y otros %2$d han levantado la mano - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Hay elementos ocultos en este álbum. Si compartes el álbum, los elementos ocultos estarán visibles para las personas con las que lo compartas. Los elementos seguirán ocultos en tu Nube. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 3dda3d4f27..9661a546fe 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -91,7 +91,7 @@ لا تفقد البيانات مرة أخرى - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + يمكنك الترجيع لاستعادة الملفات والمجلدات مرة أخرى إلى أي تاريخ يصل إلى 180 يومًا حتى تكون بياناتك مقاومة للحوادث والعبث. MEGA VPN @@ -315,7 +315,7 @@ ترقية - Upload paused, device is not charging + تم إيقاف الترفيع مؤقتًا الجهاز لا يشحن لم يتم إعداد عمليات المزامنة @@ -339,7 +339,7 @@ المشكلات التي تم حلها - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + لا يمكن مزامنة هذا المجلد. قم بإعداده للمزامنة مع ميغا MEGA باستخدام ترفيعات الكاميرا. الوصف @@ -401,27 +401,27 @@ قم بالترقية إلى برو Pro - Unlock the power to sync your mobile device to the cloud with our Pro plans. + أطلق العنان للطاقة لمزامنة جهازك المحمول مع السحابة من خلال باقات برو Pro الخاصة بنا. ترقية ليس الآن - Uploads folder conflict + تعارض مجلد الترفيعات - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + لا يمكن ربط مجلد ترفيعات الكاميرا ومجلد ترفيعات الوسائط الثانوية ببعضهما البعض. اختر مجلدًا مختلفًا. - Okay, got it + حسناً، فهمت ذلك - This device doesn’t have an app to select folders + لا يحتوي هذا الجهاز على تطبيق لتحديد المجلدات - • Automatically sync the folders on your mobile device + • قم بمزامنة المجلدات تلقائيًا على هاتفك المحمول - Your syncs have been paused. Syncing is a Pro plan feature. + تم إيقاف عمليات المزامنة الخاصة بك مؤقتًا. المزامنة هي إحدى ميزات باقة برو Pro. موافق - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + تم إيقاف المزامنة مؤقتًا بسبب إلغاء باقة ميغا برو MEGA Pro الخاصة بك. قم بالترقية لمتابعة المزامنة. عناصر مخفية @@ -429,11 +429,11 @@ الوسمات - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + استخدم العلامات لمساعدتك في العثور على بياناتك وتنظيمها. حاول وضع العلامات حسب السنة أو الموقع أو المشروع أو الموضوع. - Tag + تاغ Tag - Add “#%1$s” tag + أضف تاغ Tag «#%1$s» Existing tags @@ -457,7 +457,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. ميزة diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 39f8936005..2875e83dd4 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -425,7 +425,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Funktion diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 9acc5c4c10..8d647a24a0 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -433,7 +433,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Característica diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 183b2e5faa..bb0d495ab9 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -433,7 +433,7 @@ Vous y aurez toujours accès jusqu’à l’expiration de votre abonnement MEGA, après quoi vous passerez à un compte gratuit. - Vous utilisez actuellement %1s d’espace de stockage, vous risquez de perdre vos fichiers + You are currently using %1s of storage, which you will risk losing. Caractéristique diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 294aa20918..65c6c821bd 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -420,7 +420,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Fitur diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index a70a35a89c..b184f217ae 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -433,7 +433,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Categoria diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index b8ccb416b1..37291ca5a1 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -415,13 +415,13 @@ これらの機能をご利用いただけなくなります - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + MEGAプランの有効期限が切れるまでは、引き続きこれらの機能をご利用いただけます。有効期限が切れると、無料アカウントに移行します。 - You currently are using %1s of storage, you will be at risk of losing your files + 現在%1sのストレージをご利用中です。しかし、それが失われる危険性があります。 機能 - Free + 無料 ストレージ @@ -445,19 +445,19 @@ MEGA VPN - Call &amp; meeting duration + 通話とミーティング時間 最大1時間 無制限 - Call &amp; meeting participants + 通話とミーティングの参加者 最大100人 無制限 - Keep %1s + %1sを維持する キャンセルを続ける \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index cd5cd33c9d..c97673ea02 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -417,7 +417,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. 기능 diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 83fb53c4b2..64bbb52052 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -425,7 +425,7 @@ U heeft nog steeds toegang tot deze kenmerken tot uw MEGA-abonnement afloopt, dan word u overgezet naar een gratis account. - U gebruikt momenteel %1s van de opslag en loopt het risico uw bestanden kwijt te raken + U gebruikt momenteel %1s van de opslag, welke u het risico loopt te verliezen. Functie diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index e8dfb531ff..8c862ba59c 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -441,7 +441,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Funkcja diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 03f8adc965..32a46d07c9 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -433,7 +433,7 @@ Você vai continuar tendo acesso aos recursos até o seu plano do MEGA expirar, e então a sua conta passará a ser gratuita. - No momento, você está usando %1s de armazenamento, e portanto corre o risco de perder os seus arquivos + No momento, você está usando %1s de armazenamento, que você corre o risco de perder. Recurso diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 861e43ec4f..93d2f91202 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -433,7 +433,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Caracteristică diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 32d0624919..85efdb4f50 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -441,7 +441,7 @@ Эти функции будут доступны, пока не истечёт срок действия подписки MEGA, после чего вы будете переведены на бесплатный план. - В настоящее время используется %1s хранилища, вы рискуете потерять свои файлы + В настоящее время вы используете %1s дискового пространства, которое рискуете потерять. Особенность diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index d4f00ea580..10d96caf53 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -417,7 +417,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. ฟีเจอร์ diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 531c7fa1be..d535318deb 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -417,7 +417,7 @@ Bạn vẫn có quyền truy cập vào các tính năng này cho đến khi gói MEGA của bạn hết hạn, sau đó bạn sẽ chuyển sang tài khoản miễn phí. - You currently are using %1s of storage, you will be at risk of losing your files + Bạn hiện đang sử dụng %1s không gian lưu trữ, bạn sẽ có nguy cơ mất dữ liệu của mình. Tính năng diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index a5bb102359..c0bb6cd4e9 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -417,7 +417,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. 功能 diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 6f27199ddf..1190c8089e 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -417,7 +417,7 @@ 在您的MEGA方案到期之前,您仍然可以使用這些功能,然後您將被轉移到免費帳戶。 - 您目前使用%1s儲存空間,您將面臨遺失檔案的風險 + 您目前使用%1s儲存空間,您將面臨檔案遺失的風險。 功能 diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 5e5303ee8b..f416405074 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -425,7 +425,7 @@ You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. - You currently are using %1s of storage, you will be at risk of losing your files + You are currently using %1s of storage, which you will risk losing. Feature From 8b5861ad020ec3e60f6d1258a32e21430d43c1b0 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Mon, 17 Jun 2024 13:21:14 +0200 Subject: [PATCH 157/261] AND-18886: Replace default Switch with the one following our design system --- .../trackinfo/AudioTrackInfoView.kt | 4 +-- .../view/ParticipantsBottomPanelView.kt | 32 +++++------------ .../meeting/view/ScheduledMeetingInfoView.kt | 36 ++++++------------- .../photos/timeline/view/EnableCU.kt | 31 ++-------------- .../settings/calls/SettingsCallsView.kt | 26 ++++---------- .../controls/lists/MenuActionListTileTest.kt | 4 +-- 6 files changed, 34 insertions(+), 99 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/trackinfo/AudioTrackInfoView.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/trackinfo/AudioTrackInfoView.kt index 27608dc6db..052a31e6ff 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/trackinfo/AudioTrackInfoView.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/trackinfo/AudioTrackInfoView.kt @@ -17,7 +17,6 @@ import androidx.compose.foundation.selection.toggleable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.Divider -import androidx.compose.material.Switch import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -45,6 +44,7 @@ import mega.privacy.android.app.mediaplayer.trackinfo.Constants.AUDIO_TITLE_TEST import mega.privacy.android.app.mediaplayer.trackinfo.Constants.OFFLINE_OPTION_TEST_TAG import mega.privacy.android.app.utils.LocationInfo import mega.privacy.android.app.utils.TimeUtils.formatLongDateTime +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch import mega.privacy.android.shared.original.core.ui.preview.CombinedThemePreviews import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import java.io.File @@ -219,7 +219,7 @@ fun AudioNodeInfoView( color = colorResource(R.color.grey_087_white) ) - Switch( + MegaSwitch( checked = isEnabled ?: false, onCheckedChange = null, modifier = Modifier diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsBottomPanelView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsBottomPanelView.kt index 9d6abb1749..91a737a4e5 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsBottomPanelView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsBottomPanelView.kt @@ -22,8 +22,6 @@ import androidx.compose.material.SnackbarDuration import androidx.compose.material.SnackbarHost import androidx.compose.material.SnackbarHostState import androidx.compose.material.SnackbarResult -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -36,7 +34,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource @@ -56,21 +53,22 @@ import mega.privacy.android.app.meeting.activity.MeetingActivityViewModel import mega.privacy.android.app.presentation.meeting.WaitingRoomManagementViewModel import mega.privacy.android.app.presentation.meeting.model.MeetingState import mega.privacy.android.app.presentation.meeting.model.WaitingRoomManagementState -import mega.privacy.android.shared.original.core.ui.controls.buttons.RaisedDefaultMegaButton -import mega.privacy.android.shared.original.core.ui.controls.buttons.TextMegaButton -import mega.privacy.android.shared.original.core.ui.theme.extensions.black_white -import mega.privacy.android.shared.original.core.ui.theme.extensions.grey_200_grey_700 -import mega.privacy.android.shared.original.core.ui.theme.extensions.teal_300_teal_200 -import mega.privacy.android.shared.original.core.ui.theme.extensions.textColorPrimary -import mega.privacy.android.shared.original.core.ui.utils.isScreenOrientationLandscape import mega.privacy.android.domain.entity.ChatRoomPermission import mega.privacy.android.domain.entity.chat.ChatParticipant import mega.privacy.android.domain.entity.contacts.ContactData import mega.privacy.android.domain.entity.meeting.CallType import mega.privacy.android.domain.entity.meeting.ParticipantsSection import mega.privacy.android.legacy.core.ui.controls.chips.CallTextButtonChip +import mega.privacy.android.shared.original.core.ui.controls.buttons.RaisedDefaultMegaButton +import mega.privacy.android.shared.original.core.ui.controls.buttons.TextMegaButton +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch import mega.privacy.android.shared.original.core.ui.controls.snackbars.MegaSnackbar import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme +import mega.privacy.android.shared.original.core.ui.theme.extensions.black_white +import mega.privacy.android.shared.original.core.ui.theme.extensions.grey_200_grey_700 +import mega.privacy.android.shared.original.core.ui.theme.extensions.teal_300_teal_200 +import mega.privacy.android.shared.original.core.ui.theme.extensions.textColorPrimary +import mega.privacy.android.shared.original.core.ui.utils.isScreenOrientationLandscape import mega.privacy.mobile.analytics.event.ScheduledMeetingShareMeetingLinkButtonEvent /** @@ -297,12 +295,11 @@ fun BottomPanelView( Box( modifier = Modifier.wrapContentSize(Alignment.CenterEnd) ) { - Switch( + MegaSwitch( modifier = Modifier.align(Alignment.Center), checked = enabledAllowNonHostAddParticipantsOption, enabled = isAllowNonHostAddParticipantEnabled, onCheckedChange = null, - colors = switchColors() ) } } @@ -581,17 +578,6 @@ private fun EmptyState(section: ParticipantsSection) { } } -/** - * Control the colours of the switch depending on the status - */ -@Composable -private fun switchColors() = SwitchDefaults.colors( - checkedThumbColor = colorResource(id = R.color.teal_300_teal_200), - checkedTrackColor = colorResource(id = R.color.teal_100_teal_200_038), - uncheckedThumbColor = colorResource(id = R.color.grey_020_grey_100), - uncheckedTrackColor = colorResource(id = R.color.grey_700_grey_050_038), -) - /** * See all participants in the list button view * diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ScheduledMeetingInfoView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ScheduledMeetingInfoView.kt index 86abf6b6e7..0517305701 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ScheduledMeetingInfoView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ScheduledMeetingInfoView.kt @@ -30,8 +30,6 @@ import androidx.compose.material.Scaffold import androidx.compose.material.Snackbar import androidx.compose.material.SnackbarHost import androidx.compose.material.SnackbarHostState -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons @@ -49,7 +47,6 @@ import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag -import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource @@ -78,7 +75,16 @@ import mega.privacy.android.app.presentation.meeting.model.ScheduledMeetingManag import mega.privacy.android.app.presentation.meeting.view.dialog.DenyEntryToCallDialog import mega.privacy.android.app.presentation.meeting.view.dialog.UsersInWaitingRoomDialog import mega.privacy.android.app.presentation.meeting.view.dialog.WaitingRoomWarningDialog +import mega.privacy.android.domain.entity.ChatRoomPermission +import mega.privacy.android.domain.entity.chat.ChatParticipant +import mega.privacy.android.domain.entity.chat.ChatScheduledMeeting +import mega.privacy.android.domain.entity.contacts.UserChatStatus +import mega.privacy.android.domain.entity.meeting.WaitingRoomReminders +import mega.privacy.android.legacy.core.ui.controls.divider.CustomDivider +import mega.privacy.android.legacy.core.ui.controls.text.MarqueeText +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch import mega.privacy.android.shared.original.core.ui.controls.dialogs.ConfirmationDialog +import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import mega.privacy.android.shared.original.core.ui.theme.black import mega.privacy.android.shared.original.core.ui.theme.grey_alpha_012 import mega.privacy.android.shared.original.core.ui.theme.grey_alpha_038 @@ -89,14 +95,6 @@ import mega.privacy.android.shared.original.core.ui.theme.white import mega.privacy.android.shared.original.core.ui.theme.white_alpha_012 import mega.privacy.android.shared.original.core.ui.theme.white_alpha_038 import mega.privacy.android.shared.original.core.ui.theme.white_alpha_054 -import mega.privacy.android.domain.entity.ChatRoomPermission -import mega.privacy.android.domain.entity.chat.ChatParticipant -import mega.privacy.android.domain.entity.chat.ChatScheduledMeeting -import mega.privacy.android.domain.entity.contacts.UserChatStatus -import mega.privacy.android.domain.entity.meeting.WaitingRoomReminders -import mega.privacy.android.legacy.core.ui.controls.divider.CustomDivider -import mega.privacy.android.legacy.core.ui.controls.text.MarqueeText -import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import java.text.SimpleDateFormat import java.util.Calendar import java.util.Locale @@ -952,14 +950,13 @@ private fun ActionOption( Box( modifier = Modifier .wrapContentSize(Alignment.CenterEnd) - .size(40.dp) + .height(40.dp) ) { - Switch( + MegaSwitch( modifier = Modifier.align(Alignment.Center), checked = isChecked, enabled = isEnabled, onCheckedChange = null, - colors = switchColors() ) } @@ -981,17 +978,6 @@ private fun ActionSubtitleText(text: String) { color = grey_alpha_054.takeIf { isLight() } ?: white_alpha_054) } -/** - * Control the colours of the switch depending on the status - */ -@Composable -private fun switchColors() = SwitchDefaults.colors( - checkedThumbColor = colorResource(id = R.color.teal_300_teal_200), - checkedTrackColor = colorResource(id = R.color.teal_100_teal_200_038), - uncheckedThumbColor = colorResource(id = R.color.grey_020_grey_100), - uncheckedTrackColor = colorResource(id = R.color.grey_700_grey_050_038), -) - /** * Text of the available options * diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/EnableCU.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/EnableCU.kt index 2e8db6e116..98b0618ce7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/EnableCU.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/timeline/view/EnableCU.kt @@ -22,8 +22,6 @@ import androidx.compose.material.Card import androidx.compose.material.Divider import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -41,6 +39,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mega.privacy.android.app.R import mega.privacy.android.app.presentation.photos.timeline.model.TimelineViewState +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import mega.privacy.android.shared.original.core.ui.theme.black import mega.privacy.android.shared.original.core.ui.theme.dark_grey @@ -124,21 +123,9 @@ fun EnableCU( color = colorResource(id = R.color.grey_087_white_087), fontSize = 18.sp, ) - Switch( + MegaSwitch( checked = timelineViewState.cuUploadsVideos, onCheckedChange = onUploadVideosChanged, - colors = if (MaterialTheme.colors.isLight) { - SwitchDefaults.colors( - checkedThumbColor = colorResource(id = R.color.teal_300), - checkedTrackColor = colorResource(id = R.color.teal_100), - uncheckedThumbColor = colorResource(id = R.color.grey_010), - uncheckedTrackColor = colorResource(id = R.color.grey_alpha_038), - ) - } else { - SwitchDefaults.colors( - uncheckedThumbColor = colorResource(id = R.color.grey_200), - ) - } ) } @@ -159,21 +146,9 @@ fun EnableCU( color = colorResource(id = R.color.grey_087_white_087), fontSize = 18.sp, ) - Switch( + MegaSwitch( checked = timelineViewState.cuUseCellularConnection, onCheckedChange = onUseCellularConnectionChanged, - colors = if (MaterialTheme.colors.isLight) { - SwitchDefaults.colors( - checkedThumbColor = colorResource(id = R.color.teal_300), - checkedTrackColor = colorResource(id = R.color.teal_100), - uncheckedThumbColor = colorResource(id = R.color.grey_010), - uncheckedTrackColor = colorResource(id = R.color.grey_alpha_038), - ) - } else { - SwitchDefaults.colors( - uncheckedThumbColor = colorResource(id = R.color.grey_200), - ) - } ) } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/calls/SettingsCallsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/calls/SettingsCallsView.kt index 72bf39fa2b..db365cbbe2 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/calls/SettingsCallsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/calls/SettingsCallsView.kt @@ -1,14 +1,11 @@ package mega.privacy.android.app.presentation.settings.calls -import android.content.res.Configuration import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.selection.toggleable import androidx.compose.material.Divider -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -16,15 +13,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import mega.privacy.android.app.R import mega.privacy.android.app.presentation.settings.calls.model.SettingsCallsState -import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme -import mega.privacy.android.shared.original.core.ui.theme.Typography import mega.privacy.android.domain.entity.CallsMeetingInvitations import mega.privacy.android.domain.entity.CallsMeetingReminders import mega.privacy.android.domain.entity.CallsSoundNotifications +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch +import mega.privacy.android.shared.original.core.ui.preview.CombinedThemePreviews +import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme +import mega.privacy.android.shared.original.core.ui.theme.Typography @Composable fun SettingsCallsView( @@ -89,28 +87,18 @@ fun CallSettingItem( ) } - Switch( + MegaSwitch( checked = checked, onCheckedChange = null, - colors = switchColors() ) } Divider(color = colorResource(id = R.color.grey_012_white_012), thickness = 1.dp) } +@CombinedThemePreviews @Composable -private fun switchColors() = SwitchDefaults.colors( - checkedThumbColor = colorResource(id = R.color.teal_300_teal_200), - checkedTrackColor = colorResource(id = R.color.teal_100_teal_200_038), - uncheckedThumbColor = colorResource(id = R.color.grey_020_grey_100), - uncheckedTrackColor = colorResource(id = R.color.grey_700_grey_050_038), -) - -@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, name = "DarkPreviewSettingsCallsView") -@Preview -@Composable -fun PreviewSettingsCallsView() { +private fun PreviewSettingsCallsView() { OriginalTempTheme(isDark = isSystemInDarkTheme()) { SettingsCallsView( settingsCallsState = SettingsCallsState( diff --git a/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/lists/MenuActionListTileTest.kt b/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/lists/MenuActionListTileTest.kt index 7010b12c07..74a5a5b445 100644 --- a/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/lists/MenuActionListTileTest.kt +++ b/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/lists/MenuActionListTileTest.kt @@ -1,6 +1,5 @@ package mega.privacy.android.shared.original.core.ui.controls.lists -import androidx.compose.material.Switch import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource @@ -9,6 +8,7 @@ import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText import androidx.test.ext.junit.runners.AndroidJUnit4 import mega.privacy.android.core.R +import mega.privacy.android.shared.original.core.ui.controls.controlssliders.MegaSwitch import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -42,7 +42,7 @@ class MenuActionListTileTest { text = "MenuListViewItem", icon = painterResource(id = R.drawable.ic_favorite), ) { - Switch( + MegaSwitch( modifier = Modifier.testTag(switchTag), checked = true, onCheckedChange = {} From 7ce797ceb3b68e00a09d181a1e73967f4331dd4c Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Wed, 19 Jun 2024 10:47:18 +0800 Subject: [PATCH 158/261] T16628220 AND- Home - videos - selection mode - verify the green check mark is not appearing --- .../android/app/fragments/homepage/FileListBinding.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/fragments/homepage/FileListBinding.kt b/app/src/main/java/mega/privacy/android/app/fragments/homepage/FileListBinding.kt index e1e0cf215d..b3edaebaa5 100644 --- a/app/src/main/java/mega/privacy/android/app/fragments/homepage/FileListBinding.kt +++ b/app/src/main/java/mega/privacy/android/app/fragments/homepage/FileListBinding.kt @@ -6,7 +6,6 @@ import android.net.Uri import android.view.View import android.view.ViewGroup import android.widget.FrameLayout -import androidx.core.content.ContextCompat import androidx.databinding.BindingAdapter import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView @@ -37,12 +36,14 @@ fun setListItemThumbnail( when { selected -> { hierarchy.setOverlayImage(null) - setActualImageResource(CoreUiR.drawable.ic_select_folder) + setImageResource(CoreUiR.drawable.ic_select_folder) } + isFileAvailable(file) -> { hierarchy.setOverlayImage(null) setImageURI(Uri.fromFile(file)) } + else -> { hierarchy.setOverlayImage(null) hierarchy.setPlaceholderImage(defaultThumbnail) @@ -117,7 +118,8 @@ fun getRoundingParams(context: Context): RoundingParams? { roundingParams?.apply { setBorder( - ColorUtils.getThemeColor(context, com.google.android.material.R.attr.colorSecondary), Util.dp2px( + ColorUtils.getThemeColor(context, com.google.android.material.R.attr.colorSecondary), + Util.dp2px( context.resources.getDimension(R.dimen.photo_selected_border_width), ).toFloat() ) From 3ad5ebd259e2107c33327ac4ea8be92329b206eb Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Wed, 19 Jun 2024 19:50:07 +0800 Subject: [PATCH 159/261] Update strings --- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 2 +- .../src/main/res/values-de/strings_shared.xml | 14 ++--- .../src/main/res/values-es/strings_shared.xml | 2 +- .../src/main/res/values-fr/strings_shared.xml | 16 +++--- .../src/main/res/values-in/strings_shared.xml | 2 +- .../src/main/res/values-it/strings_shared.xml | 2 +- .../src/main/res/values-ja/strings_shared.xml | 2 +- .../src/main/res/values-ko/strings_shared.xml | 2 +- .../src/main/res/values-nl/strings_shared.xml | 2 +- .../src/main/res/values-pl/strings_shared.xml | 54 +++++++++---------- .../src/main/res/values-pt/strings_shared.xml | 2 +- .../src/main/res/values-ro/strings_shared.xml | 12 ++--- .../src/main/res/values-ru/strings_shared.xml | 2 +- .../src/main/res/values-th/strings_shared.xml | 2 +- .../src/main/res/values-vi/strings_shared.xml | 2 +- .../main/res/values-zh-rCN/strings_shared.xml | 2 +- .../main/res/values-zh-rTW/strings_shared.xml | 2 +- 21 files changed, 65 insertions(+), 65 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index b1a837693f..db289fe53e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5047,7 +5047,7 @@ Empezar una reunión - Habla de forma segura y privada en llamadas y videollamadas con amigos y colegas de todo el mundo. + Habla de forma segura y privada en llamadas y videollamadas con amigos y compañeros de todo el mundo. ¿Cancelar “%1$s”? diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 35dd5b4f6d..6868761543 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5335,7 +5335,7 @@ %1$s en %2$d anderen staken hun hand op - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Er zijn verborgen items in dit album. Als u het album deelt, zijn de verborgen items zichtbaar voor degenen met wie u deelt. De items blijven verborgen op uw Cloud-schijf. diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 31ef7352ad..210c119b67 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5811,7 +5811,7 @@ %1$s i %2$d inni podniosili ręce - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + W tym albumie znajdują się ukryte elementy. Udostępnianie albumu oznacza, że ukryte elementy będą widoczne dla tych, którym udostępniasz. Elementy będą nadal ukryte na Dysk w chmurze. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 14686c0109..13e362988f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5097,7 +5097,7 @@ %1$s和其他%2$d个人举起手 - There are hidden items in this album. Sharing the album will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + 此相册包含隐藏的项目。共享相册意味着与您共享的人可以看到隐藏的项目。这些项目仍将隐藏在您的云盘中。 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 9661a546fe..25e3467e5a 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -235,7 +235,7 @@ %1$s غيغابايت - Free + مجاني محدود diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 2875e83dd4..fc31d892dc 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -219,7 +219,7 @@ %1$s GB - Free + Kostenlos Begrenzt @@ -415,7 +415,7 @@ Keine Beschreibung - Add to playlist + Zu Playlist hinzufügen Neue Playlist @@ -423,9 +423,9 @@ Du verzichtest auf alle diese Vorteile - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + Bis Ihr MEGA-Paket abläuft, haben Sie weiterhin Zugriff auf diese Funktionen. Danach werden Sie auf einen kostenlosen Account umgestellt. - You are currently using %1s of storage, which you will risk losing. + Sie belegen derzeit %1s Speicherplatz, den Sie verlieren könnten. Funktion @@ -453,19 +453,19 @@ MEGA VPN - Call &amp; meeting duration + Anruf- und Meeting-Dauer Bis zu 1 Stunde UNBEGRENZT - Call &amp; meeting participants + Anruf- und Meeting-Teilnehmer Bis zu 100 UNBEGRENZT - Keep %1s + %1s behalten Mit Kündigung fortfahren \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 8d647a24a0..023be264bf 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -223,7 +223,7 @@ %1$s GB - Free + Gratis Limitado diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index bb0d495ab9..8e58fb593a 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -223,7 +223,7 @@ %1$s Go - Free + Gratuit limités @@ -403,7 +403,7 @@ Pro seulement - Balises + Étiquettes Utilisez des étiquettes pour vous aider à trouver et à organiser vos données. Essayez d’étiqueter par année, emplacement, projet ou sujet. @@ -419,7 +419,7 @@ Les étiquettes doivent comprendre %1$d caractères ou moins - Balises + Étiquettes Aucune description @@ -433,11 +433,11 @@ Vous y aurez toujours accès jusqu’à l’expiration de votre abonnement MEGA, après quoi vous passerez à un compte gratuit. - You are currently using %1s of storage, which you will risk losing. + Vous utilisez actuellement %1s d’espace de stockage, que vous risquez de perdre. Caractéristique - Free + Gratuit Espace de stockage @@ -445,7 +445,7 @@ Transferts - limités + Limités Liens protégés par mot de passe @@ -465,13 +465,13 @@ Jusqu’à 1 heure - ILLIMITÉE + Ilimitée Participants aux appels et réunions Jusqu’à 100 - ILLIMITÉE + IIlimités Garder %1s diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 65c6c821bd..07242cfc83 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -218,7 +218,7 @@ %1$s GB - Free + Gratis Terbatas diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index b184f217ae..66409509be 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -223,7 +223,7 @@ %1$s GB - Free + Gratis Limitata diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 37291ca5a1..3aa20b9ead 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -215,7 +215,7 @@ %1$s GB - Free + 無料 制限付き diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index c97673ea02..c105a23a3b 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -215,7 +215,7 @@ %1$sGB - Free + 무료 제한됨 diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 64bbb52052..d0a0e8ac62 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -219,7 +219,7 @@ %1$s  GB - Free + Gratis Beperkt diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 8c862ba59c..949499a416 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -91,7 +91,7 @@ Nigdy więcej nie utrać danych - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + Przewiń do tyłu, aby przywróć plik i katalog z powrotem do dowolnej daty do 180 dni, aby Twoje dane były odporne na zmiany. MEGA VPN @@ -227,7 +227,7 @@ %1$s  GB - Free + Darmowe Ograniczony @@ -299,7 +299,7 @@ Zmień - Upload paused, device is not charging + Wgraj wstrzymane, urządzenie się nie ładuje Brak ustawień synchronizacji @@ -323,7 +323,7 @@ Rozwiązane problemy - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + Tego katalogu nie można zsynchronizować. Skonfiguruj go tak, aby synchronizował się z MEGA za pomocą przesyłania z aparatu. Opis @@ -385,53 +385,53 @@ Zmień na wersję Pro - Unlock the power to sync your mobile device to the cloud with our Pro plans. + Odblokuj moc synchronizacji urządzenia mobilnego z chmurą dzięki naszym planom Pro. Zmień Nie teraz - Uploads folder conflict + Wgraj folder - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + Katalogi przesyłanie z kamery i zastępczy katalog do wgrywania multimediów nie mogą być ze sobą powiązane. Wybierz inny katalog. - Okay, got it + OK, rozumiem - This device doesn’t have an app to select folders + To urządzenie nie ma aplikacji do wybierania katalogu - • Automatically sync the folders on your mobile device + •   Automatyczna synchronizacja katalogów na urządzeniu mobilnym - Your syncs have been paused. Syncing is a Pro plan feature. + Twoje synchronizacje zostały wstrzymane. Synchronizacja jest funkcją w planie Pro. Ok - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + Synchronizacja jest wstrzymana, ponieważ Twój plan MEGA Pro został anulowany. Uaktualnij, aby kontynuować synchronizację. Ukryte elementy Tylko Pro - Tags + Tagi - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + Użyj tagów, aby ułatwić wyszukiwanie i porządkowanie danych. Spróbuj oznaczać według roku, lokalizacji, projektu lub tematu. Tag - Add “#%1$s” tag + Dodaj tag „#%1$s” - Existing tags + Istniejące tagi - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + Tagi nie mogą zawierać spacji ani symboli niealfanumerycznych. Tagi napisane wielkimi literami będą wyświetlane małymi literami. - The maximum number of tags is %1$d + Maksymalna liczba tagów wynosi %1$d - Tags must be %1$d characters or less + Tagi muszą mieć %1$d znaków lub mniej - Tags + Tagi Brak opisu - Add to playlist + Dodaj do listy odtwarzania Nowa lista odtwarzania @@ -439,9 +439,9 @@ Przegapisz następujące funkcje - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + Nadal będziesz mieć dostęp do tych funkcja do czasu wygaśnięcia planu MEGA, a następnie zostaniesz przeniesiony na bezpłatne konto. - You are currently using %1s of storage, which you will risk losing. + Aktualnie używasz %1s pojemności, której ryzykujesz utratę. Funkcja @@ -449,7 +449,7 @@ Pojemności - 20 GB + 20   GB Przesyłanie @@ -469,19 +469,19 @@ MEGA VPN - Call &amp; meeting duration + Czas trwania połączenia i spotkania Do 1 godziny BEZ OGRANICZEŃ - Call &amp; meeting participants + Uczestnicy połączeń i spotkań Do 100 BEZ OGRANICZEŃ - Keep %1s + Zatrzymaj %1s Kontynuuj anulowanie \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 32a46d07c9..90b4190826 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -223,7 +223,7 @@ %1$s GB - Free + Grátis Limitado diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 93d2f91202..67d9913f6d 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -223,7 +223,7 @@ %1$s GB - Free + Gratuit Limitat @@ -431,9 +431,9 @@ Nu veți beneficia de următoarele funcții - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + Veți avea în continuare acces la aceste funcții până la expirarea abonamentului MEGA, apoi veți fi mutat într-un cont gratuit. - You are currently using %1s of storage, which you will risk losing. + În prezent, utilizați %1s de spațiu de stocare, pe care riscați să îl pierdeți. Caracteristică @@ -461,19 +461,19 @@ MEGA VPN - Call &amp; meeting duration + Durata apelului și întâlnirii Până la 1 oră NELIMITATĂ - Call &amp; meeting participants + Participanții la apel și la întâlnire Până la 100 NELIMITATĂ - Keep %1s + Păstrați %1s Continua anularea \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 85efdb4f50..cf6f9517d1 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -227,7 +227,7 @@ %1$s ГБ - Free + Бесплатный Ограничено diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 10d96caf53..11c618c8a4 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -215,7 +215,7 @@ %1$s GB - Free + ฟรี ถูกจำกัด diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index d535318deb..53ee59343a 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -215,7 +215,7 @@ %1$s GB - Free + Miễn phí Bị giới hạn diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index c0bb6cd4e9..51bd3c7f95 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -215,7 +215,7 @@ %1$s GB - Free + 免费 有限制 diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 1190c8089e..c499463f65 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -215,7 +215,7 @@ %1$s GB - Free + 免費 有限制的 From c8c5c49cab277c80a3a46ccfeafee55a49d6269e Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Mon, 24 Jun 2024 09:34:14 +0800 Subject: [PATCH 160/261] Update strings --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-th/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 +- .../main/res/values-zh-rCN/strings_shared.xml | 52 +++++++++---------- 19 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 3e4a528a08..5cd21f58ea 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6077,7 +6077,7 @@ تم إيقاف الترفيع مؤقتًا لأن البطارية أقل من %1$d%% - توقفت ترفيعات الكاميرا عن العمل. حاول إعادة تمكين ترفيعات الكاميرا لحلها. في حالة استمرار المشكلة، تواصل مع الدعم. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. ترفيعات الكاميرا قيد الإنجاز، %1$d ملف معلق diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 068f46b9c3..fa53c95fd5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5149,7 +5149,7 @@ Upload pausiert, da Akkuladestand unter %1$d %% - Kamera-Uploads funktionieren nicht mehr. Um das Problem zu lösen, versuchen Sie, die Kamera-Uploads wieder zu aktivieren. Wenn das Problem weiterhin besteht, wenden Sie sich an den Support. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Kamera-Uploads aktiv, noch %1$d Datei diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index db289fe53e..f4146cbebf 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5381,7 +5381,7 @@ La subida está en pausa porque la batería está por debajo del %1$d %% - Las subidas de la cámara han dejado de funcionar. Intenta volver a activarlas para solucionarlo. Si el problema persiste, contactar con el servicio de soporte. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Subidas de la cámara en curso, %1$d archivo pendiente diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6c054ecc3d..43585cefe3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5047,7 +5047,7 @@ Commencer une réunion - Parlez en toute sécurité et confidentialité lors d’appels vocaux ou vidéo avec vos amis et collègues partout dans le monde. + Parlez en toute sécurité et confidentialité lors d’appels vocaux ou vidéo avec vos amis et collègues de par le monde. Annuler « %1$s » ? @@ -5381,7 +5381,7 @@ Le téléversement est en pause, car le niveau de la batterie est inférieur à %1$d %% - Les téléversements de l’appareil photo ne fonctionnent plus. Essayez de les réactiver afin de résoudre la situation. Si le problème persiste, contactez l’assistance. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Téléversements de l’appareil photo en cours, %1$d fichier en attente diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 1d7bee0cc3..9e1be6039a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -4917,7 +4917,7 @@ Unggahan dijeda karena baterai di bawah %1$d%% - Unggahan kamera berhenti berfungsi. Coba aktifkan kembali unggahan kamera untuk menyelesaikannya. Jika masalah berlanjut, hubungi dukungan. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Pengunggahan kamera sedang berlangsung, %1$d file tertunda diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index a20f2e3ec7..588445947d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5381,7 +5381,7 @@ Caricamento sospeso perché la batteria è minore del %1$d%% - I Caricamenti da fotocamera hanno smesso di funzionare. Prova a riattivare i Caricamenti da fotocamera per risolvere il problema. Se il problema persiste, contatta il supporto. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Caricamenti da fotocamera in corso, %1$d file in attesa diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 67051ec9c0..48dc23e3e4 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -4917,7 +4917,7 @@ バッテリーが%1$d%%を下回っているため、アップロードが一時停止されました - カメラアップロードが機能しなくなりました。これを解決するには、カメラアップロードを再度有効にしてみてください。問題が解決しない場合は、サポートにご連絡ください。 + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. カメラアップロードが進行中です。%1$d個のファイルが保留中です。 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index aa0e4e967b..5293adc3be 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4917,7 +4917,7 @@ 배터리가 %1$d%% 이하이기 대문에 업로드를 일시정지 하였습니다 - 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면, 지원으로 연락하세요. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. 카메라 업로드 진행 중, 파일 %1$d개 대기 중 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 6868761543..c2ac72336b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5149,7 +5149,7 @@ Het uploaden is gepauzeerd omdat de batterij lager is dan %1$d%% - Camera-uploads werken niet meer. Probeer camera-uploads opnieuw in te schakelen om het probleem op te lossen. Als het probleem zich blijft voordoen, neem contact op met de klantenservice. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Camera uploads zijn in behandeling,%1$d bestand in wachtrij diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 210c119b67..3acb4ba132 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5613,7 +5613,7 @@ Przesyłanie wstrzymane, ponieważ bateria jest poniżej %1$d%% - Przesyłanie wgraj kamery przestało działać. Spróbuj ponownie włączyć przesyłanie z kamery, aby rozwiązać ten problem. Jeśli problem nadal występuje, skontaktuj kontakt wsparcie. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Trwa przesyłanie kamery, %1$d plików oczekuje na przesłanie diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b75e5581c2..386d983033 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5381,7 +5381,7 @@ O upload foi pausado porque a bateria há menos de %1$d%% de bateria - Os uploads da câmera pararam de funcionar - tente reativá-los. Se o problema persistir, entre em contato com o suporte. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Uploads da câmera em andamento, %1$d arquivo pendente diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 784302f12f..08d193658d 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -5381,7 +5381,7 @@ Încărcarea a fost întreruptă deoarece bateria este sub %1$d %%. - Încărcări camere au încetat să funcționeze. Încercați să reactivați încărcările camerei pentru a o rezolva. Dacă problema persistă, contactați asistență. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Încărcări cameră în desfășurare, %1$d fișier în așteptare diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index df1c3df48b..e0ee5b178d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5613,7 +5613,7 @@ Загрузка приостановлена, так как заряд батареи ниже %1$d%% - Загрузки из камеры перестали работать. Попробуйте повторно включить загрузки из камеры. Если проблема повторяется, обратитесь в поддержку. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Выполняется загрузка из камеры, %1$d файл ожидает обработки diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index ab854eafac..6b86c4faca 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -4917,7 +4917,7 @@ การอัปโหลดถูกหยุดชั่วคราว เนื่องจากแบตเตอรี่เหลือต่ำกว่า %1$d%% - การอัปโหลดจากกล้องหยุดทำงาน ลองเปิดใช้งานการอัปโหลดรูปภาพจากกล้องอีกครั้งเพื่อแก้ไข หากปัญหายังมีอยู่ กรุณาติดต่อฝ่ายสนับสนุน + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. การอัปโหลดจากกล้องกำลังอยู่ในระหว่างดำเนินการ มี %1$d ไฟล์รอดำเนินการ diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 6b1d459a14..007a39172c 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -779,7 +779,7 @@ Chìa khóa bạn vừa nhập không phù hợp với tài khoản này. Xin kiểm tra lại cho chắc chắn là Chìa Khóa Phục Hồi chính xác và thử lại. - Chìa Khóa Phục Hồi không hợp lệ + Chìa khóa phục hồi không hợp lệ Đang lấy thông tin… @@ -4917,7 +4917,7 @@ Tải lên bị tạm dừng vì pin ở dưới %1$d%% - Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với bộ phận hỗ trợ. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Việc đăng tải camêra đang được thực hiện, %1$d tệp đang chờ diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 13e362988f..d764e6458f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -4917,7 +4917,7 @@ 由于电池电量已低于%1$d%%,上传已暂停。 - 相机上传功能已停止运行。尝试重新启用相机上传功能来解决问题。如果问题仍然存在,请联系客服人员。 + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. 正在相机上传,%1$d个文件待处理 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1e028fa3d2..60c9502e28 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4917,7 +4917,7 @@ 由於電池電量低於%1$d%%,上傳已暫停 - 相機上傳停止運作。嘗試重新啟用相機上傳來解決問題。如果問題仍然存在,聯繫客服。 + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. 相機上傳正在進行中,%1$d個檔案待處理 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 051f2017b5..24cd759e56 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -788,7 +788,7 @@ The key you supplied does not match this account. Please make sure you use the correct Recovery key and try again. - Invalid Recovery key + Invalid recovery key Getting info… @@ -5155,7 +5155,7 @@ Upload paused as battery is below %1$d%% - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support. + Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. Camera uploads in progress, %1$d file pending diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 51bd3c7f95..bf22e285b7 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -91,7 +91,7 @@ 再也不会丢失数据 - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + 还原可将文件和文件夹恢复到最多180天以内的任何日期,因此您的数据就不会发生意外和被篡改。 MEGA VPN @@ -275,7 +275,7 @@ 升级 - Upload paused, device is not charging + 上传已暂停,设备未在充电 未设置同步 @@ -299,7 +299,7 @@ 已解决的问题 - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + 此文件夹无法同步。使用相机上传功能将其设置为与MEGA同步。 描述 @@ -361,27 +361,27 @@ 升级为Pro帐户 - Unlock the power to sync your mobile device to the cloud with our Pro plans. + 使用我们的Pro方案,解锁将您移动设备同步到云端的功能。 升级 现在不用 - Uploads folder conflict + 上传文件夹冲突 - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + 您的相机上传文件夹和辅助媒体上传文件夹不能相互关联。选择不同的文件夹。 - Okay, got it + 好吧,明白了 - This device doesn’t have an app to select folders + 此设备没有可用于选择文件夹的应用程序 - • Automatically sync the folders on your mobile device + • 自动同步移动设备上的文件夹 - Your syncs have been paused. Syncing is a Pro plan feature. + 您的同步已暂停。同步是Pro方案的功能。 Ok - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + 由于您的MEGA Pro方案已取消,同步已暂停。升级以继续同步。 隐藏的项目 @@ -389,25 +389,25 @@ 标签 - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + 使用标签来帮助您查找和整理数据。尝试按年份、位置、项目或主题进行标记。 - Tag + 标签 - Add “#%1$s” tag + 添加“#%1$s”标签 - Existing tags + 现有标签 - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + 标签不能包含空格或非字母数字的符号。使用大写字母的标签将以小写字母显示。 - The maximum number of tags is %1$d + 标签的最大数量为%1$d - Tags must be %1$d characters or less + 标签必须是%1$d个字符数或更少 标签 无描述 - Add to playlist + 添加到播放列表 新播放列表 @@ -415,13 +415,13 @@ 您将会错过这些功能 - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + 在您的MEGA方案到期之前,您仍然可以使用这些功能,然后您将被转移到免费帐户。 - You are currently using %1s of storage, which you will risk losing. + 您目前使用%1s存储空间,您将面临数据丢失的风险。 功能 - Free + 免费 存储空间 @@ -445,19 +445,19 @@ MEGA VPN - Call &amp; meeting duration + 通话和会议时长 - 长达1小时 + 最多1小时 无限制 - Call &amp; meeting participants + 通话和会议参与者人数 最多100人 无限制 - Keep %1s + 保留%1s 继续取消 \ No newline at end of file From d0f068947f3c4a2481dd8a38d1230bd1bef14aff Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Mon, 24 Jun 2024 16:31:32 +1200 Subject: [PATCH 161/261] Update Pre-Built Mega SDK Version and SDK Submodule --- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 92c7fb9b66..4f30712044 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -85,7 +85,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "34.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240614.023946-rel" +extra["megaSdkVersion"] = "20240624.024717-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index 2e2f919e6b..8ffa53c73b 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit 2e2f919e6bdf8552d2bbecba70da019d4d01776a +Subproject commit 8ffa53c73b8295415f965139daf78cecbac70482 From 2c0e2939b3433e2a55e902217a91cd7b7a120897 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Wed, 26 Jun 2024 13:58:27 +1200 Subject: [PATCH 162/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index a4d287b095..cf315a7d4c 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -72,7 +72,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240625.220618" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 22826f0ce4f5ca5f86153d868601187fde56724f Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Wed, 10 Jul 2024 10:45:00 +0700 Subject: [PATCH 163/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 4d7ec7c861..50dbe1fa97 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -73,7 +73,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240702.021227" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 5a32e041af6f25a474303595935c95dc52281f3a Mon Sep 17 00:00:00 2001 From: Yenel Date: Wed, 10 Jul 2024 11:29:52 +0200 Subject: [PATCH 164/261] T16892682 Tapping on the notification of ongoing transfers shows a bugged Transfers screen --- .../notification/DefaultChatUploadNotificationMapper.kt | 8 ++++---- .../DefaultTransfersFinishedNotificationMapper.kt | 8 ++++---- .../notification/DefaultTransfersNotificationMapper.kt | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultChatUploadNotificationMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultChatUploadNotificationMapper.kt index d3a8513d61..a53f816bfe 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultChatUploadNotificationMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultChatUploadNotificationMapper.kt @@ -36,14 +36,14 @@ class DefaultChatUploadNotificationMapper @Inject constructor( paused: Boolean, ): Notification { val intent = if (getFeatureFlagValueUseCase(AppFeatures.TransfersSection)) { + Intent(context, TransfersActivity::class.java).apply { + putExtra(EXTRA_TAB, IN_PROGRESS_TAB_INDEX) + } + } else { Intent(context, ManagerActivity::class.java).apply { action = Constants.ACTION_SHOW_TRANSFERS putExtra(ManagerActivity.TRANSFERS_TAB, TransfersTab.PENDING_TAB) } - } else { - Intent(context, TransfersActivity::class.java).apply { - putExtra(EXTRA_TAB, IN_PROGRESS_TAB_INDEX) - } } val pendingIntent: PendingIntent = PendingIntent.getActivity( context, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersFinishedNotificationMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersFinishedNotificationMapper.kt index 64208e4c00..12a3db5957 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersFinishedNotificationMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersFinishedNotificationMapper.kt @@ -88,14 +88,14 @@ class DefaultTransfersFinishedNotificationMapper @Inject constructor( } val intent = if (getFeatureFlagValueUseCase(AppFeatures.TransfersSection)) { + Intent(context, TransfersActivity::class.java).apply { + putExtra(EXTRA_TAB, COMPLETED_TAB_INDEX) + } + } else { Intent(context, ManagerActivity::class.java).apply { action = Constants.ACTION_SHOW_TRANSFERS putExtra(ManagerActivity.TRANSFERS_TAB, TransfersTab.COMPLETED_TAB) } - } else { - Intent(context, TransfersActivity::class.java).apply { - putExtra(EXTRA_TAB, COMPLETED_TAB_INDEX) - } } val pendingIntent = PendingIntent.getActivity( context, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersNotificationMapper.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersNotificationMapper.kt index 11379441f6..dcfc85bf2a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersNotificationMapper.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/notification/DefaultTransfersNotificationMapper.kt @@ -35,14 +35,14 @@ class DefaultTransfersNotificationMapper @Inject constructor( paused: Boolean, ): Notification { val intent = if (getFeatureFlagValueUseCase(AppFeatures.TransfersSection)) { + Intent(context, TransfersActivity::class.java).apply { + putExtra(EXTRA_TAB, IN_PROGRESS_TAB_INDEX) + } + } else { Intent(context, ManagerActivity::class.java).apply { action = Constants.ACTION_SHOW_TRANSFERS putExtra(ManagerActivity.TRANSFERS_TAB, TransfersTab.PENDING_TAB) } - } else { - Intent(context, TransfersActivity::class.java).apply { - putExtra(EXTRA_TAB, IN_PROGRESS_TAB_INDEX) - } } val pendingIntent: PendingIntent = PendingIntent.getActivity( From 3a0176eea8849e41a4e974cd7f1864629d0a0cb1 Mon Sep 17 00:00:00 2001 From: Vincent Ardyan Putra Date: Thu, 11 Jul 2024 22:14:59 +1200 Subject: [PATCH 165/261] T16891023/AND-18727: Migrate InviteContactActivity to clean architecture and Compose --- .../app/presentation/contact/invite/InviteContactFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/contact/invite/InviteContactFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/contact/invite/InviteContactFragment.kt index af3f3ca38e..71dc5e7e75 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/contact/invite/InviteContactFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/contact/invite/InviteContactFragment.kt @@ -63,6 +63,7 @@ class InviteContactFragment : Fragment() { OriginalTempTheme(isDark = themeMode.isDarkMode()) { PasscodeContainer( passcodeCryptObjectFactory = passcodeCryptObjectFactory, + loading = {}, content = { // This is necessary to prevent the viewmodel class from being recreated when the configuration changes. // This can be removed after we fully migrate to a single activity and Compose navigation. From e2785f07cd21bd3d75498fc4b216cf2e26d04592 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Thu, 11 Jul 2024 12:58:46 +0600 Subject: [PATCH 166/261] MEET-4109: Fix waiting for others banner visibility --- .../call/GetParticipantsChangesUseCase.kt | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/usecase/call/GetParticipantsChangesUseCase.kt b/app/src/main/java/mega/privacy/android/app/usecase/call/GetParticipantsChangesUseCase.kt index 54ea55f4f3..d1bd5d6025 100644 --- a/app/src/main/java/mega/privacy/android/app/usecase/call/GetParticipantsChangesUseCase.kt +++ b/app/src/main/java/mega/privacy/android/app/usecase/call/GetParticipantsChangesUseCase.kt @@ -78,7 +78,8 @@ class GetParticipantsChangesUseCase @Inject constructor( val chatId: Long, val onlyMeInTheCall: Boolean, val waitingForOthers: Boolean, - var isReceivedChange: Boolean) + var isReceivedChange: Boolean, + ) /** * Method to check if I am alone on any call and whether it is because I am waiting for others or because everyone has dropped out of the call. @@ -100,20 +101,18 @@ class GetParticipantsChangesUseCase @Inject constructor( withContext(mainImmediateDispatcher) { call.changes?.apply { Timber.d("Monitor chat call updated, changes $this") - if (contains(ChatCallChanges.CallComposition)) { - if (call.status == ChatCallStatus.InProgress || call.status == ChatCallStatus.Joining) { - emitter.onNext(checkIfIAmAloneOnSpecificCall(call)) - } else if (call.status != ChatCallStatus.Destroyed && call.status != ChatCallStatus.UserNoPresent && call.status != ChatCallStatus.TerminatingUserParticipation) { - emitter.onNext( - NumParticipantsChangesResult( - call.chatId, - onlyMeInTheCall = false, - waitingForOthers = false, - isReceivedChange = true - ) + if (call.status == ChatCallStatus.InProgress || call.status == ChatCallStatus.Joining) { + emitter.onNext(checkIfIAmAloneOnSpecificCall(call)) + } else if (call.status != ChatCallStatus.Destroyed && call.status != ChatCallStatus.UserNoPresent && call.status != ChatCallStatus.TerminatingUserParticipation) { + emitter.onNext( + NumParticipantsChangesResult( + call.chatId, + onlyMeInTheCall = false, + waitingForOthers = false, + isReceivedChange = true ) + ) - } } } } @@ -143,10 +142,12 @@ class GetParticipantsChangesUseCase @Inject constructor( } } - return NumParticipantsChangesResult(call.chatid, + return NumParticipantsChangesResult( + call.chatid, onlyMeInTheCall, waitingForOthers, - isReceivedChange = true) + isReceivedChange = true + ) } /** @@ -312,4 +313,4 @@ class GetParticipantsChangesUseCase @Inject constructor( stop() } } -} \ No newline at end of file +} From 88228dfc93135f63cb355818c8598cf462731484 Mon Sep 17 00:00:00 2001 From: Sida Qian Date: Fri, 12 Jul 2024 14:28:58 +1200 Subject: [PATCH 167/261] T16859334/T16859341 Search Result Item Fixes --- .../search/view/SearchComposeView.kt | 9 ++++++++- .../app/presentation/view/NodeListView.kt | 4 ++-- .../android/app/presentation/view/NodesView.kt | 4 ++-- .../core/ui/controls/text/HighlightedText.kt | 16 +++++++++++----- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt index 3b5ee6e3f5..cd51e3f39d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/view/SearchComposeView.kt @@ -13,6 +13,7 @@ import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -110,6 +111,12 @@ fun SearchComposeView( }, ) + val highlightText by remember(state.navigationLevel) { + derivedStateOf { + searchQuery.takeIf { state.navigationLevel.isEmpty() }.orEmpty() + } + } + topBarPadding = if (state.navigationLevel.isNotEmpty()) 8.dp else 0.dp state.errorMessageId?.let { @@ -171,7 +178,7 @@ fun SearchComposeView( onItemClicked = onItemClick, onLongClick = onLongClick, sortOrder = sortOrder, - searchQuery = if (state.searchDescriptionEnabled == true) searchQuery else "", + highlightText = if (state.searchDescriptionEnabled == true) highlightText else "", isListView = state.currentViewType == ViewType.LIST, onSortOrderClick = onSortOrderClick, onChangeViewTypeClick = onChangeViewTypeClick, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt index 9a75b327fb..dcad7d1e6e 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt @@ -69,7 +69,7 @@ fun NodeListView( showMediaDiscoveryButton: Boolean, fileTypeIconMapper: FileTypeIconMapper, modifier: Modifier = Modifier, - searchQuery: String = "", + highlightText: String = "", showLinkIcon: Boolean = true, showChangeViewType: Boolean = true, isPublicNode: Boolean = false, @@ -124,7 +124,7 @@ fun NodeListView( onLongClick = { onLongClick(nodeUiItem) }, accessPermissionIcon = (nodeUiItem.node as? ShareFolderNode).getSharesIcon(), labelColor = nodeUiItem.node.getNodeLabel(), - highlightText = searchQuery, + highlightText = highlightText, showOffline = nodeUiItem.isAvailableOffline, showLink = showLinkIcon && nodeUiItem.exportedData != null, showFavourite = nodeUiItem.isFavourite && nodeUiItem.isIncomingShare.not(), diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt index 0d2ec023c2..842da92811 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodesView.kt @@ -61,7 +61,7 @@ fun NodesView( modifier: Modifier = Modifier, listState: LazyListState = LazyListState(), gridState: LazyGridState = LazyGridState(), - searchQuery: String = "", + highlightText: String = "", spanCount: Int = 2, showLinkIcon: Boolean = true, showChangeViewType: Boolean = true, @@ -94,7 +94,7 @@ fun NodesView( onLongClick = onLongClick, onEnterMediaDiscoveryClick = onEnterMediaDiscoveryClick, sortOrder = sortOrder, - searchQuery = searchQuery, + highlightText = highlightText, onSortOrderClick = onSortOrderClick, onChangeViewTypeClick = onChangeViewTypeClick, showSortOrder = showSortOrder, diff --git a/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/text/HighlightedText.kt b/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/text/HighlightedText.kt index bd43c53c08..e94dc679f2 100644 --- a/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/text/HighlightedText.kt +++ b/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/text/HighlightedText.kt @@ -44,8 +44,8 @@ fun HighlightedText( ) { val annotatedText: AnnotatedString = buildAnnotatedString { append(text) - val startIndex = text.indexOf(string = highlightText, startIndex = 0, ignoreCase = true) - if (startIndex >= 0) { + var startIndex = text.indexOf(string = highlightText, ignoreCase = true) + while (startIndex >= 0) { val endIndex = startIndex + highlightText.length addStyle( style = SpanStyle( @@ -53,10 +53,16 @@ fun HighlightedText( fontWeight = if (highlightBold) FontWeight.Bold else FontWeight.Normal ), start = startIndex, - end = endIndex, + end = endIndex + ) + startIndex = text.indexOf( + string = highlightText, + startIndex = startIndex + highlightText.length, + ignoreCase = true ) } } + Text( text = annotatedText, modifier = modifier, @@ -72,7 +78,7 @@ fun HighlightedText( private fun HighlightedTextPreview() { OriginalTempTheme(isDark = isSystemInDarkTheme()) { HighlightedText( - text = "This is a title with highlight", + text = "This is a title with Title highlight", highlightText = "TITLE", textColor = TextColor.Primary, ) @@ -84,7 +90,7 @@ private fun HighlightedTextPreview() { private fun HighlightedTextBoldPreview() { OriginalTempTheme(isDark = isSystemInDarkTheme()) { HighlightedText( - text = "This is a title with highlight", + text = "This is a title with TITLE highlight", highlightText = "TITLE", textColor = TextColor.Primary, highlightColor = red_200, From 9fa5d6b360b37efedd90773e26cc71643ae8b3d8 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Fri, 12 Jul 2024 14:21:40 +1200 Subject: [PATCH 168/261] AND-17317 Fix avatar bug (cherry picked from commit 3862bb53add4b835f816b618d126db7846940112) 3862bb53 AND-17317 Fix avatar bug --- .../list/adapter/ContactListDataViewHolder.kt | 15 +++++++++------ .../dialog/ContactBottomSheetDialogFragment.kt | 14 +++++++++++--- app/src/main/res/layout/item_contact_data.xml | 3 +-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/contacts/list/adapter/ContactListDataViewHolder.kt b/app/src/main/java/mega/privacy/android/app/contacts/list/adapter/ContactListDataViewHolder.kt index 39b30291e4..6188c89bc6 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/list/adapter/ContactListDataViewHolder.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/list/adapter/ContactListDataViewHolder.kt @@ -3,9 +3,12 @@ package mega.privacy.android.app.contacts.list.adapter import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView +import coil.load +import coil.transform.CircleCropTransformation import mega.privacy.android.app.contacts.list.data.ContactItem import mega.privacy.android.app.databinding.ItemContactDataBinding -import mega.privacy.android.app.utils.setImageRequestFromUri +import mega.privacy.android.domain.entity.user.ContactAvatar +import mega.privacy.android.domain.entity.user.UserId /** * RecyclerView's ViewHolder to show ContactItem Data info. @@ -22,11 +25,11 @@ class ContactListDataViewHolder( binding.txtLastSeen.isVisible = !item.lastSeen.isNullOrBlank() binding.chipNew.isVisible = item.isNew binding.verifiedIcon.isVisible = item.isVerified - binding.imgThumbnail.hierarchy.setPlaceholderImage(item.placeholder) - if (item.avatarUri != null) { - binding.imgThumbnail.setImageRequestFromUri(item.avatarUri) - } else { - binding.imgThumbnail.setImageRequest(null) + binding.imgThumbnail.load( + data = ContactAvatar(id = UserId(item.handle)) + ) { + transformations(CircleCropTransformation()) + placeholder(item.placeholder) } if (item.statusColor != null) { val color = ContextCompat.getColor(itemView.context, item.statusColor) diff --git a/app/src/main/java/mega/privacy/android/app/contacts/list/dialog/ContactBottomSheetDialogFragment.kt b/app/src/main/java/mega/privacy/android/app/contacts/list/dialog/ContactBottomSheetDialogFragment.kt index 933cdcbf70..6398cc4a4e 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/list/dialog/ContactBottomSheetDialogFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/list/dialog/ContactBottomSheetDialogFragment.kt @@ -14,6 +14,8 @@ import androidx.core.view.isVisible import androidx.fragment.app.FragmentManager import androidx.fragment.app.viewModels import androidx.lifecycle.lifecycleScope +import coil.load +import coil.transform.CircleCropTransformation import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch @@ -36,7 +38,8 @@ import mega.privacy.android.app.utils.Constants.REQUEST_CODE_SELECT_CHAT import mega.privacy.android.app.utils.Constants.SELECTED_CONTACTS import mega.privacy.android.app.utils.ContactUtil import mega.privacy.android.app.utils.permission.PermissionUtils -import mega.privacy.android.app.utils.setImageRequestFromUri +import mega.privacy.android.domain.entity.user.ContactAvatar +import mega.privacy.android.domain.entity.user.UserId import mega.privacy.android.navigation.MegaNavigator import nz.mega.sdk.MegaApiJava.INVALID_HANDLE import javax.inject.Inject @@ -200,8 +203,13 @@ class ContactBottomSheetDialogFragment : BaseBottomSheetDialogFragment() { binding.header.txtName.text = contact.getTitle() binding.header.txtLastSeen.text = contact.lastSeen binding.header.txtLastSeen.isVisible = !contact.lastSeen.isNullOrBlank() - binding.header.imgThumbnail.hierarchy.setPlaceholderImage(contact.placeholder) - binding.header.imgThumbnail.setImageRequestFromUri(contact.avatarUri) + binding.header.imgThumbnail.load( + data = ContactAvatar(id = UserId(contact.handle)) + ) { + transformations(CircleCropTransformation()) + placeholder(contact.placeholder) + } + contact.statusColor?.let { color -> binding.header.imgState.setColorFilter(ContextCompat.getColor(requireContext(), color)) } diff --git a/app/src/main/res/layout/item_contact_data.xml b/app/src/main/res/layout/item_contact_data.xml index 79deffcedf..5e8b5bf54a 100644 --- a/app/src/main/res/layout/item_contact_data.xml +++ b/app/src/main/res/layout/item_contact_data.xml @@ -5,7 +5,7 @@ android:layout_height="72dp" android:background="?selectableItemBackground"> - Date: Fri, 12 Jul 2024 12:15:36 +0600 Subject: [PATCH 169/261] AND-19164: Fix crash in offline sync worker --- .../usecase/offline/GetOfflineFilesUseCase.kt | 2 ++ .../usecase/offline/SyncOfflineFilesUseCase.kt | 2 +- .../usecase/offline/GetOfflineFilesUseCaseTest.kt | 6 ++++++ .../offline/SyncOfflineFilesUseCaseTest.kt | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCase.kt index c8caaffcb7..d718fcf555 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCase.kt @@ -23,6 +23,8 @@ class GetOfflineFilesUseCase @Inject constructor( */ suspend operator fun invoke(nodes: List) = coroutineScope { + if (nodes.isEmpty()) return@coroutineScope emptyMap() + val semaphore = Semaphore(8) val results = nodes.associateBy { it.id }.map { async { diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCase.kt index ba91d05b81..ccba988cf7 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCase.kt @@ -18,7 +18,7 @@ class SyncOfflineFilesUseCase @Inject constructor( */ suspend operator fun invoke() { val offlineNodes = nodeRepository.getAllOfflineNodes() - if (fileSystemRepository.getOfflineFolder().exists()) { + if (fileSystemRepository.getOfflineFolder().exists() && offlineNodes.isNotEmpty()) { getOfflineFilesUseCase(offlineNodes) .asSequence() .partition { it.value.exists() } diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCaseTest.kt index 234663dd12..a1e84ad5cd 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/GetOfflineFilesUseCaseTest.kt @@ -74,4 +74,10 @@ internal class GetOfflineFilesUseCaseTest { assertThat(result.values).containsExactly(file) } + + @Test + fun `test that empty map is returned when invoked with empty list`() = runTest { + val result = underTest(emptyList()) + assertThat(result).isEmpty() + } } \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCaseTest.kt index 083986e8b2..3f845f521d 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/offline/SyncOfflineFilesUseCaseTest.kt @@ -12,6 +12,7 @@ import org.mockito.Mockito.reset import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import java.io.File @@ -59,6 +60,20 @@ internal class SyncOfflineFilesUseCaseTest { verify(nodeRepository).removeOfflineNodeByIds(listOf(123)) } + @Test + fun `test that getOfflineFilesUseCase is not invoked when offline nodes doesn't exist`() = + runTest { + val offlineFolder = mock { + on { exists() } doReturn true + } + whenever(fileSystemRepository.getOfflineFolder()) doReturn offlineFolder + whenever(nodeRepository.getAllOfflineNodes()).thenReturn(emptyList()) + + underTest() + + verifyNoInteractions(getOfflineFilesUseCase) + } + @Test fun `test that node information is removed if folder is empty`() = runTest { val offlineFolder = mock { From 601af03c39e94ea0fbe1b5d0b9b6a46db60e572f Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 15 Jul 2024 13:52:06 +1200 Subject: [PATCH 170/261] AND-19070/T16891015: Fix psa doesn't show correctly (cherry picked from commit bb13cfc7f3e80849fdab29b6fd0ab227aeb60eda) --- .../mega/privacy/android/app/BaseActivity.kt | 8 +++++++ .../homepage/main/HomepageFragment.kt | 5 ++++- .../domain/usecase/psa/FetchPsaUseCase.kt | 3 +++ .../domain/usecase/psa/FetchPsaUseCaseTest.kt | 22 ++++++++++++++----- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/BaseActivity.kt b/app/src/main/java/mega/privacy/android/app/BaseActivity.kt index 28a8e9529a..9c6bc4d86e 100644 --- a/app/src/main/java/mega/privacy/android/app/BaseActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/BaseActivity.kt @@ -583,6 +583,14 @@ abstract class BaseActivity : AppCompatActivity(), ActivityLauncher, PermissionR Util.setAppFontSize(this) isActivityInBackground = false retryConnectionsAndSignalPresence() + fetchPsa() + } + + /** + * Fetch psa + * + */ + fun fetchPsa() { lifecycleScope.launch { kotlin.runCatching { fetchPsaUseCase(System.currentTimeMillis()) } .onFailure { Timber.e(it) } diff --git a/app/src/main/java/mega/privacy/android/app/fragments/homepage/main/HomepageFragment.kt b/app/src/main/java/mega/privacy/android/app/fragments/homepage/main/HomepageFragment.kt index f9d8161d90..f35267ef97 100644 --- a/app/src/main/java/mega/privacy/android/app/fragments/homepage/main/HomepageFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/fragments/homepage/main/HomepageFragment.kt @@ -199,7 +199,10 @@ class HomepageFragment : Fragment() { setupBottomSheetBehavior() setupFabs() - (activity as? ManagerActivity)?.adjustTransferWidgetPositionInHomepage() + (activity as? ManagerActivity)?.apply { + adjustTransferWidgetPositionInHomepage() + fetchPsa() + } if (savedInstanceState?.getBoolean(START_SCREEN_DIALOG_SHOWN, false) == true) { showChooseStartScreenDialog() diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCase.kt index a59fa521ab..43c24e0d8e 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCase.kt @@ -2,6 +2,7 @@ package mega.privacy.android.domain.usecase.psa import mega.privacy.android.domain.entity.psa.Psa import mega.privacy.android.domain.repository.psa.PsaRepository +import mega.privacy.android.domain.usecase.IsUserLoggedIn import javax.inject.Inject /** @@ -11,6 +12,7 @@ import javax.inject.Inject */ class FetchPsaUseCase @Inject constructor( private val psaRepository: PsaRepository, + private val isUserLoggedIn: IsUserLoggedIn, ) { /** * Psa request timeout @@ -23,6 +25,7 @@ class FetchPsaUseCase @Inject constructor( * @param currentTime */ suspend operator fun invoke(currentTime: Long): Psa? { + if (!isUserLoggedIn()) return null val refreshCache = shouldRefreshCache(currentTime) if (refreshCache) psaRepository.setLastFetchedTime(currentTime) return psaRepository.fetchPsa(refreshCache) diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCaseTest.kt index d24d8f5697..3caf6def7f 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/psa/FetchPsaUseCaseTest.kt @@ -1,31 +1,33 @@ package mega.privacy.android.domain.usecase.psa import com.google.common.truth.Truth.assertThat -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.psa.Psa import mega.privacy.android.domain.repository.psa.PsaRepository +import mega.privacy.android.domain.usecase.IsUserLoggedIn import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.stub import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever -@OptIn(ExperimentalCoroutinesApi::class) class FetchPsaUseCaseTest { private lateinit var underTest: FetchPsaUseCase private val psaRepository = mock() + private val isUserLoggedIn = mock() @BeforeEach internal fun setUp() { - underTest = FetchPsaUseCase(psaRepository = psaRepository) + underTest = FetchPsaUseCase(psaRepository = psaRepository, isUserLoggedIn = isUserLoggedIn) } @Test internal fun `test that psa is returned if present`() = runTest { val expected = createPsaTestData() + whenever(isUserLoggedIn()).thenReturn(true) psaRepository.stub { onBlocking { fetchPsa(any()) }.thenReturn(expected) } @@ -35,6 +37,7 @@ class FetchPsaUseCaseTest { @Test internal fun `test that null is returned if no psa is found`() = runTest { + whenever(isUserLoggedIn()).thenReturn(true) psaRepository.stub { onBlocking { fetchPsa(true) }.thenReturn(null) } @@ -48,6 +51,7 @@ class FetchPsaUseCaseTest { val currentTime = 10_000_000L val lastFetchedTime = currentTime - (underTest.psaRequestTimeout / 2) val notExpected = createPsaTestData() + whenever(isUserLoggedIn()).thenReturn(true) psaRepository.stub { onBlocking { getLastPsaFetchedTime() }.thenReturn(lastFetchedTime) onBlocking { fetchPsa(true) }.thenReturn(notExpected) @@ -64,6 +68,7 @@ class FetchPsaUseCaseTest { val lastFetchedTime = currentTime - (underTest.psaRequestTimeout + 1) val expected = createPsaTestData() + whenever(isUserLoggedIn()).thenReturn(true) psaRepository.stub { onBlocking { getLastPsaFetchedTime() }.thenReturn(lastFetchedTime) onBlocking { fetchPsa(true) }.thenReturn(expected) @@ -74,10 +79,10 @@ class FetchPsaUseCaseTest { } @Test - internal fun `test that last fetched time is updated if fetched`() = runTest{ + internal fun `test that last fetched time is updated if fetched`() = runTest { val currentTime = 10_000_000L val lastFetchedTime = currentTime - (underTest.psaRequestTimeout + 1) - + whenever(isUserLoggedIn()).thenReturn(true) psaRepository.stub { onBlocking { getLastPsaFetchedTime() }.thenReturn(lastFetchedTime) onBlocking { fetchPsa(true) }.thenReturn(null) @@ -89,6 +94,13 @@ class FetchPsaUseCaseTest { verify(psaRepository).setLastFetchedTime(currentTime) } + @Test + fun `test that user is not logged in then use case returns null`() = runTest { + whenever(isUserLoggedIn()).thenReturn(false) + + assertThat(underTest.invoke(10L)).isNull() + } + private fun createPsaTestData() = Psa( id = 1, title = "", From 4944f26aee88fa6ec6631d1987f24a20a56bf1a1 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Mon, 15 Jul 2024 18:14:50 +0200 Subject: [PATCH 171/261] TRAN-402: Refactor MonitorTransfersSizeUseCase to work with ActiveTransfers --- .../android/app/featuretoggle/AppFeatures.kt | 8 ++ .../transfers/TransfersManagementViewModel.kt | 15 +-- .../TransfersManagementViewModelTest.kt | 6 +- .../MonitorTransfersStatusUseCase.kt | 46 ++++++- .../MonitorTransfersStatusUseCaseTest.kt | 127 +++++++++++++++--- 5 files changed, 162 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt b/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt index 914c3db10e..dfe31698ff 100644 --- a/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt +++ b/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt @@ -210,6 +210,14 @@ enum class AppFeatures(override val description: String, private val defaultValu true, ), + /** + * Camera uploads utilizes active transfers to monitor transfers + */ + ActiveTransfersInCameraUploads( + "Camera Uploads uses Active transfers to monitor the transfer progress", + false, + ), + /** * Enables new confirm email fragment compose page */ diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModel.kt index d4897e860b..524a500060 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModel.kt @@ -9,7 +9,6 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.sample import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update @@ -64,15 +63,11 @@ class TransfersManagementViewModel @Inject constructor( init { viewModelScope.launch(ioDispatcher) { - val flow = if (getFeatureFlagValueUseCase(AppFeatures.UploadWorker)) { - monitorTransfersSize() - } else { - monitorTransfersSize.invokeLegacy() - .onStart { - //in invokeLegacy we only receive updates with transfer updates, so we need to force a first update - emit(TransfersStatusInfo()) - } - } + val flow = monitorTransfersSize( + uploadsWorkerFlag = getFeatureFlagValueUseCase(AppFeatures.UploadWorker), + activeTransfersInCameraUploadsFlag = getFeatureFlagValueUseCase(AppFeatures.ActiveTransfersInCameraUploads), + ) + val samplePeriodFinal = samplePeriod ?: DEFAULT_SAMPLE_PERIOD if (samplePeriodFinal > 0) { flow.sample(samplePeriodFinal) diff --git a/app/src/test/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModelTest.kt index a5d6ef4128..af73d22bc1 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/transfers/TransfersManagementViewModelTest.kt @@ -12,8 +12,8 @@ import mega.privacy.android.app.globalmanagement.TransfersManagement import mega.privacy.android.app.presentation.transfers.model.mapper.TransfersInfoMapper import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension import mega.privacy.android.domain.entity.TransfersInfo -import mega.privacy.android.domain.entity.TransfersStatusInfo import mega.privacy.android.domain.entity.TransfersStatus +import mega.privacy.android.domain.entity.TransfersStatusInfo import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransfersStatusUseCase import mega.privacy.android.domain.usecase.transfers.paused.AreAllTransfersPausedUseCase @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.extension.ExtendWith import org.mockito.ArgumentMatchers.eq +import org.mockito.kotlin.any import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.reset @@ -46,8 +47,9 @@ class TransfersManagementViewModelTest { //this mocks are only used in viewmodel init, so no need to reset val monitorTransfersSize = mock() val getFeatureFlagValueUseCase = mock() - whenever(monitorTransfersSize()) doReturn monitorTransfersSizeFlow + whenever(monitorTransfersSize(any(), any())) doReturn monitorTransfersSizeFlow whenever(getFeatureFlagValueUseCase(AppFeatures.UploadWorker)) doReturn true + whenever(getFeatureFlagValueUseCase(AppFeatures.ActiveTransfersInCameraUploads)) doReturn true commonStub() underTest = TransfersManagementViewModel( diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt index 025b51d128..d3f951687d 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt @@ -2,7 +2,10 @@ package mega.privacy.android.domain.usecase.transfers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart import mega.privacy.android.domain.entity.TransfersStatusInfo import mega.privacy.android.domain.entity.transfer.Transfer import mega.privacy.android.domain.entity.transfer.TransferState @@ -32,8 +35,33 @@ class MonitorTransfersStatusUseCase @Inject constructor( * @return Flow of [TransfersStatusInfo] */ - operator fun invoke(): Flow = - combine(TransferType.entries.filterNot { it == TransferType.NONE }.map { + operator fun invoke( + uploadsWorkerFlag: Boolean, + activeTransfersInCameraUploadsFlag: Boolean, + ): Flow = when { + uploadsWorkerFlag && activeTransfersInCameraUploadsFlag -> { + invokeNew(TransferType.entries.filter { it != TransferType.NONE }) + } + + uploadsWorkerFlag -> { + invokeNew(TransferType.entries.filter { + it != TransferType.NONE && it != TransferType.CU_UPLOAD + }).combine(invokeLegacy(onlyCameraUploads = true)) { totals, legacyCuTotals -> + totals.copy( + totalSizeToTransfer = totals.totalSizeToTransfer + legacyCuTotals.totalSizeToTransfer, + totalSizeTransferred = totals.totalSizeTransferred + legacyCuTotals.totalSizeTransferred, + pendingUploads = legacyCuTotals.pendingUploads, + paused = areTransfersPaused() + ) + } + } + + else -> invokeLegacy(onlyCameraUploads = false) + } + + + private fun invokeNew(transferTypes: List): Flow = + combine(transferTypes.map { monitorOngoingActiveTransfersUseCase(it) }) { monitorOngoingActiveTransfersResults -> TransfersStatusInfo( @@ -55,8 +83,11 @@ class MonitorTransfersStatusUseCase @Inject constructor( ) } - @Deprecated(message = "This will be deleted once AppFeatures.UploadWorker flag is deleted") - fun invokeLegacy(): Flow = repository.monitorTransferEvents() + private fun invokeLegacy(onlyCameraUploads: Boolean) = repository.monitorTransferEvents() + .filter { + !onlyCameraUploads || it.transfer.transferType == TransferType.CU_UPLOAD + } + .distinctUntilChanged() .map { val transfer = it.transfer transferMap[transfer.tag] = transfer @@ -81,9 +112,12 @@ class MonitorTransfersStatusUseCase @Inject constructor( TransfersStatusInfo( totalSizeToTransfer = totalBytes, totalSizeTransferred = totalTransferred, - pendingDownloads = getNumPendingDownloadsNonBackgroundUseCase(), + pendingDownloads = if (onlyCameraUploads) 0 else getNumPendingDownloadsNonBackgroundUseCase(), pendingUploads = getNumPendingUploadsUseCase(), - paused = areTransfersPaused(), + paused = if (onlyCameraUploads) false else areTransfersPaused(), ) + }.onStart { + //in invokeLegacy we only receive updates with transfer updates, so we need to force a first update + emit(TransfersStatusInfo()) } } \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt index e65d453ac9..cef35e3c56 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock +import org.mockito.kotlin.reset import org.mockito.kotlin.whenever import java.math.BigInteger @@ -81,6 +82,15 @@ internal class MonitorTransfersStatusUseCaseTest { ) } + @BeforeEach + fun resetMocks() = reset( + transferRepository, + getNumPendingDownloadsNonBackgroundUseCase, + getNumPendingUploadsUseCase, + monitorOngoingActiveTransfersUseCase, + areTransfersPaused, + ) + @Test fun `test that value with correct values is emitted when a new active transfer total is received`() = runTest { @@ -94,7 +104,7 @@ internal class MonitorTransfersStatusUseCaseTest { storageOverQuota = true, transferOverQuota = true, ) - underTest().test { + underTest(uploadsWorkerFlag = true, activeTransfersInCameraUploadsFlag = true).test { awaitItem() //ignore initial flowsMap[TransferType.DOWNLOAD]?.update { it.copy( @@ -129,7 +139,7 @@ internal class MonitorTransfersStatusUseCaseTest { val flowsMap = stubActiveTransfersFlows(paused = true) val expected = TransfersStatusInfo(paused = false) - underTest().test { + underTest(uploadsWorkerFlag = true, activeTransfersInCameraUploadsFlag = true).test { assertThat(awaitItem().paused).isTrue() // check initial is paused to validate the test is doing its job flowsMap.values.first().update { it.copy(paused = false) @@ -146,7 +156,7 @@ internal class MonitorTransfersStatusUseCaseTest { val flowsMap = stubActiveTransfersFlows() val expected = TransfersStatusInfo(paused = true) - underTest().test { + underTest(uploadsWorkerFlag = true, activeTransfersInCameraUploadsFlag = true).test { flowsMap.values.forEach { flow -> assertThat(awaitItem().paused).isFalse() // all but last should be false, including initial flow.update { @@ -159,22 +169,59 @@ internal class MonitorTransfersStatusUseCaseTest { } } + @Test + fun `test that totals are the addition of active transfers plus camera uploads when activeTransfersInCameraUploadsFlag is false`() = + runTest { + val expected = TransfersStatusInfo( + totalSizeToTransfer = 2000L, + totalSizeTransferred = 3000L, + pendingUploads = 1, + pendingDownloads = 4, + paused = false, + storageOverQuota = false, + transferOverQuota = true, + ) + + whenever(getNumPendingUploadsUseCase()).thenReturn(expected.pendingUploads) + whenever(transferRepository.monitorTransferEvents()).thenReturn(globalTransferFlow) + whenever(getNumPendingDownloadsNonBackgroundUseCase()).thenReturn(0) + whenever(areTransfersPaused()).thenReturn(false) + + val eventForLegacy = TransferEvent.TransferUpdateEvent( + transfer.copy(transferType = TransferType.CU_UPLOAD) + ) + val eventFromActiveTransfers = + emptyActiveTransferTotals(TransferType.DOWNLOAD).copy( + transferredBytes = expected.totalSizeTransferred - transfer.transferredBytes, + totalBytes = expected.totalSizeToTransfer - transfer.totalBytes, + totalFileTransfers = expected.pendingDownloads, + ) + + val flowsMap = stubActiveTransfersFlows() + underTest( + uploadsWorkerFlag = true, + activeTransfersInCameraUploadsFlag = false + ).test { + awaitItem() //ignore initial + flowsMap[TransferType.DOWNLOAD]?.update { + it.copy( + activeTransferTotals = eventFromActiveTransfers, + transfersOverQuota = true, + ) + } + awaitItem() //ignore updated value + globalTransferFlow.emit(eventForLegacy) + val actual = awaitItem() + + assertThat(actual).isEqualTo(expected) + } + } + private fun stubActiveTransfersFlows(paused: Boolean = false) = TransferType.entries.filterNot { it == TransferType.NONE }.associateWith { type -> MutableStateFlow( MonitorOngoingActiveTransfersResult( - activeTransferTotals = ActiveTransferTotals( - transfersType = type, - totalTransfers = 1, - totalFileTransfers = 0, - pausedFileTransfers = 0, - totalFinishedTransfers = 0, - totalFinishedFileTransfers = 0, - totalCompletedFileTransfers = 0, - totalBytes = 0L, - transferredBytes = 0L, - totalAlreadyDownloadedFiles = 0, - ), + activeTransferTotals = emptyActiveTransferTotals(type), paused = paused, storageOverQuota = false, transfersOverQuota = false, @@ -184,6 +231,19 @@ internal class MonitorTransfersStatusUseCaseTest { } } + private fun emptyActiveTransferTotals(type: TransferType) = ActiveTransferTotals( + transfersType = type, + totalTransfers = 1, + totalFileTransfers = 0, + pausedFileTransfers = 0, + totalFinishedTransfers = 0, + totalFinishedFileTransfers = 0, + totalCompletedFileTransfers = 0, + totalBytes = 0L, + transferredBytes = 0L, + totalAlreadyDownloadedFiles = 0, + ) + @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) inner class LegacyTests { @@ -202,7 +262,10 @@ internal class MonitorTransfersStatusUseCaseTest { val event = TransferEvent.TransferStartEvent(transfer) val transfersStatusInfo = MutableStateFlow(TransfersStatusInfo()) val collectJob = launch(UnconfinedTestDispatcher()) { - underTest.invokeLegacy().collect { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).collect { transfersStatusInfo.value = it } } @@ -218,7 +281,10 @@ internal class MonitorTransfersStatusUseCaseTest { val event = TransferEvent.TransferDataEvent(transfer, ByteArray(0)) val transfersStatusInfo = MutableStateFlow(TransfersStatusInfo()) val collectJob = launch(UnconfinedTestDispatcher()) { - underTest.invokeLegacy().collect { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).collect { transfersStatusInfo.value = it } } @@ -234,7 +300,10 @@ internal class MonitorTransfersStatusUseCaseTest { val event = TransferEvent.TransferFinishEvent(transfer, MegaException(-1, null)) val transfersStatusInfo = MutableStateFlow(TransfersStatusInfo()) val collectJob = launch(UnconfinedTestDispatcher()) { - underTest.invokeLegacy().collect { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).collect { transfersStatusInfo.value = it } } @@ -251,7 +320,10 @@ internal class MonitorTransfersStatusUseCaseTest { TransferEvent.TransferUpdateEvent(transfer) val transfersStatusInfo = MutableStateFlow(TransfersStatusInfo()) val collectJob = launch(UnconfinedTestDispatcher()) { - underTest.invokeLegacy().collect { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).collect { transfersStatusInfo.value = it } } @@ -274,7 +346,10 @@ internal class MonitorTransfersStatusUseCaseTest { TransferEvent.TransferUpdateEvent(transfer.copy(tag = 3)) val transfersStatusInfo = MutableStateFlow(TransfersStatusInfo()) val collectJob = launch(UnconfinedTestDispatcher()) { - underTest.invokeLegacy().collect { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).collect { transfersStatusInfo.value = it } } @@ -293,7 +368,11 @@ internal class MonitorTransfersStatusUseCaseTest { val expectedPendingUploads = 4 whenever(getNumPendingUploadsUseCase()) doReturn expectedPendingUploads whenever(getNumPendingDownloadsNonBackgroundUseCase()) doReturn expectedPendingDownloads - underTest.invokeLegacy().test { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).test { + awaitItem() //ignore first globalTransferFlow.emit(TransferEvent.TransferUpdateEvent(transfer)) val actual = awaitItem() @@ -307,7 +386,11 @@ internal class MonitorTransfersStatusUseCaseTest { runTest { val expected = true whenever(areTransfersPaused()) doReturn expected - underTest.invokeLegacy().test { + underTest( + uploadsWorkerFlag = false, + activeTransfersInCameraUploadsFlag = false + ).test { + awaitItem() //ignore first globalTransferFlow.emit(TransferEvent.TransferUpdateEvent(transfer)) val actual = awaitItem() From a7da33d5f51aa52640e186b2eb02ab873fc475ee Mon Sep 17 00:00:00 2001 From: Yenel Date: Tue, 16 Jul 2024 12:13:36 +0200 Subject: [PATCH 172/261] T16892682 Tapping on the notification of ongoing transfers shows a bugged Transfers screen app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt --- .../privacy/android/app/main/ManagerActivity.kt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 00ff5e1416..798a611bbc 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -1718,11 +1718,11 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } private fun openTransfers() { - val openTab = intent?.serializable(TRANSFERS_TAB) ?: TransfersTab.NONE + val openTab = intent?.serializable(TRANSFERS_TAB) ?: TransfersTab.PENDING_TAB lifecycleScope.launch { if (getFeatureFlagValueUseCase(AppFeatures.TransfersSection)) { val tab = openTab.let { tab -> - if (tab == TransfersTab.NONE) { + if (tab == TransfersTab.COMPLETED_TAB) { COMPLETED_TAB_INDEX } else { IN_PROGRESS_TAB_INDEX @@ -2492,7 +2492,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf Timber.d("ACTION_CANCEL_UPLOAD or ACTION_CANCEL_DOWNLOAD or ACTION_CANCEL_CAM_SYNC") drawerItem = DrawerItem.TRANSFERS transferPageViewModel.setTransfersTab( - intent.serializable(TRANSFERS_TAB) ?: TransfersTab.NONE + intent.serializable(TRANSFERS_TAB) ?: TransfersTab.PENDING_TAB ) selectDrawerItem(drawerItem) val text: String = getString(R.string.cam_sync_cancel_sync) @@ -3359,7 +3359,6 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf Timber.d("selectDrawerItemTransfers") appBarLayout.visibility = View.VISIBLE hideTransfersWidget() - drawerItem = DrawerItem.TRANSFERS setBottomNavigationMenuItemChecked(NO_BNV) transfersManagementViewModel.checkIfShouldShowCompletedTab() replaceFragment( @@ -4399,7 +4398,6 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf return true } }) - val enableSelectMenuItem = menu.findItem(R.id.action_enable_select) doNotDisturbMenuItem = menu.findItem(R.id.action_menu_do_not_disturb) clearRubbishBinMenuItem = menu.findItem(R.id.action_menu_clear_rubbish_bin) returnCallMenuItem = menu.findItem(R.id.action_return_call) @@ -4472,12 +4470,6 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } } - DrawerItem.TRANSFERS -> if (transferPageViewModel.transferTab == TransfersTab.PENDING_TAB - && transfersViewModel.getActiveTransfers().isNotEmpty() - ) { - enableSelectMenuItem.isVisible = true - } - DrawerItem.CHAT -> if (searchExpand) { openSearchView() } else { From d4af70c008d9649d5cb05333a6e91700c92a10ac Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Wed, 17 Jul 2024 12:35:19 +1200 Subject: [PATCH 173/261] AND-19147 Remove RxJava references from contact viewmodel --- .../app/contacts/list/ContactListViewModel.kt | 138 ++++++-------- .../contacts/usecase/GetContactsUseCase.kt | 125 ++++--------- .../usecase/GetContactsUseCaseTest.kt | 177 +++++------------- 3 files changed, 144 insertions(+), 296 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/contacts/list/ContactListViewModel.kt b/app/src/main/java/mega/privacy/android/app/contacts/list/ContactListViewModel.kt index 32375ea963..3ce1dcd236 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/list/ContactListViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/list/ContactListViewModel.kt @@ -2,26 +2,22 @@ package mega.privacy.android.app.contacts.list import android.content.Context import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData import androidx.lifecycle.map import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers -import io.reactivex.rxjava3.disposables.CompositeDisposable -import io.reactivex.rxjava3.kotlin.addTo -import io.reactivex.rxjava3.kotlin.subscribeBy -import io.reactivex.rxjava3.schedulers.Schedulers import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import kotlinx.coroutines.rx3.asFlowable import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.R import mega.privacy.android.app.components.ChatManagement @@ -29,11 +25,11 @@ import mega.privacy.android.app.contacts.list.data.ContactActionItem import mega.privacy.android.app.contacts.list.data.ContactActionItem.Type import mega.privacy.android.app.contacts.list.data.ContactItem import mega.privacy.android.app.contacts.list.data.ContactListState +import mega.privacy.android.app.contacts.mapper.ContactItemDataMapper import mega.privacy.android.app.contacts.usecase.GetContactsUseCase import mega.privacy.android.app.objects.PasscodeManagement import mega.privacy.android.app.usecase.chat.SetChatVideoInDeviceUseCase import mega.privacy.android.app.utils.CallUtil -import mega.privacy.android.app.utils.notifyObserver import mega.privacy.android.data.gateway.api.MegaChatApiGateway import mega.privacy.android.domain.entity.node.FolderNode import mega.privacy.android.domain.entity.node.NodeId @@ -46,25 +42,25 @@ import mega.privacy.android.domain.usecase.meeting.StartCallUseCase import mega.privacy.android.domain.usecase.shares.CreateShareKeyUseCase import nz.mega.sdk.MegaNode import timber.log.Timber -import java.util.concurrent.TimeUnit import javax.inject.Inject /** * ViewModel that handles all related logic to Contact List for the current user. * - * @param getContactsUseCase Use case to get contacts - * @param get1On1ChatIdUseCase Use case to get 1on1 chat id - * @param removedContactByEmailUseCase Use case to remove contact by email - * @param startCallUseCase Use case to start chat call - * @param passcodeManagement PasscodeManagement object - * @param chatApiGateway MegaChatApiGateway object - * @param setChatVideoInDeviceUseCase Use case to set chat video in device - * @param chatManagement ChatManagement object - * @param createShareKeyUseCase Use case to create share key - * @param getNodeByIdUseCase Use case to get node by id - * @param monitorSFUServerUpgradeUseCase Use case to monitor SFU server upgrade - * @param monitorContactRequestsUseCase Use case to monitor contact requests - * @param context Application context + * @property getContactsUseCase Use case to get contacts. + * @property get1On1ChatIdUseCase Use case to get 1 on 1 chat id. + * @property removedContactByEmailUseCase Use case to remove contact by email. + * @property startCallUseCase Use case to start a call. + * @property passcodeManagement PasscodeManagement object. + * @property chatApiGateway MegaChatApiGateway object. + * @property setChatVideoInDeviceUseCase Use case to set chat video in device. + * @property chatManagement ChatManagement object. + * @property createShareKeyUseCase Use case to create a share key. + * @property getNodeByIdUseCase Use case to get a node by id. + * @property monitorSFUServerUpgradeUseCase Use case to monitor SFU server upgrade. + * @property monitorContactRequestsUseCase Use case to monitor contact requests. + * @property contactItemDataMapper Mapper to map ContactItem to ContactItem.Data. + * @property context Application context. */ @HiltViewModel internal class ContactListViewModel @Inject constructor( @@ -80,17 +76,11 @@ internal class ContactListViewModel @Inject constructor( private val getNodeByIdUseCase: GetNodeByIdUseCase, private val monitorSFUServerUpgradeUseCase: MonitorSFUServerUpgradeUseCase, private val monitorContactRequestsUseCase: MonitorContactRequestsUseCase, + private val contactItemDataMapper: ContactItemDataMapper, @ApplicationContext private val context: Context, ) : ViewModel() { - - private val composite = CompositeDisposable() - - companion object { - private const val REQUEST_TIMEOUT_IN_MS = 100L - } - - private var queryString: String? = null - private val contacts: MutableLiveData> = MutableLiveData() + private val queryString = MutableStateFlow(null) + private val contacts: MutableStateFlow> = MutableStateFlow(emptyList()) private val _state = MutableStateFlow(ContactListState()) private var monitorSFUServerUpgradeJob: Job? = null @@ -103,7 +93,26 @@ internal class ContactListViewModel @Inject constructor( init { viewModelScope.launch { - retrieveContacts() + combine( + getContactsUseCase().map { domainList: List -> + domainList.map { contactItemDataMapper(it) }.sortedAlphabetically() + }, + queryString + ) { list: List, query: String? -> + if (query.isNullOrBlank()) { + list.groupBy { it.getFirstCharacter() } + .flatMap { (header, list) -> + mutableListOf().apply { + add(ContactItem.Header(header)) + addAll(list) + } + } + } else { + list.filter { it.matches(query) } + } + }.collectLatest { + contacts.value = it + } } retrieveContactActions() } @@ -137,57 +146,36 @@ internal class ContactListViewModel @Inject constructor( } } - private fun retrieveContacts() { - getContactsUseCase.get() - .asFlowable() - .publish { - it.take(1).concatWith(it.debounce(REQUEST_TIMEOUT_IN_MS, TimeUnit.MILLISECONDS)) - } - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribeBy( - onNext = { items -> - contacts.value = items.toList() - }, - onError = Timber::e - ) - .addTo(composite) - } - + private fun List.sortedAlphabetically(): List = + sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, ContactItem.Data::getTitle)) fun getRecentlyAddedContacts(): LiveData> = - contacts.map { items -> - if (queryString.isNullOrBlank() && items.any { it.isNew }) { + combine( + queryString, + contacts + .map { list -> + list.filterIsInstance() + .filter { it.isNew } + } + ) { query, newContacts -> + if (query.isNullOrBlank()) { mutableListOf().apply { add(ContactItem.Header(context.getString(R.string.section_recently_added))) - addAll(items.filter { it.isNew }) + addAll(newContacts) add(ContactItem.Header(context.getString(R.string.section_contacts))) } } else { emptyList() } - } + }.asLiveData() fun getContactsWithHeaders(): LiveData> = - contacts.map { items -> - val itemsWithHeaders = mutableListOf() - items?.forEachIndexed { index, item -> - if (queryString.isNullOrBlank()) { - if (index == 0 || !items[index - 1].getFirstCharacter() - .equals(items[index].getFirstCharacter(), true) - ) { - itemsWithHeaders.add(ContactItem.Header(item.getFirstCharacter())) - } - itemsWithHeaders.add(item) - } else if (item.matches(queryString!!)) { - itemsWithHeaders.add(item) - } - } - itemsWithHeaders - } + contacts.asLiveData() fun getContact(userHandle: Long): LiveData = - contacts.map { contact -> contact.find { it.handle == userHandle } } + contacts.map { contact -> contact.find { it is ContactItem.Data && it.handle == userHandle } } + .filterIsInstance() + .asLiveData() /** * Get chat room ID @@ -221,8 +209,6 @@ internal class ContactListViewModel @Inject constructor( /** * Remove contact - * - * @param megaUser MegaUser to be removed */ fun removeContact(userEmail: String) { viewModelScope.launch { @@ -235,8 +221,7 @@ internal class ContactListViewModel @Inject constructor( } fun setQuery(query: String?) { - queryString = query - contacts.notifyObserver() + queryString.value = query } /** @@ -350,11 +335,6 @@ internal class ContactListViewModel @Inject constructor( Timber.e(it) } - override fun onCleared() { - super.onCleared() - composite.clear() - } - fun getContactEmail(userHandle: Long) = getContact(userHandle).map { it?.email } } diff --git a/app/src/main/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCase.kt b/app/src/main/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCase.kt index 1cdb9d4b9d..a11bb5c6b3 100644 --- a/app/src/main/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCase.kt +++ b/app/src/main/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCase.kt @@ -1,8 +1,5 @@ package mega.privacy.android.app.contacts.usecase -import mega.privacy.android.domain.entity.contacts.ContactItem as DomainContact -import android.content.Context -import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.Flow @@ -14,21 +11,15 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.scan -import mega.privacy.android.app.R -import mega.privacy.android.app.contacts.list.data.ContactItem -import mega.privacy.android.app.contacts.mapper.ContactItemDataMapper -import mega.privacy.android.app.utils.TimeUtils -import mega.privacy.android.data.extensions.getDecodedAliases +import mega.privacy.android.domain.entity.contacts.ContactItem import mega.privacy.android.domain.entity.contacts.OnlineStatus import mega.privacy.android.domain.entity.contacts.UserChatStatus import mega.privacy.android.domain.entity.user.UserChanges import mega.privacy.android.domain.entity.user.UserLastGreen -import mega.privacy.android.domain.entity.user.UserUpdate import mega.privacy.android.domain.entity.user.UserVisibility import mega.privacy.android.domain.repository.AccountRepository import mega.privacy.android.domain.repository.ChatRepository import mega.privacy.android.domain.repository.ContactsRepository -import nz.mega.sdk.MegaRequest import java.time.Duration import java.time.Instant import java.time.LocalDateTime @@ -36,48 +27,18 @@ import java.time.ZoneId import javax.inject.Inject /** - * Get contacts use case + * Use case to get contacts. * - * @property onlineString Get online string - * @property getUnformattedLastSeenDate Get unformatted last seen date - * @property getAliasMap Get alias map - * @property getUserUpdates Get user updates + * @property accountsRepository Repository to provide information about the current account. + * @property contactsRepository Repository to provide information about contacts. + * @property chatRepository Repository to provide information about chats. */ -internal class GetContactsUseCase( - private val onlineString: () -> String, - private val getUnformattedLastSeenDate: (Int) -> String, - private val getAliasMap: (MegaRequest) -> Map, - private val getUserUpdates: () -> Flow, - private val contactMapper: ContactItemDataMapper, +internal class GetContactsUseCase @Inject constructor( + private val accountsRepository: AccountRepository, private val contactsRepository: ContactsRepository, private val chatRepository: ChatRepository, ) { - @Inject - internal constructor( - @ApplicationContext context: Context, - accountsRepository: AccountRepository, - contactsRepository: ContactsRepository, - contactMapper: ContactItemDataMapper, - chatRepository: ChatRepository, - ) : this( - onlineString = { - context.getString(R.string.online_status) - }, - getUnformattedLastSeenDate = { lastGreen -> - TimeUtils.unformattedLastGreenDate(context, lastGreen) - }, - getAliasMap = { request -> - request.megaStringMap.getDecodedAliases() - }, - getUserUpdates = { - accountsRepository.monitorUserUpdates() - }, - contactMapper = contactMapper, - contactsRepository = contactsRepository, - chatRepository = chatRepository, - ) - /** * Gets contacts. @@ -85,27 +46,25 @@ internal class GetContactsUseCase( * @param avatarFolder Avatar folder in cache. */ @OptIn(ExperimentalCoroutinesApi::class) - fun get(): Flow> = + operator fun invoke(): Flow> = listChangedFlow().flatMapLatest { initialContacts -> merge( chatOnlineStatusChangeFlow(), lastGreenChangeFlow(), chatConnectionStateChangeFlow(), userUpdatesChangeFlow(), - ).scan(initialContacts) { contacts, change: suspend (List) -> List -> + ).scan(initialContacts) { contacts, change: suspend (List) -> List -> change(contacts) } - }.map { domainList: List -> - domainList.map { contactMapper(it) }.sortedAlphabetically() }.distinctUntilChanged() - private fun lastGreenChangeFlow(): Flow) -> List> = + private fun lastGreenChangeFlow(): Flow) -> List> = contactsRepository.monitorChatPresenceLastGreenUpdates().map { event -> applyLastGreen(event) } - private fun applyLastGreen(event: UserLastGreen): suspend (List) -> List = - { contacts: List -> + private fun applyLastGreen(event: UserLastGreen): suspend (List) -> List = + { contacts: List -> contacts.map { contact -> if (contact.handle == event.handle) { contact.copy(lastSeen = event.lastGreen) @@ -115,15 +74,15 @@ internal class GetContactsUseCase( } } - private fun chatOnlineStatusChangeFlow(): Flow) -> List> = + private fun chatOnlineStatusChangeFlow(): Flow) -> List> = contactsRepository.monitorChatOnlineStatusUpdates().onEach { if (it.status != UserChatStatus.Online) contactsRepository.requestLastGreen(it.userHandle) }.map { event -> applyChatOnlineStatus(event) } - private fun applyChatOnlineStatus(event: OnlineStatus): suspend (List) -> List = - { contacts: List -> + private fun applyChatOnlineStatus(event: OnlineStatus): suspend (List) -> List = + { contacts: List -> contacts.map { contact -> if (contact.handle == event.userHandle) { contact.copy( @@ -135,13 +94,13 @@ internal class GetContactsUseCase( } } - private fun chatConnectionStateChangeFlow(): Flow) -> List> = + private fun chatConnectionStateChangeFlow(): Flow) -> List> = contactsRepository.monitorChatConnectionStateUpdates().map { applyChatConnectionState() } - private fun applyChatConnectionState(): suspend (List) -> List = - { contacts: List -> + private fun applyChatConnectionState(): suspend (List) -> List = + { contacts: List -> contacts.map { contact -> if (contact.chatroomId == null && isWithinLastThreeDays(contact.timestamp)) { contact.copy( @@ -160,22 +119,23 @@ internal class GetContactsUseCase( return Duration.between(addedTime, now).toDays() < 3 } - private fun listChangedFlow(): Flow> = flow { + private fun listChangedFlow(): Flow> = flow { val contacts = contactsRepository.getVisibleContacts() emit(contacts) - emitAll(getUserUpdates() - .map { userUpdate -> - userUpdate.changes - .mapNotNull { (key, value) -> - key.id to value.filter { it is UserChanges.Visibility || it is UserChanges.AuthenticationInformation } - }.toMap() - }.scan(contacts) { acc, userUpdate -> - if (hasVisibilityChange(acc, userUpdate) - || hasAuthChanges(userUpdate) - ) { - contactsRepository.getVisibleContacts() - } else acc - } + emitAll( + accountsRepository.monitorUserUpdates() + .map { userUpdate -> + userUpdate.changes + .mapNotNull { (key, value) -> + key.id to value.filter { it is UserChanges.Visibility || it is UserChanges.AuthenticationInformation } + }.toMap() + }.scan(contacts) { acc, userUpdate -> + if (hasVisibilityChange(acc, userUpdate) + || hasAuthChanges(userUpdate) + ) { + contactsRepository.getVisibleContacts() + } else acc + } ) awaitCancellation() }.distinctUntilChanged() @@ -184,7 +144,7 @@ internal class GetContactsUseCase( userUpdate.values.any { it.any { change -> change is UserChanges.AuthenticationInformation } } private fun hasVisibilityChange( - acc: List, + acc: List, userUpdate: Map>, ) = userUpdate.mapValues { (_, values) -> values.firstOrNull { it is UserChanges.Visibility } @@ -196,18 +156,18 @@ internal class GetContactsUseCase( private fun newContactHasBecomeVisible( visibilityChanges: Map, - acc: List, + acc: List, ) = acc.map { it.handle } .containsAll(visibilityChanges.filterValues { it == UserVisibility.Visible }.keys).not() private fun hasCurrentContactVisibilityChanged( - acc: List, + acc: List, visibilityChanges: Map, ) = acc.any { visibilityChanges[it.handle]?.let { visibility -> visibility != it.visibility } == true } - private fun userUpdatesChangeFlow(): Flow) -> List> = - getUserUpdates().map { + private fun userUpdatesChangeFlow(): Flow) -> List> = + accountsRepository.monitorUserUpdates().map { it.changes.mapKeys { (key, _) -> key.id }.mapValues { (_, list) -> @@ -217,8 +177,8 @@ internal class GetContactsUseCase( applyUserUpdates(userUpdate) } - private fun applyUserUpdates(userUpdate: Map>): suspend (List) -> List = - { contacts: List -> + private fun applyUserUpdates(userUpdate: Map>): suspend (List) -> List = + { contacts: List -> contacts.map { contact -> if (userUpdate.hasContactDataChangesForUser(contact) || userUpdate.hasAliasChange()) { contact.copy(contactData = contactsRepository.getContactData(contact)) @@ -229,7 +189,7 @@ internal class GetContactsUseCase( } private fun Map>.hasContactDataChangesForUser( - contact: DomainContact, + contact: ContactItem, ) = this[contact.handle]?.any { it is UserChanges.Avatar || it is UserChanges.Firstname || it is UserChanges.Lastname } == true @@ -237,7 +197,4 @@ internal class GetContactsUseCase( private fun Map>.hasAliasChange() = this.values.any { it.any { change -> change is UserChanges.Alias } } - - private fun List.sortedAlphabetically(): List = - sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, ContactItem.Data::getTitle)) } \ No newline at end of file diff --git a/app/src/test/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCaseTest.kt b/app/src/test/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCaseTest.kt index 7e85c1290e..71920a60ad 100644 --- a/app/src/test/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCaseTest.kt +++ b/app/src/test/java/mega/privacy/android/app/contacts/usecase/GetContactsUseCaseTest.kt @@ -1,24 +1,19 @@ package mega.privacy.android.app.contacts.usecase -import mega.privacy.android.domain.entity.contacts.ContactItem as DomainContact -import android.net.Uri -import androidx.core.net.toUri import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.awaitCancellation -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.test.runTest -import mega.privacy.android.app.contacts.list.data.ContactItem -import mega.privacy.android.app.contacts.mapper.ContactItemDataMapper import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension import mega.privacy.android.domain.entity.chat.ChatConnectionState import mega.privacy.android.domain.entity.chat.ChatConnectionStatus import mega.privacy.android.domain.entity.chat.ChatRoom import mega.privacy.android.domain.entity.contacts.ContactData +import mega.privacy.android.domain.entity.contacts.ContactItem import mega.privacy.android.domain.entity.contacts.OnlineStatus import mega.privacy.android.domain.entity.contacts.UserChatStatus import mega.privacy.android.domain.entity.user.UserChanges @@ -26,16 +21,15 @@ import mega.privacy.android.domain.entity.user.UserId import mega.privacy.android.domain.entity.user.UserLastGreen import mega.privacy.android.domain.entity.user.UserUpdate import mega.privacy.android.domain.entity.user.UserVisibility +import mega.privacy.android.domain.repository.AccountRepository import mega.privacy.android.domain.repository.ChatRepository import mega.privacy.android.domain.repository.ContactsRepository import nz.mega.sdk.MegaChatApi -import nz.mega.sdk.MegaRequest import nz.mega.sdk.MegaUser import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.kotlin.any -import org.mockito.kotlin.doAnswer import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.reset @@ -57,27 +51,20 @@ import java.time.ZoneOffset class GetContactsUseCaseTest { private lateinit var underTest: GetContactsUseCase - private val onlineString = mock<() -> String>() - private val getUnformattedLastSeenDate = mock<(Int) -> String>() - private val getAliasMap = mock<(MegaRequest) -> Map>() - private val getUserUpdates = mock<() -> Flow>() private val contactsRepository = mock() - private val contactItemDataMapper = mock() private val chatRepository = mock() + private val accountRepository = mock() @BeforeEach fun setUp() { reset( chatRepository, - onlineString, - getUnformattedLastSeenDate, - getUserUpdates, + accountRepository, contactsRepository, - contactItemDataMapper, ) - getUserUpdates.stub { - on { invoke() } doReturn emptyFlow() + accountRepository.stub { + on { monitorUserUpdates() } doReturn emptyFlow() } contactsRepository.stub { @@ -88,13 +75,10 @@ class GetContactsUseCaseTest { } } + internal fun initUnderTest() { underTest = GetContactsUseCase( - onlineString = onlineString, - getUnformattedLastSeenDate = getUnformattedLastSeenDate, - getAliasMap = getAliasMap, - getUserUpdates = getUserUpdates, - contactMapper = contactItemDataMapper, + accountsRepository = accountRepository, contactsRepository = contactsRepository, chatRepository = chatRepository ) @@ -106,13 +90,9 @@ class GetContactsUseCaseTest { onBlocking { getVisibleContacts() } doReturn emptyList() } - val contact = mock() - contactItemDataMapper.stub { - on { invoke(any()) } doReturn contact - } initUnderTest() - underTest.get().test { + underTest().test { assertThat(awaitItem()).isEmpty() } } @@ -123,7 +103,7 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().test { + underTest().test { assertThat(awaitItem()).containsExactly(expected) } } @@ -132,7 +112,7 @@ class GetContactsUseCaseTest { fun `test that contact is removed if visibility changes`() = runTest { val userHandle = 1L val userEmail = "email" - val contactItem = mock { + val contactItem = mock { on { handle } doReturn userHandle on { email } doReturn userEmail on { visibility } doReturn UserVisibility.Visible @@ -148,7 +128,7 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().test { + underTest().test { assertThat(awaitItem()).isNotEmpty() assertThat(awaitItem()).isEmpty() } @@ -176,7 +156,7 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().map { it.first().fullName.orEmpty() }.test { + underTest().map { it.first().contactData.fullName.orEmpty() }.test { assertThat(awaitItem()).isEqualTo(initial.fullName) assertThat(awaitItem()).isEqualTo(expected.fullName) } @@ -204,7 +184,7 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().map { it.first().fullName.orEmpty() }.test { + underTest().map { it.first().contactData.fullName.orEmpty() }.test { assertThat(awaitItem()).isEqualTo(initial.fullName) assertThat(awaitItem()).isEqualTo(expected.fullName) } @@ -233,9 +213,9 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().test { - assertThat(awaitItem().first().avatarUri).isEqualTo(Uri.EMPTY) - assertThat(awaitItem().first().avatarUri).isEqualTo(newUri.toUri()) + underTest().test { + assertThat(awaitItem().first().contactData.avatarUri).isEqualTo(null) + assertThat(awaitItem().first().contactData.avatarUri).isEqualTo(newUri) } } @@ -262,9 +242,9 @@ class GetContactsUseCaseTest { } initUnderTest() - underTest.get().test { - assertThat(awaitItem().first().alias).isEqualTo(oldAlias.alias) - assertThat(awaitItem().first().alias).isEqualTo(newAlias.alias) + underTest().test { + assertThat(awaitItem().first().contactData.alias).isEqualTo(oldAlias.alias) + assertThat(awaitItem().first().contactData.alias).isEqualTo(newAlias.alias) } } @@ -273,7 +253,7 @@ class GetContactsUseCaseTest { runTest { val userHandle = 1L val userEmail = "email" - val contactItem = mock { + val contactItem = mock { on { handle } doReturn userHandle on { email } doReturn userEmail } @@ -288,7 +268,7 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().test { + underTest().test { assertThat(awaitItem()).isEmpty() assertThat(awaitItem()).isNotEmpty() cancelAndIgnoreRemainingEvents() @@ -298,23 +278,19 @@ class GetContactsUseCaseTest { @Test fun `test that chat online update with online status updates the contact status`() = runTest { val userHandle = 1 - stubContact(userHandle = userHandle.toLong(), userEmail = "email") + val lastSeen = 42 + stubContact(userHandle = userHandle.toLong(), userEmail = "email", lastSeen = lastSeen) - val expectedStatus = MegaChatApi.STATUS_ONLINE - val expectedLastSeenString = "Online" + val expectedStatus = UserChatStatus.Online stubOnlineStatusUpdate(userHandle = userHandle, status = expectedStatus) - onlineString.stub { - on { invoke() } doReturn expectedLastSeenString - } - initUnderTest() - underTest.get().test { + underTest().test { awaitItem() val actual = awaitItem().first() assertThat(actual.status).isEqualTo(expectedStatus) - assertThat(actual.lastSeen).isEqualTo(expectedLastSeenString) + assertThat(actual.lastSeen).isEqualTo(lastSeen) } } @@ -324,18 +300,13 @@ class GetContactsUseCaseTest { stubContact(userHandle = userHandle, userEmail = "email") val expectedLastGreen = 123456 - val expectedLastSeenString = "Last seen" stubLastGreenUpdate(userHandle = userHandle, lastGreen = expectedLastGreen) - getUnformattedLastSeenDate.stub { - on { invoke(expectedLastGreen) } doReturn expectedLastSeenString - } - initUnderTest() - underTest.get().test { + underTest().test { awaitItem() - assertThat(awaitItem().first().lastSeen).isEqualTo(expectedLastSeenString) + assertThat(awaitItem().first().lastSeen).isEqualTo(expectedLastGreen) } } @@ -358,9 +329,9 @@ class GetContactsUseCaseTest { initUnderTest() - underTest.get().test { - assertThat(awaitItem().first().isNew).isTrue() - assertThat(awaitItem().first().isNew).isFalse() + underTest().test { + assertThat(awaitItem().first().chatroomId).isNull() + assertThat(awaitItem().first().chatroomId).isNotNull() } } @@ -368,7 +339,7 @@ class GetContactsUseCaseTest { fun `test that authentication update fetches the contacts again`() = runTest { val userHandle = 1L val userEmail = "email" - val contactItem = mock { + val contactItem = mock { on { handle } doReturn userHandle on { email } doReturn userEmail on { areCredentialsVerified }.doReturn(false, true) @@ -386,7 +357,7 @@ class GetContactsUseCaseTest { verifyNoInteractions(contactsRepository) - underTest.get().test { cancelAndIgnoreRemainingEvents()} + underTest().test { cancelAndIgnoreRemainingEvents() } verifyBlocking(contactsRepository, times(2)) { getVisibleContacts() } } @@ -425,13 +396,13 @@ class GetContactsUseCaseTest { } } - private fun stubOnlineStatusUpdate(userHandle: Int, status: Int) { + private fun stubOnlineStatusUpdate(userHandle: Int, status: UserChatStatus) { contactsRepository.stub { on { monitorChatOnlineStatusUpdates() } doReturn flow { emit( OnlineStatus( userHandle = userHandle.toLong(), - status = getStatusFromInt(status), + status = status, inProgress = false ) ) @@ -446,8 +417,8 @@ class GetContactsUseCaseTest { changes: List, userVisibility: UserVisibility = UserVisibility.Visible, ) { - getUserUpdates.stub { - on { invoke() } doReturn flow { + accountRepository.stub { + on { monitorUserUpdates() } doReturn flow { emit( UserUpdate( changes = stubChangesList(userHandle, changes, userVisibility), @@ -507,28 +478,10 @@ class GetContactsUseCaseTest { } } - private fun stubContactsList(list: List, vararg lists: List) { + private fun stubContactsList(list: List, vararg lists: List) { contactsRepository.stub { onBlocking { getVisibleContacts() }.doReturn(list, *lists) } - - contactItemDataMapper.stub { - on { invoke(any()) }.doAnswer { - val domain = it.getArgument(0) as DomainContact - val newLastSeen = - if (domain.status == UserChatStatus.Online) onlineString() else domain.lastSeen?.let { it1 -> - getUnformattedLastSeenDate(it1) - } - ContactItem.Data( - handle = domain.handle, - email = domain.email, - lastSeen = newLastSeen, - status = getIntFromStatus(domain.status), - isNew = domain.timestamp > 0 && domain.chatroomId == null, - placeholder = mock(), - ) - } - } } private fun stubContact( @@ -537,36 +490,9 @@ class GetContactsUseCaseTest { fullName: String? = "name", alias: String = "alias", isNew: Boolean = false, - ): ContactItem.Data { - - val item = ContactItem.Data( - handle = userHandle, - email = userEmail, - placeholder = mock(), - fullName = fullName, - avatarUri = Uri.EMPTY, - alias = alias, - status = MegaChatApi.STATUS_OFFLINE, - isNew = isNew, - ) - contactItemDataMapper.stub { - on { invoke(any()) }.doAnswer { - val domain = it.getArgument(0) as DomainContact - val newLastSeen = - if (domain.status == UserChatStatus.Online) onlineString() else domain.lastSeen?.let { it1 -> - getUnformattedLastSeenDate(it1) - } - item.copy( - lastSeen = newLastSeen, - status = getIntFromStatus(domain.status), - isNew = domain.timestamp > 0 && domain.chatroomId == null, - fullName = domain.contactData.fullName, - alias = domain.contactData.alias ?: alias, - ) - } - } - - val domainContact = DomainContact( + lastSeen: Int? = null, + ): ContactItem { + val domainContact = ContactItem( handle = userHandle, email = userEmail, contactData = ContactData( @@ -574,7 +500,7 @@ class GetContactsUseCaseTest { ), defaultAvatarColor = null, visibility = UserVisibility.Visible, - lastSeen = null, + lastSeen = lastSeen, timestamp = if (isNew) LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(0)) else 0L, status = UserChatStatus.Offline, areCredentialsVerified = false, @@ -584,21 +510,6 @@ class GetContactsUseCaseTest { onBlocking { getVisibleContacts() } doReturn listOf(domainContact) } - return item + return domainContact } - - private val statusMap = mapOf( - MegaChatApi.STATUS_ONLINE to UserChatStatus.Online, - MegaChatApi.STATUS_AWAY to UserChatStatus.Away, - MegaChatApi.STATUS_BUSY to UserChatStatus.Busy, - MegaChatApi.STATUS_OFFLINE to UserChatStatus.Offline, - MegaChatApi.STATUS_INVALID to UserChatStatus.Invalid, - ) - - private fun getIntFromStatus(status: UserChatStatus) = - statusMap.entries.firstOrNull { it.value == status }?.key ?: MegaChatApi.STATUS_INVALID - - private fun getStatusFromInt(status: Int): UserChatStatus = - statusMap[status] ?: UserChatStatus.Invalid - } \ No newline at end of file From da52667d9a9dbbf1d10e5b592a1e1735c5fd8d61 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Wed, 17 Jul 2024 13:44:18 +1200 Subject: [PATCH 174/261] Update strings --- app/src/main/res/values-ar/strings.xml | 4 ++ app/src/main/res/values-de/strings.xml | 4 ++ app/src/main/res/values-es/strings.xml | 14 ++-- app/src/main/res/values-fr/strings.xml | 16 +++-- app/src/main/res/values-in/strings.xml | 6 +- app/src/main/res/values-it/strings.xml | 4 ++ app/src/main/res/values-ja/strings.xml | 4 ++ app/src/main/res/values-ko/strings.xml | 4 ++ app/src/main/res/values-nl/strings.xml | 6 +- app/src/main/res/values-pl/strings.xml | 4 ++ app/src/main/res/values-pt/strings.xml | 4 ++ app/src/main/res/values-ro/strings.xml | 70 ++++++++++--------- app/src/main/res/values-ru/strings.xml | 6 +- app/src/main/res/values-th/strings.xml | 4 ++ app/src/main/res/values-vi/strings.xml | 6 +- app/src/main/res/values-zh-rCN/strings.xml | 4 ++ app/src/main/res/values-zh-rTW/strings.xml | 4 ++ .../strings_device_center_feature.xml | 2 +- .../res/values-ro/strings_sync_feature.xml | 2 +- .../src/main/res/values-es/strings_shared.xml | 2 +- .../src/main/res/values-ro/strings_shared.xml | 20 +++--- .../src/main/res/values-ru/strings_shared.xml | 4 +- .../main/res/values-zh-rTW/strings_shared.xml | 6 +- 23 files changed, 134 insertions(+), 66 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index f346df86de..e1e20eb019 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6286,4 +6286,8 @@ + + الموقع + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2aa41d4e23..4eac8d7ba5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -5334,4 +5334,8 @@ + + Ort + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 25d884a99e..ed250b351e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5552,17 +5552,17 @@ Has levantado la mano - Tú y %1$d persona habéis levantado la mano - Tú y %1$d personas habéis levantado la mano - Tú y %1$d personas habéis levantado la mano + Tú y %1$d persona más habéis levantado la mano + Tú y %1$d de personas más habéis levantado la mano + Tú y %1$d personas más habéis levantado la mano %1$s ha levantado la mano %1$s y %2$d más han levantado la mano - %1$s y otros %2$d han levantado la mano - %1$s y otros %2$d han levantado la mano + %1$s y %2$dde personas más han levantado la mano + %1$s y %2$d personas más han levantado la mano Hay elementos ocultos en este álbum. Si compartes el álbum, los elementos ocultos estarán visibles para las personas con las que lo compartas. Los elementos seguirán ocultos en tu Nube. @@ -5572,4 +5572,8 @@ + + Ubicación + + No location information \ 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 9093ca3a38..9a54aa95cb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5552,17 +5552,17 @@ Vous avez levé la main - Vous et %1$d autre personne ont levé la main - Vous et %1$d autres personnes ont levé la main - Vous et %1$d autres personnes ont levé la main + Vous et %1$d autre personne avez levé la main + Vous et %1$d autres personnes avez levé la main + Vous et %1$d autres personnes avez levé la main %1$s a levé la main - %1$s et %2$d autre personne ont levé la main - %1$s et %2$d autres personnes ont levé la main - %1$s et %2$d autres personnes ont levé la main + %1$s et %2$d autre personne avez levé la main + %1$s et %2$d autres personnes avez levé la main + %1$s et %2$d autres personnes avez levé la main Des éléments cachés sont présents dans cet album. Partager l’album implique que les éléments cachés sont visibles par les personnes avec qui vous le partagez. Les éléments resteront cachés sur votre Disque nuagique. @@ -5572,4 +5572,8 @@ Des éléments sont cachés Des éléments sont cachés + + Emplacement + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 154d7a27c6..998c89788a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -2379,7 +2379,7 @@ Tahan dan Jawab - Tahan dan Gabung + Tahan dan gabung Akhiri dan Jawab @@ -5096,4 +5096,8 @@ + + Lokasi + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 7210fb1ea1..71d5b291bc 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5570,4 +5570,8 @@ + + Posizione + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8e5ba0b4b0..06fac5d385 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5096,4 +5096,8 @@ 非表示項目 + + 場所 + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index de880a1b58..7b20084af5 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -5096,4 +5096,8 @@ 숨겨진 항목 + + 위치 + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index d5ba3cfbfe..2b53b9a3eb 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -2441,7 +2441,7 @@ Wacht en Antwoord - Wacht en Toetreden + Wacht en toetreden Beëindigen en Antwoorden @@ -5334,4 +5334,8 @@ + + Locatie + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 3df4514e59..688ca3a323 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -5810,4 +5810,8 @@ + + Lokalizacja + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 768869eb77..b44df0115b 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -5572,4 +5572,8 @@ itens ocultos itens ocultos + + Localização + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index eaa731a39a..88ba545602 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -9,7 +9,7 @@ Nu - Anulează + Anulați Mută în @@ -63,7 +63,7 @@ Niciun spațiu stocare externă detectat - Deconectează-te + Deconectați-vă Încarcă @@ -95,7 +95,7 @@ Fă backup cheii de recuperare - Anulează abonamentul + Anulați abonamentul Abonamentul a fost anulat @@ -127,7 +127,7 @@ Sigur vreți să anulați procesul actual de autentificare? - Autentifică-te + Conectați-vă E-mail @@ -189,7 +189,7 @@ Anulezi toate transferurile? - Anulează toate + Anulați toate Transferul selectat va fi anulat. @@ -485,7 +485,7 @@ Pune pe pauză transferurile - Anulează toate transferurile + Anulați toate transferurile Capturează @@ -1031,7 +1031,7 @@ Vibrații - [A]Deconectează-te[/A] pentru a comuta între conturile MEGA + [A]Deconectați-vă[/A] pentru a comuta între conturile MEGA Sigur vreți să deconectați de la contul curent? @@ -1216,7 +1216,7 @@ Afișați abonamentele - Continuă fără cont + Continuați fără cont %1$d fișier @@ -2109,7 +2109,7 @@ %d participanți - Alătură-te + Alăturați-vă Observatori @@ -2209,9 +2209,9 @@ Obiectul participării tale în programul nostru de realizări. - Anulează + Anulați - Continuă + Continuați [A]Google Pay[/A] (abonament) @@ -2503,15 +2503,15 @@ Pune în așteptare și răspunde - Pune în așteptare și alătură-te + Puneți în așteptare și alăturați-vă Încheie și răspunde - Încheie și alătură-te + Încheiați și alăturați-vă Fișier deja descărcat. Copiat în calea selectată. - Alătură-te apelului + Alăturați-vă apelului Pentru a te alătura acestui apel, trebuie să închei apelul actual. @@ -2555,7 +2555,7 @@ %d de fișiere în așteptare. - Autentifică-te pe MEGA + Conectați-vă la MEGA Creează-ți contul MEGA @@ -2805,7 +2805,7 @@ Reia transferurile - Anulează transferul + Anulați transferul Scoate de pe pauză transferurile pentru a continua cu încărcarea. @@ -2921,7 +2921,7 @@ Sistemul nostru de criptare tip zero cunoștințe necesită o cheie unică generată automat pentru acest fișier sau folder. În mod implicit, este creat un link cu această cheie, însă poți exporta cheia de decriptare separat pentru un strat de securitate suplimentar. - Resetează parola + Resetați parola Partajezi cheia pentru acest link? @@ -3135,7 +3135,7 @@ Îți mai aduci aminte parola?\nMEGA nu îți poate reseta parola dacă o uiți. - Modifică numele + Schimbați numele Schimbați imaginea profilului @@ -3181,15 +3181,15 @@ Întâlnire - Începe/Alătură-te unei întâlniri + Începeți sau alăturați întâlnirii Întâlnire nouă - Alătură-te întâlnirii + Alăturați-vă întâlnirii Începe o întâlnire - Alătură-te ca invitat + Alăturați-vă ca invitat Întâlnirea lui %s @@ -3235,9 +3235,9 @@ Link pentru întâlnire - Alătură-te întâlnirii ca invitat + Alăturați-vă întâlnirii ca invitat - Ești invitat(ă) la o întâlnire. + Sunteți invitat la o întâlnire. Atinge linkul întâlnirii care ți-a fost trimis sau lipește-l aici @@ -3273,7 +3273,7 @@ Intimitatea ta contează - Alătură-te celei mai mari platforme de stocare în cloud și colaborare securizate din lume. + Alăturați-vă celei mai mari platforme securizate de stocare în cloud și colaborare din lume. Obține 20 GB gratuit @@ -3507,7 +3507,7 @@ Se scanează… - Anulează transferurile + Anulați transferurile Transferurile neprocesate încă vor fi anulate. @@ -3967,7 +3967,7 @@ [A]%s a anulat [/A][B] ocurență programată pentru: [/B] - Acest link nu a fost generat cu contul în care ești autentificat(ă) în prezent. Autentifică-te în contul aferent acestui link pentru a-ți verifica adresa de e-mail. + Acest link nu a fost generat cu contul la care sunteți conectat în prezent. Conectați-vă la contul legat de acest link pentru a vă confirma adresa de e-mail. Nu se poate actualiza adresa de e-mail @@ -4501,11 +4501,11 @@ Acest folder a fost eliminat în conformitate cu [A]Politica pentru ghidul de eliminare [/A]. - Alătură-te + Alăturați-vă Începe o întâlnire - Alătură-te întâlnirii + Alăturați-vă întâlnirii %1$d invitație a fost trimisă.  @@ -5043,17 +5043,17 @@ Discută securizat și privat în apeluri audio sau video cu prieteni și colegi din întreaga lume. - Anulează „%1$s”? + Anulați „%1$s”? Această întâlnire va fi arhivată și toți participanții vor fi anunțați. Această întâlnire va fi plasată în cadrul Întâlniri anterioare și toți participanții vor fi anunțați. - Nu o anula + Nu anulați - Anulează și arhivează + Anulați și arhivează - Anulează întâlnirea + Anulați întâlnirea Întâlnirea a fost anulată și arhivată @@ -5071,7 +5071,7 @@ Ocurență din %1$s a fost anulat - Anulează ocurența + Anulați ocurența [A]%1$s[/A][B] a actualizat întâlnirea [/B] @@ -5572,4 +5572,8 @@ Elemente ascunse Elemente ascunse + + Locație + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index a4cc21f715..ca13db71d3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -3821,7 +3821,7 @@ Проигрывать сигнал, когда кто-то присоединяется к вызову или покидает его. - Файл сохранён в Облачном диске + Файл сохранён в Облачном диске. Файл не сохранён в Облачном диске. Попробуйте ещё раз. @@ -5810,4 +5810,8 @@ Скрытые элементы Скрытые элементы + + Расположение + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index fcd07cf8b2..e3c5e7d6cd 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -5096,4 +5096,8 @@ + + ตำแหน่งที่ตั้ง + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index b0e6d754d5..5486fa8742 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -2379,7 +2379,7 @@ Trả lời &amp; Tạm dừng cuộc hiện tại - Tham gia &amp; Tạm dừng cuộc hiện tại + Tham gia và tạm dừng cuộc hiện tại Trả lời &amp; Kết thúc cuộc hiện tại @@ -5096,4 +5096,8 @@ Các mục ẩn + + Vị trí + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 975d5c3c3a..c11adcf95b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5096,4 +5096,8 @@ + + 位置 + + No location information \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 425fd478f3..81ada6f08d 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -5096,4 +5096,8 @@ 隱藏的項目 + + 位置 + + No location information \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index 7fa637b257..ceef4f11ba 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -5,7 +5,7 @@ Redenumește - Anulează + Anulați Acest dispozitiv diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index 673ebafb36..cfe48bf683 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -55,7 +55,7 @@ Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest dispozitiv. Datele dvs. sunt întotdeauna în siguranță la noi. - Continuă + Continuați Nu acum diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 7b088da6b6..3ce3697f2c 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -405,7 +405,7 @@ Etiquetas - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + Usa las etiquetas para encontrar y organizar tus datos. Puedes etiquetar por año, ubicación, proyecto o tema. Tag diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 6b2e592661..579e94c162 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -229,7 +229,7 @@ Gratuit - Continuă + Continuați Alegeți-vă abonamentul MEGA @@ -437,7 +437,7 @@ Caracteristică - Free + Gratuit Spațiu de stocare @@ -445,7 +445,7 @@ Transferuri - Limitat + Limitate Linkuri protejate prin parolă @@ -465,17 +465,17 @@ Până la 1 oră - NELIMITATĂ + Nelimitată Participanții la apel și la întâlnire Până la 100 - NELIMITATĂ + Nelimitate Păstrați %1s - Continua anularea + Continuați anularea Maximum 32 de caractere @@ -485,7 +485,7 @@ Unul sau mai multe dintre aceste elemente sunt setate la ascuns. Odată ce partajați elementele ascunse, oricine are linkul le va putea vedea. Elementele vor fi în continuare ascunse în Unitatea cloud. - Anulează abonamentul + Anulați abonamentul Reactivați abonamentul @@ -543,15 +543,15 @@ Fără conexiune la internet - Creează un folder nou + Creați un folder nou Folder nou Numele folderului - Creează + Creați - Anulează + Anulați Introduceți un nume de folder diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 5a2bb20559..455f4f353e 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -473,13 +473,13 @@ До 1 часа - НЕОГРАНИЧЕН + Неограниченно Участники звонка и встречи До 100 - НЕОГРАНИЧЕН + Неограниченно Оставить %1s diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 19c738b2bd..f9a4a95d8a 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -179,7 +179,7 @@ 刪除播放列表 - 要從播放列表中移除? + 從播放列表中移除? 移除 @@ -393,13 +393,13 @@ 標籤 - 加入「#%1$s」標籤 + 新增「#%1$s」標籤 現有標籤 標籤不能包含空格或非字母數字的符號。使用大寫字母的標籤將以小寫字母顯示。 - 標籤的最大數量為%1$d + 標籤最大數量為%1$d 標籤不得超過%1$d個字元 From 66df1c7c7cc1298c5cf63c64540ab696620531c8 Mon Sep 17 00:00:00 2001 From: Yenel Date: Wed, 17 Jul 2024 07:51:43 +0200 Subject: [PATCH 175/261] T16891227 Cancel a single file download --- .../java/mega/privacy/android/app/main/ManagerActivity.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 798a611bbc..05128e3bc4 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -4398,6 +4398,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf return true } }) + val enableSelectMenuItem = menu.findItem(R.id.action_enable_select) doNotDisturbMenuItem = menu.findItem(R.id.action_menu_do_not_disturb) clearRubbishBinMenuItem = menu.findItem(R.id.action_menu_clear_rubbish_bin) returnCallMenuItem = menu.findItem(R.id.action_return_call) @@ -4470,6 +4471,12 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } } + DrawerItem.TRANSFERS -> if (transferPageViewModel.transferTab == TransfersTab.PENDING_TAB + && transfersViewModel.getActiveTransfers().isNotEmpty() + ) { + enableSelectMenuItem.isVisible = true + } + DrawerItem.CHAT -> if (searchExpand) { openSearchView() } else { From 20c72789019b1ae45a9e961d6b1ca99103d43b02 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Wed, 17 Jul 2024 21:18:31 +1200 Subject: [PATCH 176/261] TRAN-402: Refactor MonitorTransfersSizeUseCase to work with ActiveTransfers --- .../MonitorTransfersStatusUseCase.kt | 6 ++- .../MonitorTransfersStatusUseCaseTest.kt | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt index d3f951687d..387be6f233 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCase.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.yield import mega.privacy.android.domain.entity.TransfersStatusInfo import mega.privacy.android.domain.entity.transfer.Transfer import mega.privacy.android.domain.entity.transfer.TransferState @@ -47,10 +48,11 @@ class MonitorTransfersStatusUseCase @Inject constructor( invokeNew(TransferType.entries.filter { it != TransferType.NONE && it != TransferType.CU_UPLOAD }).combine(invokeLegacy(onlyCameraUploads = true)) { totals, legacyCuTotals -> + yield() totals.copy( totalSizeToTransfer = totals.totalSizeToTransfer + legacyCuTotals.totalSizeToTransfer, totalSizeTransferred = totals.totalSizeTransferred + legacyCuTotals.totalSizeTransferred, - pendingUploads = legacyCuTotals.pendingUploads, + pendingUploads = getNumPendingUploadsUseCase(), paused = areTransfersPaused() ) } @@ -113,7 +115,7 @@ class MonitorTransfersStatusUseCase @Inject constructor( totalSizeToTransfer = totalBytes, totalSizeTransferred = totalTransferred, pendingDownloads = if (onlyCameraUploads) 0 else getNumPendingDownloadsNonBackgroundUseCase(), - pendingUploads = getNumPendingUploadsUseCase(), + pendingUploads = if (onlyCameraUploads) 0 else getNumPendingUploadsUseCase(), paused = if (onlyCameraUploads) false else areTransfersPaused(), ) }.onStart { diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt index cef35e3c56..328694c217 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/MonitorTransfersStatusUseCaseTest.kt @@ -217,6 +217,59 @@ internal class MonitorTransfersStatusUseCaseTest { } } + @Test + fun `test that upload counter and paused are updated with legacy use cases on each new active transfer and each new transfer event when activeTransfersInCameraUploadsFlag is false`() = + runTest { + whenever(transferRepository.monitorTransferEvents()).thenReturn(globalTransferFlow) + val flowsMap = stubActiveTransfersFlows() + stubPendingUploadsAndPausedUseCases(0, false) + underTest( + uploadsWorkerFlag = true, + activeTransfersInCameraUploadsFlag = false + ).test { + awaitItem().assertPendingUploadsAndPaused(0, false) + + stubPendingUploadsAndPausedUseCases(1, false) + flowsMap[TransferType.DOWNLOAD]?.update { + it.copy( + activeTransferTotals = emptyActiveTransferTotals(TransferType.DOWNLOAD), + transfersOverQuota = true, + ) + } + awaitItem().assertPendingUploadsAndPaused(1, false) + + stubPendingUploadsAndPausedUseCases(2, true) + flowsMap[TransferType.GENERAL_UPLOAD]?.update { + it.copy( + activeTransferTotals = emptyActiveTransferTotals(TransferType.GENERAL_UPLOAD), + transfersOverQuota = true, + ) + } + awaitItem().assertPendingUploadsAndPaused(2, true) + + stubPendingUploadsAndPausedUseCases(3, false) + globalTransferFlow.emit( + TransferEvent.TransferUpdateEvent( + transfer.copy(transferType = TransferType.CU_UPLOAD) + ) + ) + awaitItem().assertPendingUploadsAndPaused(3, false) + } + } + + private suspend fun stubPendingUploadsAndPausedUseCases(uploads: Int, paused: Boolean) { + whenever(getNumPendingUploadsUseCase()).thenReturn(uploads) + whenever(areTransfersPaused()).thenReturn(paused) + } + + private fun TransfersStatusInfo.assertPendingUploadsAndPaused( + uploads: Int, + paused: Boolean, + ) { + assertThat(this.pendingUploads).isEqualTo(uploads) + assertThat(this.paused).isEqualTo(paused) + } + private fun stubActiveTransfersFlows(paused: Boolean = false) = TransferType.entries.filterNot { it == TransferType.NONE }.associateWith { type -> MutableStateFlow( From a36f0ca1cb84e872e26a0555657d12b2385e234e Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Thu, 18 Jul 2024 16:14:38 +1200 Subject: [PATCH 177/261] Task/pre release/v13.6 --- build.gradle.kts | 2 +- sdk/src/main/jni/build.sh | 4 +++- sdk/src/main/jni/mega/sdk | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5e9097c146..2cbbb258aa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,7 +87,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "35.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240710.022013-rel" +extra["megaSdkVersion"] = "20240718.035505-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/build.sh b/sdk/src/main/jni/build.sh index 29a151c78e..23ff462ec5 100755 --- a/sdk/src/main/jni/build.sh +++ b/sdk/src/main/jni/build.sh @@ -69,7 +69,9 @@ CRYPTOPP=cryptopp CRYPTOPP_VERSION=820 CRYPTOPP_SOURCE_FILE=cryptopp${CRYPTOPP_VERSION}.zip CRYPTOPP_SOURCE_FOLDER=${CRYPTOPP}/${CRYPTOPP} -CRYPTOPP_DOWNLOAD_URL=http://www.cryptopp.com/${CRYPTOPP_SOURCE_FILE} +#CRYPTOPP_DOWNLOAD_URL=http://www.cryptopp.com/${CRYPTOPP_SOURCE_FILE} +# www.cryptopp.com is not reachable on July 18, 2024. Use Artifactory instead. +CRYPTOPP_DOWNLOAD_URL=${ARTIFACTORY_BASE_URL}:443/artifactory/android-mega/cicd/build-sdk/cryptopp820.zip CRYPTOPP_SHA1="b042d2f0c93410abdec7c12bcd92787d019f8da1" SQLITE=sqlite diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index c54a98e9c3..e5d6d490be 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit c54a98e9c3b734037d076b68c55d501754475fe1 +Subproject commit e5d6d490be99352d5f2048a31c303063a458b562 From 6e85c5d260c7eba9843924c33f5dff38f9f3504e Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Wed, 24 Jul 2024 15:39:48 +0800 Subject: [PATCH 178/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 4d7ec7c861..81c0601086 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -73,7 +73,7 @@ simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorag stickyheader = 'com.brandongogetap:stickyheaders:0.6.1' vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240716.121240" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 5e7da2dcb10b401d44e2af8dadcdbfe5d8eb8c3b Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 25 Jul 2024 07:16:41 +0700 Subject: [PATCH 179/261] AND-19191: Fix crash after force dark theme meeting screen (cherry picked from commit 642a30d3369b992319733a45c0385aba463029fc) --- app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9439f1886a..28938de1e2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -508,7 +508,7 @@ android:launchMode="singleTop" /> Date: Thu, 25 Jul 2024 15:52:24 +0800 Subject: [PATCH 180/261] Update strings (cherry picked from commit b8f666578d8629b2d07d30d18252ea9bf5b887ca) --- app/src/main/res/values-ar/strings.xml | 4 +- app/src/main/res/values-de/strings.xml | 8 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 8 +- .../main/res/values-it/strings_sdk_errors.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 4 +- app/src/main/res/values-nl/strings.xml | 2 +- .../values-nl/strings_document_scanner.xml | 2 +- app/src/main/res/values-pt/strings.xml | 20 +-- .../values-pt/strings_document_scanner.xml | 6 +- app/src/main/res/values-ro/strings.xml | 70 +++++------ app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- .../strings_device_center_feature.xml | 24 ++-- .../res/values-ro/strings_sync_feature.xml | 10 +- .../src/main/res/values-ar/strings_shared.xml | 68 +++++----- .../src/main/res/values-de/strings_shared.xml | 24 ++-- .../src/main/res/values-es/strings_shared.xml | 24 ++-- .../src/main/res/values-fr/strings_shared.xml | 18 +-- .../src/main/res/values-in/strings_shared.xml | 18 +-- .../src/main/res/values-it/strings_shared.xml | 58 ++++----- .../src/main/res/values-ja/strings_shared.xml | 16 +-- .../src/main/res/values-ko/strings_shared.xml | 118 +++++++++--------- .../src/main/res/values-nl/strings_shared.xml | 20 +-- .../src/main/res/values-pl/strings_shared.xml | 50 ++++---- .../src/main/res/values-pt/strings_shared.xml | 32 ++--- .../src/main/res/values-ro/strings_shared.xml | 52 ++++---- .../src/main/res/values-ru/strings_shared.xml | 16 +-- .../src/main/res/values-th/strings_shared.xml | 18 +-- .../src/main/res/values-vi/strings_shared.xml | 54 ++++---- .../main/res/values-zh-rCN/strings_shared.xml | 16 +-- .../main/res/values-zh-rTW/strings_shared.xml | 16 +-- .../src/main/res/values/strings_shared.xml | 2 +- 36 files changed, 414 insertions(+), 380 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index e1e20eb019..937504544e 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6068,7 +6068,7 @@ تم إيقاف الترفيع مؤقتًا لأن البطارية أقل من %1$d%% - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + توقفت ترفيعات الكاميرا عن العمل. حاول إعادة تمكين ترفيعات الكاميرا لحلها. إذا استمرت المشكلة، تواصل مع support@mega.nz. ترفيعات الكاميرا قيد الإنجاز، %1$d ملف معلق @@ -6289,5 +6289,5 @@ الموقع - No location information + لا توجد معلومات عن الموقع \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4eac8d7ba5..8ec9224e71 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -3796,7 +3796,7 @@ Um die Kamera-Uploads zu aktivieren, gewähren Sie MEGA Zugriff auf Fotos und andere Medien auf Ihrem Gerät. - Zugriff freigeben + Zugriff erlauben Nicht gewähren @@ -5122,7 +5122,7 @@ Gewähren Sie Zugriff auf Ihre Galerie - Zugriff freigeben + Zugriff erlauben Update erforderlich @@ -5268,7 +5268,7 @@ Hinzugefügt - Zuletzt bearbeitet am + Letzte Änderung Heute @@ -5337,5 +5337,5 @@ Ort - No location information + Keine Standortdaten \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index ed250b351e..906297ba17 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5575,5 +5575,5 @@ Ubicación - No location information + No hay información de ubicación \ 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 9a54aa95cb..9c6d0975c3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5575,5 +5575,5 @@ Emplacement - No location information + Aucun renseignement sur la position \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 71d5b291bc..cfbc77c5b8 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -643,7 +643,7 @@ Politica sulla privacy - Termini di servizio + Termini di Servizio Versione @@ -3431,11 +3431,11 @@ Hai inserito la tua password corrente - File nomn più disponibile + File non più disponibile File rimosso perché viola i nostri Termini di servizio. - Termini di servizio violati + Termini di Servizio violati Questo dispositivo non ha app per selezionare le cartelle. @@ -5573,5 +5573,5 @@ Posizione - No location information + Nessuna informazione sulla posizione \ No newline at end of file diff --git a/app/src/main/res/values-it/strings_sdk_errors.xml b/app/src/main/res/values-it/strings_sdk_errors.xml index d6df8355b4..6b64542b47 100644 --- a/app/src/main/res/values-it/strings_sdk_errors.xml +++ b/app/src/main/res/values-it/strings_sdk_errors.xml @@ -13,7 +13,7 @@ Fallito permanentemente - Termini di servizio violati + Termini di Servizio violati Troppe connessioni simultanee o trasferimenti diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 06fac5d385..3256401849 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5099,5 +5099,5 @@ 場所 - No location information + 位置情報がありません \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 7b20084af5..85bac34d01 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4913,7 +4913,7 @@ 배터리가 %1$d%% 이하이기 대문에 업로드를 일시정지 하였습니다 - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면, support@mega.nz으로 연락하세요. 카메라 업로드 진행 중, 파일 %1$d개 대기 중 @@ -5099,5 +5099,5 @@ 위치 - No location information + 위치 정보 없음 \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 2b53b9a3eb..b19879bb9e 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5337,5 +5337,5 @@ Locatie - No location information + Geen lokatie informatie \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings_document_scanner.xml b/app/src/main/res/values-nl/strings_document_scanner.xml index 11b4a47302..30fa375592 100644 --- a/app/src/main/res/values-nl/strings_document_scanner.xml +++ b/app/src/main/res/values-nl/strings_document_scanner.xml @@ -5,7 +5,7 @@ Scan opslaan - Voeg toe + Toevoegen Opslaan diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b44df0115b..a9f56927e7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -183,7 +183,7 @@ As senhas não coincidem - Já existe uma conta no MEGA com esse e-mail + Já existe uma conta no MEGA com este email Conectando-se ao servidor: criando conta @@ -465,7 +465,7 @@ Problema no sistema de arquivos - Erro aconteceu quando executar a ação + Aconteceu um erro ao executar esta ação Alterar senha @@ -1107,7 +1107,7 @@ Continuidade do status - Mostrar sempre a aparência de status selecionada, mesmo quando eu estiver desconectado + Mostrar sempre o status selecionado, mesmo quando eu estiver desconectado Estabelecer o limite de tempo @@ -1238,7 +1238,7 @@ %s já foi convidado. Revise as suas solicitações pendentes. - Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[A]. + Se você errou ao digitar o seu email, corrija e pressione [A]Reenviar[A]. Reenviar @@ -2219,7 +2219,7 @@ nome do arquivo - Mostrar último acesso + Mostrar o último acesso Permitir que seus contatos vejam o seu último acesso ao MEGA @@ -4783,9 +4783,9 @@ Não foi possível abrir o arquivo - This folder has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Esta pasta foi removida de acordo com a nossa [A]Política do guia de remoção[/A]. Você pode disputar esta remoção se acreditar que cometemos um erro. - This file has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Este arquivo foi removido de acordo com a nossa [A]Política do guia de remoção[/A]. Você pode disputar esta remoção se acreditar que cometemos um erro. Somente para usuários Pro @@ -4917,7 +4917,7 @@ S - Q + T Q @@ -4925,7 +4925,7 @@ S - D + S D @@ -5575,5 +5575,5 @@ Localização - No location information + Não há informação de localização \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings_document_scanner.xml b/app/src/main/res/values-pt/strings_document_scanner.xml index 9874c37f01..5c6a0e93f2 100644 --- a/app/src/main/res/values-pt/strings_document_scanner.xml +++ b/app/src/main/res/values-pt/strings_document_scanner.xml @@ -25,9 +25,9 @@ Baixa - Descartar este documento escaneado? + Descartar o documento escaneado? - Este documento escaneado será eliminado + O documento escaneado será eliminado Descartar todos os documentos escaneados? @@ -35,7 +35,7 @@ Descartar - Deletar esta digitalização? + Deletar o documento escaneado? Permita o acesso à sua câmera para escanear documentos diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 88ba545602..73de30ce83 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -147,7 +147,7 @@ Nicio conexiune la rețea - Ai fost deconectat de pe acest dispozitiv dintr-o altă locație + Ai fost deconectat de pe acest aparat dintr-o altă locație Se generează cheile de criptare @@ -273,7 +273,7 @@ Adaugă contacte noi folosind butonul de mai jos - Spațiu liber insuficient pe dispozitiv + Spațiu liber insuficient pe aparat Cheie de decriptare @@ -293,9 +293,9 @@ Vezi transferurile - Nu există nicio aplicație disponibilă pentru a executa acest fișier pe dispozitiv + Nu există nicio aplicație disponibilă pentru a executa acest fișier pe aparat - Nu există aplicații disponibile pe dispozitiv pentru a deschide această locație + Nu există aplicații disponibile pe aparat pentru a deschide această locație Este posibil să nu ai instalate aplicații care acceptă acest tip de fișiere @@ -335,7 +335,7 @@ Se copiază - Mută în Coșul de gunoi + Mutați în Coșul de gunoi Elimină de pe MEGA @@ -515,7 +515,7 @@ Opțiuni pentru codul de acces - Comprimarea video folosește cantități considerabile de electricitate. Conectați dispozitivul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. + Comprimarea video folosește cantități considerabile de electricitate. Conectați aparatul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. Dacă este activată, informațiile despre locație vor fi incluse în imaginile dvs. Vă rugăm să aveți grijă când le împărtășiți. @@ -591,9 +591,9 @@ Include etichetele locațiilor - Solicită-mi încărcarea activă a dispozitivului + Solicită-mi încărcarea activă a aparatului - Păstrează numele fișierelor precum în dispozitiv + Păstrează numele fișierelor precum în aparat Folder local pentru cameră @@ -1358,13 +1358,13 @@ Eliminarea contactului de la folderul partajat - Muți în Coșul de gunoi? + Mutați în Coșul de gunoi? Doriți să mutați acest folder în Coșul de gunoi? Un nou folder va fi creat automat pentru încărcările camere. Doriți să mutați acest folder în Coșul de gunoi? Un nou folder va fi creat automat pentru încărcările media. - Muți în Coșul de gunoi? + Mutați în Coșul de gunoi? Ștergi de pe MEGA? @@ -1440,7 +1440,7 @@ Vă rugăm să furnizați feedback-ul dvs. aici: - Modelul dispozitivului + Modelul aparatului Versiunea Android @@ -1550,7 +1550,7 @@ Creează cod QR - Aliniați codul QR pentru a-l digitaliza cu camera dispozitivului dvs. + Aliniați codul QR pentru a-l digitaliza cu camera aparatului dvs. Vezi @@ -1707,7 +1707,7 @@ În acest fel, vei vedea instantaneu mesaje noi\npe telefonul Android. - Deschide [A]Setările[/A] de pe dispozitivul Android + Deschide [A]Setările[/A] de pe aparatul Android Deschide [A]Aplicații și notificări[/A] @@ -1825,7 +1825,7 @@ Scanează sau copiază sămânța în aplicația de autentificare. - Asigură-te că faci backupul acestei sămânțe într-un loc sigur în cazul în care îți pierzi aparatul. + Asigurați-vă că faceți backupul acestei semințe într-un loc sigur în cazul în care vă pierdeți aparatul. Vă rugăm să introduceți codul din 6 cifre generat de aplicația dvs. de autentificare. @@ -1841,7 +1841,7 @@ Cod nevalid - Ți-ai pierdut dispozitivul pentru autentificare? + Ți-ai pierdut aparatul pentru autentificare? Verificarea autentificării @@ -1863,7 +1863,7 @@ Deschide în - Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe dispozitiv + Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe aparat Închide @@ -2131,7 +2131,7 @@ Fișiere - Salvează pe dispozitiv + Salvează pe aparat Încarcă pe MEGA @@ -2229,7 +2229,7 @@ Dimensiunea comprimării video este prea mare - Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți dispozitivul la taxarea pentru a continua. + Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți aparatul la taxarea pentru a continua. Această setare se va aplica data viitoare când rulează Încărcări cameră @@ -2389,7 +2389,7 @@ %1$s . %2$s - Încă îi poți acorda lui MEGA permisiuni în setările dispozitivului + Încă îi poți acorda lui MEGA permisiuni în setările aparatului Mesaj redirecționat @@ -2463,7 +2463,7 @@ Fotografiile dvs. în cloud - Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. Introduceți parola dvs. @@ -2627,11 +2627,11 @@ Contactează administratorul contului business pentru a rezolva problema și a-ți activa contul. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv. + Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat. Când te deconectezi, transferurile în curs vor fi anulate. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv și transferurile în curs vor fi anulate. + Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat și transferurile în curs vor fi anulate. Nume necunoscut @@ -2909,7 +2909,7 @@ Cheie copiată în clipboard - Parolă copiată în clipboard + Parolă a fost copiată în clipboard Link și cheie trimise @@ -3141,7 +3141,7 @@ Adaugă un număr de telefon - MEGA are nevoie de permisiuni de scriere în spațiul de stocare al dispozitivului pentru a continua. + MEGA are nevoie de permisiuni de scriere în spațiul de stocare al aparatului pentru a continua. Mâine, %1$s @@ -3277,7 +3277,7 @@ Obține 20 GB gratuit - Înscrie-te acum și bucură-te gratuit de funcțiile avansate de colaborare. + Înscrieți-vă acum și bucurați-vă gratuit de funcții avansate de colaborare. Un alt apel în desfășurare. Vă rugăm să încheiați apelul curent înainte de a efectua altul. @@ -3399,7 +3399,7 @@ Aveți deja un abonament. Dacă cumpărați altul, veți fi taxat de două ori. Pentru a evita acest lucru, anulați abonamentul curent accesând MEGA într-un browser web desktop sau mobil. Vizitați Centrul nostru de ajutor pentru mai multe informații. - Accesați Setări pentru a permite MEGA permisiunea de a accesa dispozitivele din apropiere utilizând Bluetooth. + Accesați Setări pentru a permite MEGA permisiunea de a accesa aparatele din apropiere utilizând Bluetooth. Nu putem continua cu facturarea. Dacă utilizați o aplicație duală, vă rugăm să luați în considerare conectarea la MEGA fără ea. Dacă nu, încercați să actualizați prin browserul dvs. web. @@ -3437,7 +3437,7 @@ A încălcat Termenii de utilizare a serviciului - Acest dispozitiv nu are o aplicație care să selecteze foldere. + Acest aparat nu are o aplicație care să selecteze foldere. Următorul fișier audio @@ -3715,7 +3715,7 @@ Începe să chatuiești acum - Chatuiește securizat și privat, cu oricine și de pe orice dispozitiv, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. + Chatuiește securizat și privat, cu oricine și de pe orice aparat, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. Începe întâlnirea acum @@ -3805,7 +3805,7 @@ Ați adăugat deja toate contactele dvs. la acest chat. Dacă doriți să adăugați mai mulți participanți, invitați-i mai întâi la lista dvs. de contacte. - Imagine salvată în galeria dispozitivului + Imagine salvată în galeria aparatului Introduceți numele albumului @@ -3895,7 +3895,7 @@ Elimini din album? - Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe dispozitiv. + Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe aparat. Activează accesul @@ -3933,7 +3933,7 @@ Acces refuzat - Ați refuzat accesul MEGA la fișierele de stocare și media ale dispozitivului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. + Ați refuzat accesul MEGA la fișierele de stocare și media ale aparatului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. Acordă permisiunea @@ -4633,7 +4633,7 @@ Trimite invitația pentru calendar - Adaugă o descriere + Adăugați o descriere Este necesar numele întâlnirii @@ -4759,7 +4759,7 @@ Amintiți-vă preferințele - Centrul dispozitivului + Centrul de aparate În fiecare zi @@ -5267,7 +5267,7 @@ Acest apel este înregistrat - Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe dispozitivul persoanei care o înregistrează. + Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe aparatul persoanei care o înregistrează. Bine, am înțeles @@ -5575,5 +5575,5 @@ Locație - No location information + Nicio informație despre locație \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ca13db71d3..4229dd3fbf 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5813,5 +5813,5 @@ Расположение - No location information + Нет информации о местоположении \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 5486fa8742..70c34a1f71 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4913,7 +4913,7 @@ Tải lên bị tạm dừng vì pin ở dưới %1$d%% - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với support@mega.nz. Việc đăng tải camêra đang được thực hiện, %1$d tệp đang chờ @@ -5099,5 +5099,5 @@ Vị trí - No location information + Không có thông tin vị trí \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c11adcf95b..30135039ad 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5099,5 +5099,5 @@ 位置 - No location information + 没有位置信息 \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index ceef4f11ba..700148b6ad 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -1,19 +1,19 @@ - Redenumire dispozitivul + Redenumire aparatul Redenumește Anulați - Acest dispozitiv + Acest aparat - Alte dispozitive + Alte aparate Stare necunoscută - Dispozitiv necunoscut + Aparat necunoscut La zi @@ -41,7 +41,7 @@ Blocat - Centrul dispozitivului + Centrul de aparate Încărcări cameră @@ -59,7 +59,7 @@ Nicio eroare de sincronizare - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat Folderul ales nu poate fi sincronizat @@ -111,9 +111,9 @@ Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din dispozitiv nu poate fi localizat acum, încercați din nou mai târziu. + Folderul din aparat nu poate fi localizat acum, încercați din nou mai târziu. - Folderul din dispozitiv dvs. nu poate fi localizat + Folderul din aparat dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați asistența. @@ -123,13 +123,13 @@ Încărcări camere sunt dezactivate - Introduceți un nume de dispozitiv. + Introduceți un nume de aparat. - Un dispozitiv cu acest nume există deja. Introduceți un alt nume. + Un aparat cu acest nume există deja. Introduceți un alt nume. Următoarele caractere nu sunt permise: %1$s - Dispozitiv a fost redenumit + Aparat a fost redenumit Maximum 32 de caractere @@ -145,7 +145,7 @@ Nimic nu este încă configurat - Căutarea dispozitivelor + Căutarea aparatelor Căutarea sincronizării diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index cfe48bf683..4db625810c 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -7,7 +7,7 @@ Sincronizează - MEGA trebuie să acceseze spațiul de stocare al dispozitivului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. + MEGA trebuie să acceseze spațiul de stocare al aparatului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal @@ -53,7 +53,7 @@ Conflictul a fost rezolvat - Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest dispozitiv. Datele dvs. sunt întotdeauna în siguranță la noi. + Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest aparat. Datele dvs. sunt întotdeauna în siguranță la noi. Continuați @@ -69,7 +69,7 @@ Nicio problemă - Folderul dispozitivului + Folderul aparatului Folder MEGA @@ -81,7 +81,7 @@ Sincronizată - Folderul dispozitivului + Folderul aparatului Folder MEGA @@ -97,7 +97,7 @@ Numai Wi-Fi - Va trebui să configurați un folder local pe dispozitivul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud + Va trebui să configurați un folder local pe aparatul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud Monitorizarea sincronizărilor diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 94c8507ea1..e07ee62aa3 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -435,11 +435,11 @@ أضف تاغ Tag «#%1$s» - Existing tags + التاغات الموجودة - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + لا يمكن أن تحتوي التاغات بدون مسافات أو رموز غير أبجدية رقمية. سيتم عرض التاغات المكتوبة بأحرف كبيرة بأحرف صغيرة. - The maximum number of tags is %1$d + الحد الأقصى لعدد التاغات هو %1$d Tags must be %1$d characters or less @@ -447,7 +447,7 @@ لا يوجد وصف - Add to playlist + إضافة إلى قائمة التشغيل قائمة تشغيل جديدة @@ -455,17 +455,17 @@ سوف تفقدُ هذه الميزات - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + سيظل بإمكانك الوصول إلى هذه الميزات حتى انتهاء صلاحية باقة ميغا MEGA الخاصة بك بعد ذلك سيتم نقلك إلى حساب مجاني. - You are currently using %1s of storage, which you will risk losing. + أنت تستخدم حاليًا %1s من مساحة التخزين الذي ستخاطر بفقدانه. ميزة Free مساحة التخزين - - 20 GB + + %1s غيغابايت التحميل @@ -480,30 +480,30 @@ ترجيع حتى 30 يومًا (للعرض فقط) - - ما يصل إلى 180 يوماً + + يصل إلى %1s يوم MEGA VPN - Call &amp; meeting duration + مدة المكالمة والاجتماع ما يصل إلى 1 ساعة غير محدود - Call &amp; meeting participants + المشاركون في الاتصال والاجتماعات ما يصل إلى 100 غير محدود - Keep %1s + الإبقاء على %1s تابع الإلغاء الحد الأقصى 32 محرفاً - Hidden item + عنصر مخفي تم تعيين هذا العنصر ليكون مخفيًا. بمجرد مشاركة العنصر، سيتمكن أي شخص لديه الرابط من رؤيته. ستظل مخفية في السواقة السحابية الخاص بك. @@ -511,53 +511,53 @@ إلغاء الاشتراك - Reactivate subscription + إعادة تفعيل الاشتراك - Your subscription is not managed by Google + لا تتم إدارة اشتراكك بواسطة غوغل Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + هذا لأنك اشتركت في ميغا MEGA عبر آبل Apple. لإلغاء اشتراكك، ستحتاج إلى: - On a iOS Device + على جهاز أي أو إس iOS - 1. Open the Settings app. + 1. افتح [A]إعدادات[/A] التطبيق. - 2. Tap on your name. + 2. انقر على اسمك. - 3. Tap Subscriptions. + 3. انقر على [A]الإشتراكات[/A]. - 4. Tap your MEGA subscription. + 4. انقر على اشتراك ميغا MEGA الخاص بك. - 5. Tap Cancel subscription. + 5. انقر على [A]إلغاء الاشتراك[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]انقر هنا[/A] للحصول على تعليمات مفصلة حول كيفية إلغاء اشتراكك على الكمبيوتر أو أي جهاز آخر. تحتاج إلى إلغاء اشتراكك باستخدام متصفح الويب - You need to reactivate your subscription using a web browser + تحتاج إلى إعادة تفعيل اشتراكك باستخدام متصفح الويب - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + هذا لأنك اشتركت في ميغا MEGA في متصفح الويب الخاص بك. لإعادة تفعيل اشتراكك، ستحتاج إلى: هذا لأنك اشتركت في ميغا MEGA في متصفح الويب الخاص بك. لإلغاء اشتراكك، ستحتاج إلى: على الحاسوب - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. قم بزيارة [A]www.mega.nz[/A] في متصفح الويب الخاص بك. 2. قم بتسجيل الدخول إلى حساب ميغا MEGA الخاص بك. - 3. Click the main menu. + 3. انقر على القائمة الرئيسية. - 4. Click [A]Settings.[/A] + 4. انقر على [A]إعدادات.[/A] - 5. Click [A]Plan[/A]. + 5. انقر على [A]الباقة[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. انقر على [A]إلغاء الاشتراك[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. انقر على [A]إعادة تفعيل الاشتراك[/A]. على هاتف محمول - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. قم بزيارة [A]www.mega.nz[/A] في متصفح الويب الخاص بك. 2. قم بتسجيل الدخول إلى حساب ميغا MEGA الخاص بك. @@ -582,4 +582,6 @@ هناك مجلد بنفس الاسم المحارف التالية غير مسموح بها: %1$s + + مزامنة \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 3cf149af53..ef067f46c6 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -151,7 +151,7 @@ Freigaben - Dauer + Länge Alle Längen @@ -223,7 +223,7 @@ Begrenzt - Free + Kostenlos Fortfahren @@ -432,8 +432,8 @@ Free Speicher - - 20 GB + + %1s GB Transfer @@ -448,8 +448,8 @@ Wiederherstellen Bis zu 30 Tage (nur Ansicht) - - Bis zu 180 Tage + + Bis zu %1s Tage MEGA VPN @@ -457,13 +457,13 @@ Bis zu 1 Stunde - UNBEGRENZT + Unbegrenzt Anruf- und Meeting-Teilnehmer Bis zu 100 - UNBEGRENZT + Unbegrenzt %1s behalten @@ -487,15 +487,15 @@ Auf einem iOS-Gerät - 1. Öffnen Sie die App Einstellungen. + 1. Öffnen Sie die App [A]Einstellungen[/A]. 2. Tippen Sie auf Ihren Namen. - 3. Tippen Sie auf Abos. + 3. Tippen Sie auf [A]Abos[/A]. 4. Tippen Sie auf Ihr MEGA-Abonnement. - 5. Tippen Sie auf Abonnement kündigen. + 5. Tippen Sie auf [A]Abonnement kündigen[/A]. [A]Tippen Sie hier[/A] für detaillierte Anweisungen zum Kündigen Ihres Abonnements auf einem Computer oder einem anderen Gerät. @@ -550,4 +550,6 @@ Ein Ordner dieses Namens existiert bereits Die folgenden Zeichen sind nicht zulässig: %1$s + + Synchronisierung \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 3ce3697f2c..923077bf00 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -440,8 +440,8 @@ Free Almacenamiento - - 20 GB + + %1s GB Transferencia @@ -456,8 +456,8 @@ Rebobinar Hasta 30 días (solo lectura) - - Hasta 180 días + + Up to %1s days MEGA VPN @@ -465,13 +465,13 @@ Hasta 1 hora - Ilimitado + Ilimitadas Call &amp; meeting participants Hasta 100 - Ilimitado + Ilimitados Keep %1s @@ -493,17 +493,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -521,7 +521,7 @@ 2. Inicia sesión en tu cuenta de MEGA. - 3. Click the main menu. + 3. Haz clic en el menú principal. 4. Click [A]Settings.[/A] @@ -558,4 +558,6 @@ Ya existe una carpeta con el mismo nombre Los siguientes caracteres no están permitidos: %1$s + + Sincronizar \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index e5138b7c4c..43a85f363b 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -417,7 +417,7 @@ Le nombre maximal d’étiquettes est de %1$d - Les étiquettes doivent comprendre %1$d caractères ou moins + Tags must be %1$d characters or less Étiquettes @@ -440,8 +440,8 @@ Gratuit Espace de stockage - - 20 Go + + %1s Go Transferts @@ -456,8 +456,8 @@ Retour en arrière Jusqu’à 30 jours (visualiser seulement) - - Jusqu’à 180 jours + + Jusqu’à %1s jours RPV MEGA VPN @@ -495,15 +495,15 @@ Sur un appareil iOS - 1. Ouvrez l’appli Paramètres. + 1. Ouvrez l’appli [A]Paramètres[/A]. 2. Touchez votre nom. - 3. Touchez Abonnements. + 3.. Touchez [A]Abonnements[/A]. 4. Touchez votre abonnement MEGA. - 5. Touchez Annuler l’abonnement. + 5. Touchez [A]Annuler l’abonnement[/A]. [A]Touchez ici[/A] pour obtenir des instructions détaillées sur la manière d’annuler votre abonnement sur un ordinateur ou sur un autre appareil. @@ -558,4 +558,6 @@ Un dossier porte déjà ce nom Les caractères suivants ne sont pas autorisés : %1$s + + Synchronisations \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 7e41db1ac5..792758e7c3 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -427,8 +427,8 @@ Free Gudang - - 20 GB + + %1s GB Transfer @@ -443,8 +443,8 @@ Putar balik Hingga 30 hari (hanya lihat) - - Hingga 180 days + + Up to %1s days MEGA VPN @@ -480,17 +480,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -545,4 +545,6 @@ Sudah ada folder dengan nama yang sama Karakter berikut tidak diperbolehkan: %1$s + + Sinkronkan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 72506b841e..cc17085349 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -383,7 +383,7 @@ Non adesso - Uploads folder conflict + Conflitto tra cartelle di caricamento La cartella dei Caricamenti da fotocamera e la cartella dei caricamenti multimediali secondari non possono essere correlate tra loro. Scegli una cartella diversa. @@ -440,8 +440,8 @@ Free Archivio - - 20 GB + + %1s GB Trasferisci @@ -456,8 +456,8 @@ Ripristina Fino a 30 giorni (solo visualizzazione) - - Fino a 180 giorni + + Fino a %1s giorni MEGA VPN @@ -465,13 +465,13 @@ Fino a 1 ora - ILLIMITATA + Illimitata Partecipanti alle chiamate e ai meeting Fino a 100 - ILLIMITATA + Illimitati Mantieni %1s @@ -487,59 +487,59 @@ Annulla Iscrizione - Reactivate subscription + Riattiva l\’abbonamento - Your subscription is not managed by Google + Il tuo abbonamento non è gestito da Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Questo perché hai creato l\’abbonamento a MEGA tramite Apple. Per annullare l\’abbonamento, dovrai: - On a iOS Device + Su un dispositivo iOS - 1. Open the Settings app. + 1. Aprire l\’app [A]Impostazioni[/A]. - 2. Tap on your name. + 2. Toccare il tuo nome. - 3. Tap Subscriptions. + 3. Toccare [A]Abbonamenti[/A]. - 4. Tap your MEGA subscription. + 4. Toccare il tuo abbonamento MEGA. - 5. Tap Cancel subscription. + 5. Toccare [A]Annulla abbonamento[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Tocca qui[/A] per istruzioni dettagliate su come annullare l\’abbonamento su un computer o un altro dispositivo. Devi annullare l\’abbonamento utilizzando un web browser - You need to reactivate your subscription using a web browser + È necessario riattivare l\’abbonamento utilizzando un browser web - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Questo perché hai creato l\’abbonamento a MEGA nel tuo browser web. Per riattivare l\’abbonamento, dovrai: - Questo perché ti sei iscritto a MEGA tramite un web browser. Per annullare l\’abbonamento, dovrai: + Questo perché hai creato l\’abbonamento a MEGA tramite un web browser. Per annullare l\’abbonamento, dovrai: Su un computer - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visitare [A]www.mega.nz[/A] nel tuo browser web. 2. Accedi al tuo account MEGA. - 3. Click the main menu. + 3. Cliccare sul menu principale. - 4. Click [A]Settings.[/A] + 4. Cliccare su [A]Impostazioni[/A]. - 5. Click [A]Plan[/A]. + 5. Cliccare su [A]Piano[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Cliccare su [A]Annulla abbonamento[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Cliccare su [A]Riattiva abbonamento[/A]. Su un dispositivo mobile - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visitare [A]www.mega.nz[/A] nel tuo browser web. 2. Accedi al tuo account MEGA. 3. Tocca il tuo avatar. - 4. Tap [A]Cancel subscription[/A]. + 4. Toccare [A]Annulla abbonamento[/A]. Nessuna connessione Internet @@ -558,4 +558,6 @@ C\’è già una cartella con lo stesso nome I seguenti caratteri non sono ammessi: %1$s + + Sincronizza \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index c7ccccf523..b29be12184 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -424,8 +424,8 @@ 無料 ストレージ - - 20 GB + + %1s GB 転送 @@ -440,8 +440,8 @@ 巻き戻す 最大30日間(閲覧のみ) - - 最大180日 + + 最大%1s日 MEGA VPN @@ -479,15 +479,15 @@ iOSデバイスで - 1. 設定アプリを開く。 + 1.[A]設定[/A]アプリを開く。 2. 自分の名前をタップする。 - 3. 「サブスクリプション」をタップする。 + 3.「[A]定期購入[/A]」をタップする。 4. MEGAサブスクリプションをタップする。 - 5. 「サブスクリプションをキャンセル」をタップする。 + 5.[A]「サブスクリプションをキャンセル」[/A]をタップする。 [A]こちらをタップ[/A]すると、コンピューターまたはその他のデバイスでサブスクリプションをキャンセルする方法の詳細な手順が表示されます。 @@ -542,4 +542,6 @@ 同じ名前のフォルダがすでにあります 次の文字は許可されていません:%1$s + + 同期 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index e98812987b..1000b46cf7 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -91,7 +91,7 @@ 다시는 데이터를 잃지 마세요 - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + 당신의 데이터가 사고로 인해 변경되는 것을 막을 수 있도록, 파일과 폴더를 최대 180일까지 되돌려서 복원하세요. MEGA VPN @@ -275,7 +275,7 @@ 업그레이드 - Upload paused, device is not charging + 장치가 충전 중이 아니어서, 업로드가 일시정지 되었습니다 설정된 동기화가 없습니다 @@ -299,7 +299,7 @@ 해결된 문제 - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + 이 폴더는 동기화할 수 없습니다. 카메라 업로드를 이용하여 동기화를 설정하세요. 설명 @@ -361,53 +361,53 @@ Pro로 업그레이드 - Unlock the power to sync your mobile device to the cloud with our Pro plans. + Pro 요금제로 휴대 장치에서 클라우드로 동기화하는 기능을 잠금 해제하세요. 업그레이드 나중에 - Uploads folder conflict + 업로드 폴더 충돌 - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + 카메라 업로드 폴더와 보조 미디어 업로드 폴더는 서로 연관 관계가 있을 수 없습니다. 다른 폴더를 선택하세요. - Okay, got it + 알겠습니다 - This device doesn’t have an app to select folders + 이 장치에 폴더를 선택할 앱이 없습니다 - • Automatically sync the folders on your mobile device + • 휴대 장치의 폴더를 자동으로 동기화 - Your syncs have been paused. Syncing is a Pro plan feature. + 동기화가 일시정지 되었습니다. 동기화는 Pro 요금제 기능입니다. Ok - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + 당신의 MEGA Pro 요금제가 취소되어 동기화가 일시정지 되었습니다. 동기화를 계속하려면 업그레이드 하세요. 숨겨진 항목 Pro 전용 - Tags + 태그 - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + 데이터를 찾고 정리하는데에 도움을 받기 위해 태그를 이용하세요. 연도, 위치, 프로젝트, 또는 제목으로 태그해보세요. - Tag + 태그 - Add “#%1$s” tag + “#%1$s” 태그 추가함 - Existing tags + 존재하는 태그 - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + 태그는 공백 또는 영숫자가 아닌 기호를 포함할 수 없습니다. 대문자로 쓴 태그는 소문자로 표기됩니다. - The maximum number of tags is %1$d + 최대 태그 수는 %1$d입니다. Tags must be %1$d characters or less - Tags + 태그 설명 없음 - Add to playlist + 재생목록에 추가 새 재생 목록 @@ -415,17 +415,17 @@ 이러한 기능들을 잃게 됩니다 - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + MEGA 요금제가 만료되기 전까지는 이러한 기능들에 접근할 수 있지만, 그 이후에는 무료 계정으로 바뀝니다. - You are currently using %1s of storage, which you will risk losing. + 현재 저장소의 %1s만큼 이용 중이며, 손실의 위험이 있습니다. 기능 Free 저장소 - - 20 GB + + %1s GB 전송 @@ -440,24 +440,24 @@ 되감기 최대 30일 (보기 전용) - - 최대 180일 + + Up to %1s days MEGA VPN - Call &amp; meeting duration + 통화 &amp; 회의 길이 - Up to 1 hour + 최대 1시간 무제한 - Call &amp; meeting participants + 통화 &amp; 회의 참여자 - Up to 100 + 최대 100명 무제한 - Keep %1s + %1s 유지 취소 진행 @@ -471,59 +471,59 @@ 구독 취소 - Reactivate subscription + 구독 재활성화 - Your subscription is not managed by Google + 당신의 구독은 Google에서 관리되지 않습니다 - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + 이것은 당신이 Apple을 통해 MEGA를 구독하였기 때문입니다. 구독을 취소하려면, 다음을 하세요: - On a iOS Device + iOS 장치에서 - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. - 2. Tap on your name. + 2. 이름을 탭합니다. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. - 4. Tap your MEGA subscription. + 4. 당신의 MEGA 구독을 탭합니다. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + 컴퓨터 또는 다른 장치에서 구독을 취소하는 자세한 방법은 [A]여기를 탭[/A]하세요. - You need to cancel your subscription using a web browser + 웹 브라우저를 이용하여 구독을 취소하여야 합니다 - You need to reactivate your subscription using a web browser + 웹 브라우저를 이용하여 구독을 재활성화하여야 합니다 - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + 당신이 웹 브라우저에서 MEGA를 구독하였기 때문입니다.\n구독을 재활성화 하려면, 다음을 해야 합니다: - This is because you subscribed to MEGA in your web browser. To cancel your subscription, you will need to: + 당신이 웹 브라우저에서 MEGA를 구독하였기 때문입니다.\n구독을 취소 하려면, 다음을 해야 합니다: - On a computer + 컴퓨터에서 - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. 웹 브라우저에서 [A]www.mega.nz[/A]에 방문합니다. - 2. Log in to your MEGA account. + 2. MEGA 계정에 로그인합니다. - 3. Click the main menu. + 3. 메인 메뉴를 클릭합니다. - 4. Click [A]Settings.[/A] + 4. [A]설정[/A]을 클릭합니다. - 5. Click [A]Plan[/A]. + 5. [A]요금제[/A]를 클릭합니다 - 6. Click [A]Cancel subscription[/A]. + 6. [A]구독 취소[/A]를 클릭합니다. - 6. Click [A]Reactivate subscription[/A]. + 6. [A]구독 재활성화[/A]를 클릭합니다. - On a mobile device + 휴대 장치에서 - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. 웹 브라우저에서 [A]www.mega.nz[/A]에 방문합니다. - 2. Log in to your MEGA account. + 2. MEGA 계정에 로그인합니다. - 3. Tap on your avatar. + 3. 아바타를 탭합니다. - 4. Tap [A]Cancel subscription[/A]. + 4. [A]구독 취소[/A]를 탭합니다. 인터넷 연결이 없습니다 @@ -542,4 +542,6 @@ 이미 같은 이름을 가진 폴더가 존재합니다 다음의 문자는 허용되지 않습니다: %1$s + + 동기화 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 4ba75a7e78..e9a832a3d4 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -432,8 +432,8 @@ Free Opslag - - 20   GB + + %1s  GB Overdracht @@ -448,8 +448,8 @@ Terugspoelen Tot 30 dagen (alleen weergeven) - - Tot op 180 dagen + + Tot %1s dagen MEGA VPN @@ -457,13 +457,13 @@ Tot 1 uur - ONBEPERKT + Onbeperkt Deelnemers aan de oproep en vergadering Tot 100 - ONBEPERKT + Onbeperkt %1s behouden @@ -487,15 +487,15 @@ Op een iOS-apparaat - 1. Open de Instellingen-applicatie. + 1. Open het [A]Instellingen[/A] applicatie. 2. tik op uw naam. - 3. Tik op Abonnementen. + 3. Tik [A]Abonnementen[/A]. 4. tik op uw MEGA-abonnement. - 5. tik op Abonnement annuleren. + 5. Tik [A]Abonnement opzeggen[/A]. [A]Tik hier[/A] voor gedetailleerde instructies voor het opzeggen van uw abonnement op een computer of ander apparaat. @@ -550,4 +550,6 @@ Er is al een map met dezelfde naam De volgende tekens zijn niet toegestaan: %1$s + + Synchroniseren \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index a303e0e786..670bc7ea0d 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -448,8 +448,8 @@ Free Pojemności - - 20   GB + + %1s  GB Przesyłanie @@ -464,8 +464,8 @@ Przewiń Do 30 dni (tylko podgląd) - - Do 180 dni + + Do %1s dni MEGA VPN @@ -495,59 +495,59 @@ Anuluj subskrypcję - Reactivate subscription + Ponownie aktywuj subskrypcję - Your subscription is not managed by Google + Twoja subskrypcja nie jest zarządzana przez Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Dzieje się tak, ponieważ subskrybowałeś MEGA za pośrednictwem Apple. Aby anulować subskrypcję, musisz: - On a iOS Device + Na urządzeniu z systemem iOS - 1. Open the Settings app. + 1. Otwórz [A]Ustawienia[/A] aplikacji. - 2. Tap on your name. + 2. Kliknij w swoje imię. - 3. Tap Subscriptions. + 3. Kliknij [A]subskrypcje[/A]. - 4. Tap your MEGA subscription. + 4. Kliknij subskrypcja MEGA. - 5. Tap Cancel subscription. + 5. Kliknij [A]aby anulować subskrypcję[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Kliknij tutaj[/A] po szczegółowe instrukcje dotyczące anulowania subskrypcji na komputerze lub innym urządzeniu. Musisz anulować subskrypcję za pomocą przeglądarki internetowej - You need to reactivate your subscription using a web browser + Musisz ponownie aktywować subskrypcję za pomocą przeglądarki internetowej - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Dzieje się tak, ponieważ subskrybowałeś MEGA w swojej przeglądarce internetowej. Aby ponownie aktywować subskrypcję, musisz: Dzieje się tak, ponieważ subskrybowałeś MEGA w swojej przeglądarce internetowej. Aby anulować subskrypcja, musisz: Na komputerze - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Odwiedź [A]www.mega.nz[/A] w przeglądarce internetowej. 2. Zaloguj się na swoje konto MEGA. - 3. Click the main menu. + 3. Kliknij menu główne. - 4. Click [A]Settings.[/A] + 4. Kliknij [A]Ustawienia.[/A] - 5. Click [A]Plan[/A]. + 5. Kliknij [A]plan[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Kliknij [A]Anuluj subskrypcję[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Kliknij [A]Ponownie aktywuj subskrypcję[/A]. Na urządzeniu mobilnym - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Odwiedź [A]www.mega.nz[/A] w przeglądarce internetowej. 2. Zaloguj się na swoje konto MEGA. 3. Kliknij swojego awatara - 4. Tap [A]Cancel subscription[/A]. + 4. Kliknij [A]Anuluj subskrypcję[/A]. Brak połączenia z internetem @@ -566,4 +566,6 @@ Istnieje już katalog o takiej nazwie Następujące znaki są niedozwolone: %1$s + + Sync \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index d767a1dc18..72110de316 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -285,7 +285,7 @@ Agora não - Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[/A]. + Se você errou ao digitar o seu email, corrija e pressione [A]Reenviar[/A]. A sincronização foi pausada porque o seu plano do MEGA já não tem armazenamento disponível @@ -373,7 +373,7 @@ Mantenha a sua informação sincronizada e atualizada fazendo o upgrade a um dos nossos planos Pro. - Upgrade + Fazer upgrade Fazer o upgrade a Pro @@ -395,7 +395,7 @@ As suas sincronizações foram pausadas: sincronizar é um recurso dos planos Pro. - Ok + OK A sincronização foi pausada porque o seu plano Pro do MEGA foi cancelado. Faça upgrade para continuar sincronizando. @@ -437,15 +437,15 @@ Recurso - Free + Grátis Armazenamento - - 20 GB + + %1s GB Transferência - Limitado + Limitada Links protegidos por senha @@ -456,8 +456,8 @@ Retroceder Até 30 dias (somente visualização) - - Até 180 dias + + Até %1s dias MEGA VPN @@ -465,13 +465,13 @@ Até 1 hora - ILIMITADO + Ilimitada Participantes em reuniões e chamadas Até 100 - ILIMITADO + Ilimitado Manter o plano %1s @@ -495,15 +495,15 @@ Em um dispositivo iOS - 1. Acesse o aplicativo das Configurações. + 1. Acesse o aplicativo das [A]Configurações[/A]. 2. Pressione o seu nome. - 3. Pressione Assinaturas. + 3. Pressione [A]Assinaturas[/A]. 4. Selecione a sua assinatura do MEGA. - 5. Pressionar Cancelar assinatura. + 5. Pressione [A]Cancelar assinatura[/A]. [A]Veja aqui[/A] instruções detalhadas sobre como cancelar a sua assinatura em um computador ou outro dispositivo. @@ -541,7 +541,7 @@ 4. Pressione [A]Cancelar assinatura[/A]. - Não há conexão à Internet + Não há conexão à internet Criar nova pasta @@ -558,4 +558,6 @@ Já existe uma pasta com o mesmo nome Os seguintes caracteres não são permitidos: %1$s + + Sincronizar \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 579e94c162..36c6e0a826 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat Folderul ales nu poate fi sincronizat @@ -61,7 +61,7 @@ Unable to open state cache database - Spațiu de stocare insuficient pe dispozitiv + Spațiu de stocare insuficient pe aparat Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. @@ -71,9 +71,9 @@ Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din dispozitiv nu poate fi localizat chiar acum. Încercați din nou mai târziu. + Folderul din aparat nu poate fi localizat chiar acum. Încercați din nou mai târziu. - Folderul din dispozitiv dvs. nu poate fi localizat + Folderul din aparat dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați Asistența. @@ -85,7 +85,7 @@ Sincronizarea întreruptă, nivelul bateriei prea scăzut. Încărcați bateria pentru a relua sincronizarea. - Partajare de fișiere ușoară și sigură + Partajarea de fișiere ușoară și sigură Partajați fișiere mari datorită unei cote generoase de transfer și asigurați securitatea cu link-uri protejate prin parolă. @@ -291,7 +291,7 @@ Upgradează - Încărcarea este întreruptă, deoarece dispozitivul nu se încarcă + Încărcarea este întreruptă, deoarece aparatul nu se încarcă Nu este configurată nicio sincronizare @@ -305,11 +305,11 @@ Essential - Încărcările vor fi întrerupte până când începeți să încărcați dispozitivul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. + Încărcările vor fi întrerupte până când începeți să încărcați aparatul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. Nu este configurată nicio sincronizare - Sincronizați un folder local de pe dispozitiv cu un folder de pe MEGA. + Sincronizați un folder local de pe aparat cu un folder de pe MEGA. Adăugați o nouă sincronizare @@ -319,7 +319,7 @@ Descriere - Adaugă o descriere + Adăugați o descriere A fost adăugată o descriere @@ -327,9 +327,9 @@ Și acces la aceste beneficii interesante: - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil\n• Fără reclame + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil\n• Fără reclame - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil Nicio problemă rezolvată @@ -349,7 +349,7 @@ Adăugați contacte, creați o rețea, colaborați și efectuați apeluri vocale și video fără a părăsi MEGA. - Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. Întâlnire video criptată cu zero cunoștințe. @@ -377,7 +377,7 @@ Upgradează la Pro - Abonamentele noastre Pro dezlănțuie puterea de sincronizare a dispozitivului dvs. mobil cu MEGA. + Abonamentele noastre Pro dezlănțuie puterea de sincronizare a aparatului dvs. mobil cu MEGA. Upgradează @@ -389,9 +389,9 @@ Bine, am înțeles - Acest dispozitiv nu are o aplicație care să selecteze foldere + Acest aparat nu are o aplicație care să selecteze foldere - • Sincronizați automat folderele de pe dispozitivul mobil + • Sincronizați automat folderele de pe aparatul mobil Sincronizările dvs. au fost întrerupte. Sincronizarea este o funcție a abonamentelor Pro. @@ -440,8 +440,8 @@ Gratuit Spațiu de stocare - - 20 GB + + %1s GB Transferuri @@ -456,8 +456,8 @@ Derulare înapoi Până la 30 de zile (numai vizualizare) - - Până la 180 de zile + + Până la %1s de zile MEGA VPN @@ -493,19 +493,19 @@ V-ați abonat la MEGA cu Apple. Pentru a vă anula abonamentul, trebuie să: - Pe un dispozitiv iOS + Pe un aparat iOS - 1. Deschideți aplicația Setări. + 1. Deschideți aplicația [A]Setări[/A]. 2. Atingeți numele dvs. - 3. Atingeți Abonamente. + 3. Atingeți [A]Abonamente[/A]. 4. Atingeți abonamentul MEGA. - 5. Atingeți Anulați abonamentul. + 5. Atingeți [A]Anulați abonamentul[/A]. - [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt dispozitiv. + [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt aparat. Trebuie să vă anulați abonamentul folosind un browser web @@ -531,7 +531,7 @@ 6. Dați clic pe [A]Reactivați abonamentul[/A]. - Pe un dispozitiv mobil + Pe un aparat mobil 1. Accesați [A]www.mega.nz[/A] în browserul web. @@ -558,4 +558,6 @@ Există deja un folder cu același nume Următoarele caractere nu sunt permise: %1$s + + Sincronizează \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 455f4f353e..001e4ebddc 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -448,8 +448,8 @@ Free Хранилище - - 20 ГБ + + %1s ГБ Передача данных @@ -464,8 +464,8 @@ Перемотка До 30 дней (только просмотр) - - До 180 дней + + До %1s дней MEGA VPN @@ -503,15 +503,15 @@ На устройстве iOS - 1. Откройте приложение «Настройки». + 1. Откройте приложение [A]«Настройки»[/A]. 2. Нажмите на своё имя. - 3. Нажмите «Подписки». + 3. Нажмите [A]«Подписки»[/A]. 4. Нажмите на свою подписку MEGA. - 5. Нажмите «Отменить подписку». + 5. Нажмите [A]«Отменить подписку»[/A]. [A]Нажмите здесь[/A], чтобы получить подробные инструкции о том, как отменить подписку на компьютере или другом устройстве. @@ -566,4 +566,6 @@ Папка с таким именем уже существует Следующие символы не допускаются: %1$s + + Синхронизация \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index e9d239f863..1ce7fc0369 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -424,8 +424,8 @@ Free พื้นที่เก็บข้อมูล - - 20 GB + + %1s GB ถ่ายโอน @@ -440,8 +440,8 @@ มีกระบวนการย้อนกลับไฟล์ได้ สูงสุด 30 วัน (ดูอย่างเดียว) - - นานถึง 180 วัน + + Up to %1s days MEGA VPN @@ -477,17 +477,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -542,4 +542,6 @@ มีโฟลเดอร์ชื่อเดียวกันอยู่แล้ว ไม่อนุญาตให้ใช้อักขระต่อไปนี้: %1$s + + ซิงค์ \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 4bbb5394b3..387b0d8cb6 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -424,8 +424,8 @@ Free Lưu trữ - - 20 GB + + %1s GB Truyền Tải @@ -440,8 +440,8 @@ Tua lại Lên đến 30 ngày (chỉ được xem) - - Lên đến 180 ngày + + Up to %1s days MEGA VPN @@ -449,13 +449,13 @@ Lên đến 1 tiếng - KHÔNG GIỚI HẠN + Không giới hạn Số người tham gia cuộc gọi $ cuộc họp Lên đến 100 người - KHÔNG GIỚI HẠN + Không giới hạn Giữ %1s @@ -471,59 +471,59 @@ Hủy Gói Đăng Ký Dịch Vụ - Reactivate subscription + Kích hoạt lại gói đăng ký - Your subscription is not managed by Google + Gói đăng ký của bạn không có quản lý bởi Google. - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Điều này là do bạn đã đăng ký MEGA thông qua Apple. Để hủy gói đăng ký, bạn sẽ cần: - On a iOS Device + Trên thiết bị iOS - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. - 2. Tap on your name. + 2. Chạm vào tên của bạn. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. - 4. Tap your MEGA subscription. + 4. Chạm vào gói đăng ký MEGA. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Chạm vào đây[/A] để được hướng dẫn chi tiết về cách hủy gói đăng ký của bạn trên máy tính hoặc loại thiết bị khác. Bạn cần phải hủy gói đăng ký của mình bằng trình duyệt web - You need to reactivate your subscription using a web browser + Bạn cần phải sử dụng trình duyệt web để kích hoạt lại gói đăng ký của mình - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Điều này là do bạn đã đăng ký gói MEGA bằng trình duyệt web. Để hủy gói đăng ký, bạn sẽ cần: Điều này là do bạn đã đăng ký gói MEGA trong trình duyệt web của mình. Để hủy gói đăng ký, bạn sẽ cần: Trên máy tính - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Ghé trang [A]www.mega.nz[/A] trong trình duyệt web của bạn. 2. Đăng nhập vào tài khoản MEGA của bạn. - 3. Click the main menu. + 3. Click vào menu chính. - 4. Click [A]Settings.[/A] + 4. Click vào [A]Thiết Đặt.[/A] - 5. Click [A]Plan[/A]. + 5. Click vào [A]Gói[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Click vào [A]Hủy đăng ký[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Click vào [A]Kích hoạt lại gói đăng ký[/A]. Trên thiết bị di động - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Ghé trang [A]www.mega.nz[/A] trong trình duyệt web của bạn. 2. Đăng nhập vào tài khoản MEGA của bạn. 3. Chạm vào ảnh đại diện của bạn. - 4. Tap [A]Cancel subscription[/A]. + 4. Chạm vào [A]Hủy đăng ký[/A]. Không có kết nối internet @@ -542,4 +542,6 @@ Đã có một thư mục với cái tên này rồi Các ký tự này không được phép sử dụng: %1$s + + Đồng bộ \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 56d78af611..b05be66800 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -424,8 +424,8 @@ 免费 存储空间 - - 20 GB + + %1s GB 传输 @@ -440,8 +440,8 @@ 还原 最多30天(仅限查看) - - 最长可达180天 + + 长达%1s天 MEGA VPN @@ -479,15 +479,15 @@ 在iOS设备上 - 1. 打开应用程序的设置。 + 1.打开应用程序的[A]设置[/A]。 2. 点按您的名字。 - 3. 点按订阅。 + 3.点按[A]订阅[/A]。 4. 点按您的MEGA订阅。 - 5. 点按取消订阅。 + 5.点按[A]取消订阅[/A]。 [A]点按这里[/A]了解有关如何在计算机或其它设备上取消订阅的详细说明。 @@ -542,4 +542,6 @@ 已经有一个相同名称的文件夹 不允许使用这些字符:%1$s + + 同步 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index f9a4a95d8a..646e4aa583 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -424,8 +424,8 @@ 免費 儲存空間 - - 20 GB + + %1s GB 傳輸 @@ -440,8 +440,8 @@ 回溯 最多30天(僅能檢視) - - 長達180天 + + 長達%1s天 MEGA VPN @@ -479,15 +479,15 @@ 在iOS裝置上 - 1. 開啟設定應用程式。 + 1.打開應用程式的[A]設定[/A]。 2. 點選您的名稱。 - 3. 點選訂閱。 + 3.點選[A]訂閱[/A]。 4. 點選您的MEGA訂閱。 - 5. 點選取消訂閱。 + 5.點選[A]取消訂閱[/A]。 [A]點選此處[/A]以取得如何在電腦或其它裝置上取消訂閱的詳細說明。 @@ -542,4 +542,6 @@ 已經有一個同名的資料夾 不允許使用以下字元:%1$s + + 同步 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 88270a104c..fb6ef8c441 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -485,7 +485,7 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device 1. Open the [A]Settings[/A] app. From 87a8e3d5307e8267fce2bbba18b8e13ebc058fc6 Mon Sep 17 00:00:00 2001 From: Erick Sumargo Date: Fri, 26 Jul 2024 08:37:39 +0700 Subject: [PATCH 181/261] Fix TRAN-489: NPE - ManagerActivity.onPostResume --- .../main/java/mega/privacy/android/app/main/ManagerActivity.kt | 2 +- build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index 05128e3bc4..7fb3c378b1 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -2606,7 +2606,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf showSnackbar(Constants.MESSAGE_SNACKBAR_TYPE, null, chatId) } } - intent.action = null + intent?.action = null intent = null } resetNavigationViewMenu(bottomNavigationView.menu) diff --git a/build.gradle.kts b/build.gradle.kts index 2cbbb258aa..ba08228e1c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,7 +78,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "13.6" +extra["appVersion"] = "13.6.1" // Sdk and tools extra["compileSdkVersion"] = 35 From 171fa8ba12301dd0b57a65714c9781a021304deb Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 26 Jul 2024 09:59:39 +0800 Subject: [PATCH 182/261] T17059408 Scenario 3: Duplicated name in the playlist T17059409 Scenario 4: Name a playlist with characters are not allowed --- .../videosection/view/playlist/VideoPlaylistsView.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt index ad8a5c9ad4..e25e4710d0 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt @@ -94,6 +94,9 @@ internal fun VideoPlaylistsView( if (showRenameVideoPlaylistDialog) { showRenameVideoPlaylistDialog = false } + if (showCreateVideoPlaylistDialog) { + showCreateVideoPlaylistDialog = false + } } val snackBarHostState = remember { SnackbarHostState() } @@ -182,7 +185,6 @@ internal fun VideoPlaylistsView( }, onDialogPositiveButtonClicked = { titleOfNewVideoPlaylist -> onCreateDialogPositiveButtonClicked(titleOfNewVideoPlaylist) - showCreateVideoPlaylistDialog = false }, ) { isInputTitleValid From ff058f5de5d67557c5e7fd41afec91af26f581ff Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 26 Jul 2024 10:18:58 +0800 Subject: [PATCH 183/261] T17059427 Add the audio mini controller in zip browser --- .../zipbrowser/ZipBrowserComposeActivity.kt | 29 ++++++++++++++++++- .../zipbrowser/view/ZipBrowserScreen.kt | 3 ++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/ZipBrowserComposeActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/ZipBrowserComposeActivity.kt index d14e8a80de..0c01757980 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/ZipBrowserComposeActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/ZipBrowserComposeActivity.kt @@ -7,7 +7,12 @@ import android.os.Bundle import android.widget.Toast import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.constraintlayout.compose.ConstraintLayout +import androidx.constraintlayout.compose.Dimension import androidx.core.content.FileProvider import androidx.core.net.toUri import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -29,6 +34,7 @@ import mega.privacy.android.app.presentation.imagepreview.fetcher.ZipImageNodeFe import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewFetcherSource import mega.privacy.android.app.presentation.imagepreview.model.ImagePreviewMenuSource import mega.privacy.android.app.presentation.pdfviewer.PdfViewerActivity +import mega.privacy.android.app.presentation.search.view.MiniAudioPlayerView import mega.privacy.android.app.presentation.zipbrowser.view.ZipBrowserScreen import mega.privacy.android.app.textEditor.TextEditorActivity import mega.privacy.android.app.utils.Constants @@ -84,7 +90,28 @@ class ZipBrowserComposeActivity : PasscodeActivity() { initialValue = ThemeMode.System ) OriginalTempTheme(isDark = themeMode.isDarkMode()) { - ZipBrowserScreen(viewModel = viewModel) + ConstraintLayout( + modifier = Modifier.fillMaxSize() + ) { + val (audioPlayer, audioSectionComposeView) = createRefs() + MiniAudioPlayerView( + modifier = Modifier + .constrainAs(audioPlayer) { + bottom.linkTo(parent.bottom) + } + .fillMaxWidth(), + lifecycle = lifecycle, + ) + ZipBrowserScreen( + modifier = Modifier + .constrainAs(audioSectionComposeView) { + top.linkTo(parent.top) + bottom.linkTo(audioPlayer.top) + height = Dimension.fillToConstraints + } + .fillMaxWidth(), + viewModel = viewModel) + } } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/view/ZipBrowserScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/view/ZipBrowserScreen.kt index 6a6b2185a2..2f9a39ef63 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/view/ZipBrowserScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/zipbrowser/view/ZipBrowserScreen.kt @@ -2,11 +2,13 @@ package mega.privacy.android.app.presentation.zipbrowser.view import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import mega.privacy.android.app.presentation.zipbrowser.ZipBrowserViewModel @Composable internal fun ZipBrowserScreen( + modifier: Modifier, viewModel: ZipBrowserViewModel, ) { @@ -14,6 +16,7 @@ internal fun ZipBrowserScreen( val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher ZipBrowserView( + modifier = modifier, items = uiState.items, parentFolderName = uiState.parentFolderName, folderDepth = uiState.folderDepth, From a695b2d83eeeb5b1b56161ac9192ca0a465096e5 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Fri, 26 Jul 2024 17:02:39 +1200 Subject: [PATCH 184/261] Temporarily do not upload release notes to Google Play Alpha channel --- jenkinsfile/android_release.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkinsfile/android_release.groovy b/jenkinsfile/android_release.groovy index aaaf1c0df5..dbee7d969d 100644 --- a/jenkinsfile/android_release.groovy +++ b/jenkinsfile/android_release.groovy @@ -462,7 +462,7 @@ pipeline { rolloutPercentage: '0', additionalVersionCodes: '487,233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", - recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), +// recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), releaseName: common.readAppVersion1() } } From cd4d3f1f33c1a36a29dbc77c1a4af3c30ec5aa85 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Sat, 27 Jul 2024 14:54:43 +0700 Subject: [PATCH 185/261] AND-19225: Fix crash CameraActivity.setResult (cherry picked from commit c1568955056e67dd23cdde6a29707e2214cdcf9c) --- .../java/mega/privacy/android/app/camera/CameraActivity.kt | 1 - .../mega/privacy/android/app/camera/CameraCaptureScreen.kt | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/camera/CameraActivity.kt b/app/src/main/java/mega/privacy/android/app/camera/CameraActivity.kt index 1f4291057f..b41bbf42da 100644 --- a/app/src/main/java/mega/privacy/android/app/camera/CameraActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/camera/CameraActivity.kt @@ -51,7 +51,6 @@ internal class CameraActivity : AppCompatActivity() { private fun setResult(uri: Uri?) { uri?.let { - contentResolver.takePersistableUriPermission(it, Intent.FLAG_GRANT_READ_URI_PERMISSION) setResult(RESULT_OK, Intent().apply { putExtra(EXTRA_URI, uri) }) } finish() diff --git a/app/src/main/java/mega/privacy/android/app/camera/CameraCaptureScreen.kt b/app/src/main/java/mega/privacy/android/app/camera/CameraCaptureScreen.kt index b2f884a608..3b5e0262f6 100644 --- a/app/src/main/java/mega/privacy/android/app/camera/CameraCaptureScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/camera/CameraCaptureScreen.kt @@ -1,6 +1,7 @@ package mega.privacy.android.app.camera import android.Manifest +import android.content.Intent import android.net.Uri import android.view.OrientationEventListener import androidx.activity.compose.rememberLauncherForActivityResult @@ -90,7 +91,10 @@ internal fun CameraCaptureScreen( rememberLauncherForActivityResult( contract = ActivityResultContracts.PickVisualMedia() ) { - it?.let(onFinish) + it?.let { + context.contentResolver.takePersistableUriPermission(it, Intent.FLAG_GRANT_READ_URI_PERMISSION) + onFinish(it) + } } LaunchedEffect(isRecording) { From 41ec771764f12da47b7f795d4d696623a2218297 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 29 Jul 2024 16:48:51 +0800 Subject: [PATCH 186/261] T17059427 Fix the issue regarding the shuffle mode when open the audio player from the zip browser --- .../app/mediaplayer/AudioPlayerFragment.kt | 12 ++++++++-- .../app/mediaplayer/AudioPlayerViewHolder.kt | 23 +++++++++++++++++-- .../mediaplayer/facade/MediaPlayerFacade.kt | 8 ++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerFragment.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerFragment.kt index 5f18f211f6..a03a7bfdd3 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerFragment.kt @@ -154,7 +154,11 @@ class AudioPlayerFragment : Fragment() { viewLifecycleOwner.collectFlow(it.playlistUpdate()) { info -> Timber.d("MediaPlayerService observed playlist ${info.first.size} items") - playerViewHolder?.togglePlaylistEnabled(requireContext(), info.first) + playerViewHolder?.togglePlaylistEnabled( + requireContext(), + info.first, + it.shuffleEnabled() + ) } viewLifecycleOwner.collectFlow(it.retryUpdate()) { isRetry -> @@ -196,7 +200,11 @@ class AudioPlayerFragment : Fragment() { } serviceViewModelGateway?.run { - viewHolder.setupPlaylistButton(requireContext(), getPlaylistItems()) { + viewHolder.setupPlaylistButton( + requireContext(), + getPlaylistItems(), + shuffleEnabled() + ) { findNavController().let { viewLifecycleOwner.lifecycleScope.launch { if (it.currentDestination?.id == R.id.audio_main_player) { diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerViewHolder.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerViewHolder.kt index 978432d16f..64a20ff2c5 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerViewHolder.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/AudioPlayerViewHolder.kt @@ -143,9 +143,10 @@ class AudioPlayerViewHolder(val binding: FragmentAudioPlayerBinding) { fun setupPlaylistButton( context: Context, playlistItems: List, + shuffleEnabled: Boolean, openPlaylist: () -> Unit, ) { - togglePlaylistEnabled(context, playlistItems) + togglePlaylistEnabled(context, playlistItems, shuffleEnabled) playlist.setOnClickListener { openPlaylist() @@ -158,7 +159,11 @@ class AudioPlayerViewHolder(val binding: FragmentAudioPlayerBinding) { * @param context Context * @param playlistItems the new playlist */ - fun togglePlaylistEnabled(context: Context, playlistItems: List) { + fun togglePlaylistEnabled( + context: Context, + playlistItems: List, + shuffleEnabled: Boolean, + ) { playlist.isEnabled = playlistItems.size > SINGLE_PLAYLIST_SIZE playlist.setColorFilter( context.getColor( @@ -170,6 +175,20 @@ class AudioPlayerViewHolder(val binding: FragmentAudioPlayerBinding) { ) ) shuffle.isEnabled = playlist.isEnabled + shuffle.setColorFilter( + context.getColor( + when { + !playlist.isEnabled -> + R.color.grey_050_grey_800 + + shuffleEnabled -> + R.color.teal_300_teal_600 + + else -> + R.color.dark_grey_white + } + ) + ) } /** diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/facade/MediaPlayerFacade.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/facade/MediaPlayerFacade.kt index 62bfd242b4..c995581490 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/facade/MediaPlayerFacade.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/facade/MediaPlayerFacade.kt @@ -226,7 +226,13 @@ class MediaPlayerFacade @Inject constructor( } override fun setShuffleOrder(newShuffleOrder: ShuffleOrder) { - exoPlayer.setShuffleOrder(newShuffleOrder) + if (exoPlayer.shuffleModeEnabled && newShuffleOrder.length > 2) { + runCatching { + exoPlayer.setShuffleOrder(newShuffleOrder) + }.recover { + Timber.e(it) + } + } } override fun getCurrentPlayingPosition(): Long = exoPlayer.currentPosition From 2d737479b992116cf2a78aec326a56856b955830 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Tue, 30 Jul 2024 12:26:17 +1200 Subject: [PATCH 187/261] Revert "Temporarily do not upload release notes to Google Play Alpha channel" This reverts commit a695b2d83eeeb5b1b56161ac9192ca0a465096e5. --- jenkinsfile/android_release.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkinsfile/android_release.groovy b/jenkinsfile/android_release.groovy index dbee7d969d..aaaf1c0df5 100644 --- a/jenkinsfile/android_release.groovy +++ b/jenkinsfile/android_release.groovy @@ -462,7 +462,7 @@ pipeline { rolloutPercentage: '0', additionalVersionCodes: '487,233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", -// recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), + recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), releaseName: common.readAppVersion1() } } From 2fef3495fd077bd607fc2d29b3f55e88d65c30a5 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 30 Jul 2024 01:47:57 +1200 Subject: [PATCH 188/261] AND-19191: Fix dark setting screen when opening meeting --- app/src/main/AndroidManifest.xml | 2 +- .../android/app/meeting/activity/MeetingActivity.kt | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 28938de1e2..9439f1886a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -508,7 +508,7 @@ android:launchMode="singleTop" /> Date: Tue, 30 Jul 2024 02:52:30 +1200 Subject: [PATCH 189/261] MEET-4173: Fix record view visibility and refactor audio and video enable logic --- .../activity/MeetingActivityViewModel.kt | 34 ++++++----- .../meeting/fragments/InMeetingFragment.kt | 57 ++++++++++++------- .../meeting/listeners/GroupVideoListener.kt | 46 ++++++++------- 3 files changed, 76 insertions(+), 61 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt index 17903006fd..af3be72024 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/activity/MeetingActivityViewModel.kt @@ -63,16 +63,16 @@ import mega.privacy.android.data.gateway.DeviceGateway import mega.privacy.android.domain.entity.ChatRequestParamType import mega.privacy.android.domain.entity.ChatRoomPermission import mega.privacy.android.domain.entity.StorageState -import mega.privacy.android.domain.entity.call.ChatCall -import mega.privacy.android.domain.entity.chat.ChatParticipant -import mega.privacy.android.domain.entity.chat.ChatRoomChange -import mega.privacy.android.domain.entity.chat.ScheduledMeetingChanges -import mega.privacy.android.domain.entity.contacts.InviteContactRequest import mega.privacy.android.domain.entity.call.CallType +import mega.privacy.android.domain.entity.call.ChatCall import mega.privacy.android.domain.entity.call.ChatCallChanges import mega.privacy.android.domain.entity.call.ChatCallStatus import mega.privacy.android.domain.entity.call.ChatCallTermCodeType import mega.privacy.android.domain.entity.call.ChatSessionChanges +import mega.privacy.android.domain.entity.chat.ChatParticipant +import mega.privacy.android.domain.entity.chat.ChatRoomChange +import mega.privacy.android.domain.entity.chat.ScheduledMeetingChanges +import mega.privacy.android.domain.entity.contacts.InviteContactRequest import mega.privacy.android.domain.entity.meeting.MeetingParticipantNotInCallStatus import mega.privacy.android.domain.entity.meeting.ParticipantsSection import mega.privacy.android.domain.entity.node.NodeId @@ -86,6 +86,14 @@ import mega.privacy.android.domain.usecase.RemoveFromChat import mega.privacy.android.domain.usecase.SetOpenInvite import mega.privacy.android.domain.usecase.account.GetCurrentSubscriptionPlanUseCase import mega.privacy.android.domain.usecase.account.MonitorStorageStateEventUseCase +import mega.privacy.android.domain.usecase.call.AllowUsersJoinCallUseCase +import mega.privacy.android.domain.usecase.call.AnswerChatCallUseCase +import mega.privacy.android.domain.usecase.call.BroadcastCallEndedUseCase +import mega.privacy.android.domain.usecase.call.GetCallIdsOfOthersCallsUseCase +import mega.privacy.android.domain.usecase.call.GetChatCallUseCase +import mega.privacy.android.domain.usecase.call.HangChatCallUseCase +import mega.privacy.android.domain.usecase.call.MonitorCallEndedUseCase +import mega.privacy.android.domain.usecase.call.RingIndividualInACallUseCase import mega.privacy.android.domain.usecase.chat.CreateChatLinkUseCase import mega.privacy.android.domain.usecase.chat.IsEphemeralPlusPlusUseCase import mega.privacy.android.domain.usecase.chat.MonitorChatRoomUpdatesUseCase @@ -97,22 +105,14 @@ import mega.privacy.android.domain.usecase.contact.InviteContactWithHandleUseCas import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase import mega.privacy.android.domain.usecase.login.LogoutUseCase import mega.privacy.android.domain.usecase.login.MonitorFinishActivityUseCase -import mega.privacy.android.domain.usecase.call.AllowUsersJoinCallUseCase -import mega.privacy.android.domain.usecase.call.AnswerChatCallUseCase -import mega.privacy.android.domain.usecase.call.BroadcastCallEndedUseCase -import mega.privacy.android.domain.usecase.call.GetCallIdsOfOthersCallsUseCase import mega.privacy.android.domain.usecase.meeting.EnableOrDisableAudioUseCase import mega.privacy.android.domain.usecase.meeting.EnableOrDisableVideoUseCase -import mega.privacy.android.domain.usecase.call.GetChatCallUseCase -import mega.privacy.android.domain.usecase.call.HangChatCallUseCase -import mega.privacy.android.domain.usecase.call.MonitorCallEndedUseCase +import mega.privacy.android.domain.usecase.meeting.GetScheduledMeetingByChatUseCase import mega.privacy.android.domain.usecase.meeting.MonitorChatCallUpdatesUseCase import mega.privacy.android.domain.usecase.meeting.MonitorChatSessionUpdatesUseCase import mega.privacy.android.domain.usecase.meeting.MonitorScheduledMeetingUpdatesUseCase import mega.privacy.android.domain.usecase.meeting.MuteAllPeersUseCase import mega.privacy.android.domain.usecase.meeting.MutePeersUseCase -import mega.privacy.android.domain.usecase.call.RingIndividualInACallUseCase -import mega.privacy.android.domain.usecase.meeting.GetScheduledMeetingByChatUseCase import mega.privacy.android.domain.usecase.meeting.StartVideoDeviceUseCase import mega.privacy.android.domain.usecase.network.IsConnectedToInternetUseCase import mega.privacy.android.domain.usecase.network.MonitorConnectivityUseCase @@ -1349,13 +1349,12 @@ class MeetingActivityViewModel @Inject constructor( */ private fun enableVideo(enable: Boolean) { state.value.currentCall?.apply { - val enableVideo = enable && !hasLocalVideo if (enable && hasLocalVideo) { return } viewModelScope.launch { runCatching { - enableOrDisableVideoUseCase(chatId = chatId, enable = enableVideo) + enableOrDisableVideoUseCase(chatId = chatId, enable = enable) }.onFailure { exception -> Timber.e(exception) }.onSuccess { chatRequest -> @@ -1376,10 +1375,9 @@ class MeetingActivityViewModel @Inject constructor( */ private fun enableAudio(enable: Boolean) { state.value.currentCall?.apply { - val enableAudio = enable && !hasLocalAudio viewModelScope.launch { runCatching { - enableOrDisableAudioUseCase(chatId, enableAudio) + enableOrDisableAudioUseCase(chatId, enable) }.onFailure { exception -> Timber.e(exception) } diff --git a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt index 775494046f..2fa54fb04d 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt @@ -1776,6 +1776,11 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn it.removeTextureView() } } + removePictureInPictureListener() + inMeetingViewModel.removeListeners() + } + + private fun removePictureInPictureListener() { inMeetingViewModel.state.value.run { if (isPictureInPictureFeatureFlagEnabled && !isInPipMode) { pictureCallFragment?.let { @@ -1785,9 +1790,6 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn } } } - - - inMeetingViewModel.removeListeners() } /** @@ -1823,10 +1825,16 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn speakerViewCallFragment = null } } + removePictureInPictureFragment() + } + + private fun removePictureInPictureFragment() { inMeetingViewModel.state.value.run { + Timber.d("Remove Picture Call Fragment isInPipMode = $isInPipMode") if (isPictureInPictureFeatureFlagEnabled && !isInPipMode) { pictureCallFragment?.let { - if (it.isAdded) { + if (isAdded) { + Timber.d("Removing Pip Fragment") removeChildFragment(it) pictureCallFragment = null } @@ -1867,35 +1875,40 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn checkSwapCameraMenuItemVisibility() } + /** + * hide views that are not necessary for Picture in Picture Mode + * show views when not in Picture in Picture Mode + */ + private fun hideOrShowHelperViews(shouldHide: Boolean) { + val visibility = if (shouldHide) View.GONE else View.VISIBLE + toolbar.visibility = visibility + binding.selfFeedFloatingWindowContainer.visibility = visibility + binding.meetingContainer.visibility = visibility + binding.bottomFloatingPanel.meetingActionButtons.visibility = visibility + binding.bottomFloatingPanel.backgroundMask.visibility = visibility + binding.bottomFloatingPanel.participantsComposeView.visibility = visibility + binding.bottomFloatingPanel.indicator.visibility = visibility + if (shouldHide.not()) { + removePictureInPictureFragment() + } + } + /** * Control the UI of the call, whether one-to-one or meeting */ private fun checkChildFragments() { - if (inMeetingViewModel.state.value.isInPipMode) { + if (inMeetingViewModel.state.value.isPictureInPictureFeatureFlagEnabled && inMeetingViewModel.state.value.isInPipMode) { if (pictureCallFragment == null) { removeListenersAndFragments() pictureCallFragment = PictureInPictureCallFragment.newInstance().apply { loadChildFragment(R.id.pip_container, this, PictureInPictureCallFragment.TAG) } } - toolbar.visibility = View.GONE - binding.recIndicator.visibility = View.GONE - binding.selfFeedFloatingWindowContainer.visibility = View.GONE - binding.meetingContainer.visibility = View.GONE - binding.bottomFloatingPanel.meetingActionButtons.visibility = View.GONE - binding.bottomFloatingPanel.backgroundMask.visibility = View.GONE - binding.bottomFloatingPanel.participantsComposeView.visibility = View.GONE - binding.bottomFloatingPanel.indicator.visibility = View.GONE + hideOrShowHelperViews(shouldHide = true) } else { - toolbar.visibility = View.VISIBLE - binding.recIndicator.visibility = View.VISIBLE - binding.selfFeedFloatingWindowContainer.visibility = View.VISIBLE - binding.meetingContainer.visibility = View.VISIBLE - binding.meetingContainer.visibility = View.VISIBLE - binding.bottomFloatingPanel.meetingActionButtons.visibility = View.VISIBLE - binding.bottomFloatingPanel.backgroundMask.visibility = View.VISIBLE - binding.bottomFloatingPanel.participantsComposeView.visibility = View.VISIBLE - binding.bottomFloatingPanel.indicator.visibility = View.VISIBLE + if (inMeetingViewModel.state.value.isPictureInPictureFeatureFlagEnabled) { + hideOrShowHelperViews(shouldHide = false) + } inMeetingViewModel.state.value.call?.apply { binding.reconnecting.isVisible = false when (status) { diff --git a/app/src/main/java/mega/privacy/android/app/meeting/listeners/GroupVideoListener.kt b/app/src/main/java/mega/privacy/android/app/meeting/listeners/GroupVideoListener.kt index 2d7b67c97d..b6d02ea601 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/listeners/GroupVideoListener.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/listeners/GroupVideoListener.kt @@ -7,6 +7,7 @@ import mega.privacy.android.app.utils.Constants.INVALID_DIMENSION import mega.privacy.android.app.utils.VideoCaptureUtils import nz.mega.sdk.MegaChatApiJava import nz.mega.sdk.MegaChatVideoListenerInterface +import timber.log.Timber import java.nio.ByteBuffer class GroupVideoListener( @@ -14,7 +15,7 @@ class GroupVideoListener( peerId: Long, clientId: Long, isMe: Boolean, - isScreenShared: Boolean + isScreenShared: Boolean, ) : MegaChatVideoListenerInterface { var width = 0 @@ -29,30 +30,33 @@ class GroupVideoListener( chatid: Long, width: Int, height: Int, - byteBuffer: ByteArray + byteBuffer: ByteArray, ) { + kotlin.runCatching { + if (width == 0 || height == 0) { + return + } - if (width == 0 || height == 0) { - return - } - - if (this.width != width || this.height != height) { - this.width = width - this.height = height - val viewWidth = textureView!!.width - val viewHeight = textureView!!.height - if (viewWidth != 0 && viewHeight != 0) { - bitmap = localRenderer!!.createBitmap(width, height) - } else { - this.width = INVALID_DIMENSION - this.height = INVALID_DIMENSION + if (this.width != width || this.height != height) { + this.width = width + this.height = height + val viewWidth = textureView!!.width + val viewHeight = textureView!!.height + if (viewWidth != 0 && viewHeight != 0) { + bitmap = localRenderer!!.createBitmap(width, height) + } else { + this.width = INVALID_DIMENSION + this.height = INVALID_DIMENSION + } } - } - (bitmap ?: return).copyPixelsFromBuffer(ByteBuffer.wrap(byteBuffer)) + (bitmap ?: return).copyPixelsFromBuffer(ByteBuffer.wrap(byteBuffer)) - if (!isLocal || VideoCaptureUtils.isVideoAllowed()) { - localRenderer!!.drawBitmap(isLocal) + if (!isLocal || VideoCaptureUtils.isVideoAllowed()) { + localRenderer!!.drawBitmap(isLocal) + } + }.onFailure { + Timber.e("Error drawing video: $it") } } @@ -63,4 +67,4 @@ class GroupVideoListener( this.isLocal = isMe this.localRenderer = MegaSurfaceRenderer(textureView, peerId, clientId, isScreenShared) } -} \ No newline at end of file +} From 3fd93747eb3a17e2f1a0d2ac2062977056409cee Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Tue, 30 Jul 2024 16:46:28 +0900 Subject: [PATCH 190/261] Update strings --- app/src/main/res/values-ar/strings.xml | 4 +- app/src/main/res/values-de/strings.xml | 8 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 18 +-- .../main/res/values-it/strings_sdk_errors.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 4 +- app/src/main/res/values-nl/strings.xml | 2 +- .../values-nl/strings_document_scanner.xml | 2 +- app/src/main/res/values-pt/strings.xml | 20 +-- .../values-pt/strings_document_scanner.xml | 6 +- app/src/main/res/values-ro/strings.xml | 70 +++++----- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values/strings.xml | 6 +- .../strings_device_center_feature.xml | 24 ++-- .../res/values-ro/strings_sync_feature.xml | 10 +- sdk/src/main/jni/mega/sdk | 2 +- .../src/main/res/values-ar/strings_shared.xml | 72 ++++++----- .../src/main/res/values-de/strings_shared.xml | 26 ++-- .../src/main/res/values-es/strings_shared.xml | 26 ++-- .../src/main/res/values-fr/strings_shared.xml | 20 +-- .../src/main/res/values-in/strings_shared.xml | 20 +-- .../src/main/res/values-it/strings_shared.xml | 60 ++++----- .../src/main/res/values-ja/strings_shared.xml | 18 +-- .../src/main/res/values-ko/strings_shared.xml | 120 +++++++++--------- .../src/main/res/values-nl/strings_shared.xml | 22 ++-- .../src/main/res/values-pl/strings_shared.xml | 52 ++++---- .../src/main/res/values-pt/strings_shared.xml | 34 ++--- .../src/main/res/values-ro/strings_shared.xml | 54 ++++---- .../src/main/res/values-ru/strings_shared.xml | 18 +-- .../src/main/res/values-th/strings_shared.xml | 20 +-- .../src/main/res/values-vi/strings_shared.xml | 56 ++++---- .../main/res/values-zh-rCN/strings_shared.xml | 18 +-- .../main/res/values-zh-rTW/strings_shared.xml | 18 +-- .../src/main/res/values/strings_shared.xml | 20 +-- 38 files changed, 454 insertions(+), 412 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index e1e20eb019..937504544e 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -6068,7 +6068,7 @@ تم إيقاف الترفيع مؤقتًا لأن البطارية أقل من %1$d%% - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + توقفت ترفيعات الكاميرا عن العمل. حاول إعادة تمكين ترفيعات الكاميرا لحلها. إذا استمرت المشكلة، تواصل مع support@mega.nz. ترفيعات الكاميرا قيد الإنجاز، %1$d ملف معلق @@ -6289,5 +6289,5 @@ الموقع - No location information + لا توجد معلومات عن الموقع \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4eac8d7ba5..8ec9224e71 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -3796,7 +3796,7 @@ Um die Kamera-Uploads zu aktivieren, gewähren Sie MEGA Zugriff auf Fotos und andere Medien auf Ihrem Gerät. - Zugriff freigeben + Zugriff erlauben Nicht gewähren @@ -5122,7 +5122,7 @@ Gewähren Sie Zugriff auf Ihre Galerie - Zugriff freigeben + Zugriff erlauben Update erforderlich @@ -5268,7 +5268,7 @@ Hinzugefügt - Zuletzt bearbeitet am + Letzte Änderung Heute @@ -5337,5 +5337,5 @@ Ort - No location information + Keine Standortdaten \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index ed250b351e..906297ba17 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5575,5 +5575,5 @@ Ubicación - No location information + No hay información de ubicación \ 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 9a54aa95cb..9c6d0975c3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5575,5 +5575,5 @@ Emplacement - No location information + Aucun renseignement sur la position \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 71d5b291bc..272b5f91cf 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -643,7 +643,7 @@ Politica sulla privacy - Termini di servizio + Termini di Servizio Versione @@ -3431,11 +3431,11 @@ Hai inserito la tua password corrente - File nomn più disponibile + File non più disponibile File rimosso perché viola i nostri Termini di servizio. - Termini di servizio violati + Termini di Servizio violati Questo dispositivo non ha app per selezionare le cartelle. @@ -5552,15 +5552,17 @@ Hai alzato la tua mano - You and %1$d other raised your hands - You and %1$d others raised your hands + Tu e %1$d altra persona avete alzato la mano + Tu e %1$d di altre persone avete alzato la mano + Tu e altre %1$d persone avete alzato la mano %1$s ha alzato la mano - %1$s and %2$d other raised their hands - %1$s and %2$d others raised their hands + %1$s e %2$d altra persona hanno alzato la mano + %1$s e %2$d di altre persone hanno alzato la mano + %1$s e altre %2$d persone hanno alzato la mano Ci sono oggetti nascosti in questo album. Condividere l\’album significa che gli oggetti nascosti saranno visibili alle persone con cui condividi. Gli oggetti saranno comunque nascosti nel tuo Cloud drive. @@ -5573,5 +5575,5 @@ Posizione - No location information + Nessuna informazione sulla posizione \ No newline at end of file diff --git a/app/src/main/res/values-it/strings_sdk_errors.xml b/app/src/main/res/values-it/strings_sdk_errors.xml index d6df8355b4..6b64542b47 100644 --- a/app/src/main/res/values-it/strings_sdk_errors.xml +++ b/app/src/main/res/values-it/strings_sdk_errors.xml @@ -13,7 +13,7 @@ Fallito permanentemente - Termini di servizio violati + Termini di Servizio violati Troppe connessioni simultanee o trasferimenti diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 06fac5d385..3256401849 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -5099,5 +5099,5 @@ 場所 - No location information + 位置情報がありません \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 7b20084af5..85bac34d01 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -4913,7 +4913,7 @@ 배터리가 %1$d%% 이하이기 대문에 업로드를 일시정지 하였습니다 - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + 카메라 업로드가 작동을 멈추었습니다. 해결하려면 카메라 업로드를 재활성화 하세요. 만약 문제가 계속되면, support@mega.nz으로 연락하세요. 카메라 업로드 진행 중, 파일 %1$d개 대기 중 @@ -5099,5 +5099,5 @@ 위치 - No location information + 위치 정보 없음 \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 2b53b9a3eb..b19879bb9e 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5337,5 +5337,5 @@ Locatie - No location information + Geen lokatie informatie \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings_document_scanner.xml b/app/src/main/res/values-nl/strings_document_scanner.xml index 11b4a47302..30fa375592 100644 --- a/app/src/main/res/values-nl/strings_document_scanner.xml +++ b/app/src/main/res/values-nl/strings_document_scanner.xml @@ -5,7 +5,7 @@ Scan opslaan - Voeg toe + Toevoegen Opslaan diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b44df0115b..a9f56927e7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -183,7 +183,7 @@ As senhas não coincidem - Já existe uma conta no MEGA com esse e-mail + Já existe uma conta no MEGA com este email Conectando-se ao servidor: criando conta @@ -465,7 +465,7 @@ Problema no sistema de arquivos - Erro aconteceu quando executar a ação + Aconteceu um erro ao executar esta ação Alterar senha @@ -1107,7 +1107,7 @@ Continuidade do status - Mostrar sempre a aparência de status selecionada, mesmo quando eu estiver desconectado + Mostrar sempre o status selecionado, mesmo quando eu estiver desconectado Estabelecer o limite de tempo @@ -1238,7 +1238,7 @@ %s já foi convidado. Revise as suas solicitações pendentes. - Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[A]. + Se você errou ao digitar o seu email, corrija e pressione [A]Reenviar[A]. Reenviar @@ -2219,7 +2219,7 @@ nome do arquivo - Mostrar último acesso + Mostrar o último acesso Permitir que seus contatos vejam o seu último acesso ao MEGA @@ -4783,9 +4783,9 @@ Não foi possível abrir o arquivo - This folder has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Esta pasta foi removida de acordo com a nossa [A]Política do guia de remoção[/A]. Você pode disputar esta remoção se acreditar que cometemos um erro. - This file has been taken down in accordance with our [A]Takedown Guidance Policy[/A]. You can dispute this takedown if you believe we’ve made a mistake. + Este arquivo foi removido de acordo com a nossa [A]Política do guia de remoção[/A]. Você pode disputar esta remoção se acreditar que cometemos um erro. Somente para usuários Pro @@ -4917,7 +4917,7 @@ S - Q + T Q @@ -4925,7 +4925,7 @@ S - D + S D @@ -5575,5 +5575,5 @@ Localização - No location information + Não há informação de localização \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings_document_scanner.xml b/app/src/main/res/values-pt/strings_document_scanner.xml index 9874c37f01..5c6a0e93f2 100644 --- a/app/src/main/res/values-pt/strings_document_scanner.xml +++ b/app/src/main/res/values-pt/strings_document_scanner.xml @@ -25,9 +25,9 @@ Baixa - Descartar este documento escaneado? + Descartar o documento escaneado? - Este documento escaneado será eliminado + O documento escaneado será eliminado Descartar todos os documentos escaneados? @@ -35,7 +35,7 @@ Descartar - Deletar esta digitalização? + Deletar o documento escaneado? Permita o acesso à sua câmera para escanear documentos diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 88ba545602..73de30ce83 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -147,7 +147,7 @@ Nicio conexiune la rețea - Ai fost deconectat de pe acest dispozitiv dintr-o altă locație + Ai fost deconectat de pe acest aparat dintr-o altă locație Se generează cheile de criptare @@ -273,7 +273,7 @@ Adaugă contacte noi folosind butonul de mai jos - Spațiu liber insuficient pe dispozitiv + Spațiu liber insuficient pe aparat Cheie de decriptare @@ -293,9 +293,9 @@ Vezi transferurile - Nu există nicio aplicație disponibilă pentru a executa acest fișier pe dispozitiv + Nu există nicio aplicație disponibilă pentru a executa acest fișier pe aparat - Nu există aplicații disponibile pe dispozitiv pentru a deschide această locație + Nu există aplicații disponibile pe aparat pentru a deschide această locație Este posibil să nu ai instalate aplicații care acceptă acest tip de fișiere @@ -335,7 +335,7 @@ Se copiază - Mută în Coșul de gunoi + Mutați în Coșul de gunoi Elimină de pe MEGA @@ -515,7 +515,7 @@ Opțiuni pentru codul de acces - Comprimarea video folosește cantități considerabile de electricitate. Conectați dispozitivul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. + Comprimarea video folosește cantități considerabile de electricitate. Conectați aparatul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. Dacă este activată, informațiile despre locație vor fi incluse în imaginile dvs. Vă rugăm să aveți grijă când le împărtășiți. @@ -591,9 +591,9 @@ Include etichetele locațiilor - Solicită-mi încărcarea activă a dispozitivului + Solicită-mi încărcarea activă a aparatului - Păstrează numele fișierelor precum în dispozitiv + Păstrează numele fișierelor precum în aparat Folder local pentru cameră @@ -1358,13 +1358,13 @@ Eliminarea contactului de la folderul partajat - Muți în Coșul de gunoi? + Mutați în Coșul de gunoi? Doriți să mutați acest folder în Coșul de gunoi? Un nou folder va fi creat automat pentru încărcările camere. Doriți să mutați acest folder în Coșul de gunoi? Un nou folder va fi creat automat pentru încărcările media. - Muți în Coșul de gunoi? + Mutați în Coșul de gunoi? Ștergi de pe MEGA? @@ -1440,7 +1440,7 @@ Vă rugăm să furnizați feedback-ul dvs. aici: - Modelul dispozitivului + Modelul aparatului Versiunea Android @@ -1550,7 +1550,7 @@ Creează cod QR - Aliniați codul QR pentru a-l digitaliza cu camera dispozitivului dvs. + Aliniați codul QR pentru a-l digitaliza cu camera aparatului dvs. Vezi @@ -1707,7 +1707,7 @@ În acest fel, vei vedea instantaneu mesaje noi\npe telefonul Android. - Deschide [A]Setările[/A] de pe dispozitivul Android + Deschide [A]Setările[/A] de pe aparatul Android Deschide [A]Aplicații și notificări[/A] @@ -1825,7 +1825,7 @@ Scanează sau copiază sămânța în aplicația de autentificare. - Asigură-te că faci backupul acestei sămânțe într-un loc sigur în cazul în care îți pierzi aparatul. + Asigurați-vă că faceți backupul acestei semințe într-un loc sigur în cazul în care vă pierdeți aparatul. Vă rugăm să introduceți codul din 6 cifre generat de aplicația dvs. de autentificare. @@ -1841,7 +1841,7 @@ Cod nevalid - Ți-ai pierdut dispozitivul pentru autentificare? + Ți-ai pierdut aparatul pentru autentificare? Verificarea autentificării @@ -1863,7 +1863,7 @@ Deschide în - Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe dispozitiv + Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe aparat Închide @@ -2131,7 +2131,7 @@ Fișiere - Salvează pe dispozitiv + Salvează pe aparat Încarcă pe MEGA @@ -2229,7 +2229,7 @@ Dimensiunea comprimării video este prea mare - Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți dispozitivul la taxarea pentru a continua. + Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți aparatul la taxarea pentru a continua. Această setare se va aplica data viitoare când rulează Încărcări cameră @@ -2389,7 +2389,7 @@ %1$s . %2$s - Încă îi poți acorda lui MEGA permisiuni în setările dispozitivului + Încă îi poți acorda lui MEGA permisiuni în setările aparatului Mesaj redirecționat @@ -2463,7 +2463,7 @@ Fotografiile dvs. în cloud - Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. Introduceți parola dvs. @@ -2627,11 +2627,11 @@ Contactează administratorul contului business pentru a rezolva problema și a-ți activa contul. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv. + Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat. Când te deconectezi, transferurile în curs vor fi anulate. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv și transferurile în curs vor fi anulate. + Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat și transferurile în curs vor fi anulate. Nume necunoscut @@ -2909,7 +2909,7 @@ Cheie copiată în clipboard - Parolă copiată în clipboard + Parolă a fost copiată în clipboard Link și cheie trimise @@ -3141,7 +3141,7 @@ Adaugă un număr de telefon - MEGA are nevoie de permisiuni de scriere în spațiul de stocare al dispozitivului pentru a continua. + MEGA are nevoie de permisiuni de scriere în spațiul de stocare al aparatului pentru a continua. Mâine, %1$s @@ -3277,7 +3277,7 @@ Obține 20 GB gratuit - Înscrie-te acum și bucură-te gratuit de funcțiile avansate de colaborare. + Înscrieți-vă acum și bucurați-vă gratuit de funcții avansate de colaborare. Un alt apel în desfășurare. Vă rugăm să încheiați apelul curent înainte de a efectua altul. @@ -3399,7 +3399,7 @@ Aveți deja un abonament. Dacă cumpărați altul, veți fi taxat de două ori. Pentru a evita acest lucru, anulați abonamentul curent accesând MEGA într-un browser web desktop sau mobil. Vizitați Centrul nostru de ajutor pentru mai multe informații. - Accesați Setări pentru a permite MEGA permisiunea de a accesa dispozitivele din apropiere utilizând Bluetooth. + Accesați Setări pentru a permite MEGA permisiunea de a accesa aparatele din apropiere utilizând Bluetooth. Nu putem continua cu facturarea. Dacă utilizați o aplicație duală, vă rugăm să luați în considerare conectarea la MEGA fără ea. Dacă nu, încercați să actualizați prin browserul dvs. web. @@ -3437,7 +3437,7 @@ A încălcat Termenii de utilizare a serviciului - Acest dispozitiv nu are o aplicație care să selecteze foldere. + Acest aparat nu are o aplicație care să selecteze foldere. Următorul fișier audio @@ -3715,7 +3715,7 @@ Începe să chatuiești acum - Chatuiește securizat și privat, cu oricine și de pe orice dispozitiv, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. + Chatuiește securizat și privat, cu oricine și de pe orice aparat, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. Începe întâlnirea acum @@ -3805,7 +3805,7 @@ Ați adăugat deja toate contactele dvs. la acest chat. Dacă doriți să adăugați mai mulți participanți, invitați-i mai întâi la lista dvs. de contacte. - Imagine salvată în galeria dispozitivului + Imagine salvată în galeria aparatului Introduceți numele albumului @@ -3895,7 +3895,7 @@ Elimini din album? - Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe dispozitiv. + Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe aparat. Activează accesul @@ -3933,7 +3933,7 @@ Acces refuzat - Ați refuzat accesul MEGA la fișierele de stocare și media ale dispozitivului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. + Ați refuzat accesul MEGA la fișierele de stocare și media ale aparatului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. Acordă permisiunea @@ -4633,7 +4633,7 @@ Trimite invitația pentru calendar - Adaugă o descriere + Adăugați o descriere Este necesar numele întâlnirii @@ -4759,7 +4759,7 @@ Amintiți-vă preferințele - Centrul dispozitivului + Centrul de aparate În fiecare zi @@ -5267,7 +5267,7 @@ Acest apel este înregistrat - Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe dispozitivul persoanei care o înregistrează. + Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe aparatul persoanei care o înregistrează. Bine, am înțeles @@ -5575,5 +5575,5 @@ Locație - No location information + Nicio informație despre locație \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ca13db71d3..4229dd3fbf 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -5813,5 +5813,5 @@ Расположение - No location information + Нет информации о местоположении \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 5486fa8742..70c34a1f71 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -4913,7 +4913,7 @@ Tải lên bị tạm dừng vì pin ở dưới %1$d%% - Camera uploads stopped working. Try re-enabling camera uploads to solve it. If the problem persists, contact support@mega.nz. + Đăng tải camêra đã dừng hoạt động. Hãy thử bật lại đăng tải camêra để giải quyết. Nếu vấn đề tiếp diễn, vui lòng liên hệ với support@mega.nz. Việc đăng tải camêra đang được thực hiện, %1$d tệp đang chờ @@ -5099,5 +5099,5 @@ Vị trí - No location information + Không có thông tin vị trí \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c11adcf95b..30135039ad 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -5099,5 +5099,5 @@ 位置 - No location information + 没有位置信息 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 224e837254..efb89c246a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2441,7 +2441,7 @@ Hold and answer - Hold and Join + Hold and join End and answer @@ -5340,4 +5340,8 @@ Hidden item Hidden items + + Location + + No location information \ No newline at end of file diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index ceef4f11ba..700148b6ad 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -1,19 +1,19 @@ - Redenumire dispozitivul + Redenumire aparatul Redenumește Anulați - Acest dispozitiv + Acest aparat - Alte dispozitive + Alte aparate Stare necunoscută - Dispozitiv necunoscut + Aparat necunoscut La zi @@ -41,7 +41,7 @@ Blocat - Centrul dispozitivului + Centrul de aparate Încărcări cameră @@ -59,7 +59,7 @@ Nicio eroare de sincronizare - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat Folderul ales nu poate fi sincronizat @@ -111,9 +111,9 @@ Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din dispozitiv nu poate fi localizat acum, încercați din nou mai târziu. + Folderul din aparat nu poate fi localizat acum, încercați din nou mai târziu. - Folderul din dispozitiv dvs. nu poate fi localizat + Folderul din aparat dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați asistența. @@ -123,13 +123,13 @@ Încărcări camere sunt dezactivate - Introduceți un nume de dispozitiv. + Introduceți un nume de aparat. - Un dispozitiv cu acest nume există deja. Introduceți un alt nume. + Un aparat cu acest nume există deja. Introduceți un alt nume. Următoarele caractere nu sunt permise: %1$s - Dispozitiv a fost redenumit + Aparat a fost redenumit Maximum 32 de caractere @@ -145,7 +145,7 @@ Nimic nu este încă configurat - Căutarea dispozitivelor + Căutarea aparatelor Căutarea sincronizării diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index cfe48bf683..4db625810c 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -7,7 +7,7 @@ Sincronizează - MEGA trebuie să acceseze spațiul de stocare al dispozitivului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. + MEGA trebuie să acceseze spațiul de stocare al aparatului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal @@ -53,7 +53,7 @@ Conflictul a fost rezolvat - Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest dispozitiv. Datele dvs. sunt întotdeauna în siguranță la noi. + Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest aparat. Datele dvs. sunt întotdeauna în siguranță la noi. Continuați @@ -69,7 +69,7 @@ Nicio problemă - Folderul dispozitivului + Folderul aparatului Folder MEGA @@ -81,7 +81,7 @@ Sincronizată - Folderul dispozitivului + Folderul aparatului Folder MEGA @@ -97,7 +97,7 @@ Numai Wi-Fi - Va trebui să configurați un folder local pe dispozitivul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud + Va trebui să configurați un folder local pe aparatul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud Monitorizarea sincronizărilor diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index e5d6d490be..e0b68f94b5 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit e5d6d490be99352d5f2048a31c303063a458b562 +Subproject commit e0b68f94b554c88c0108613c2682de831c8c7066 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 94c8507ea1..033f184fa8 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -65,7 +65,7 @@ تعذرت قراءة موقع المزامنة. تحقق من إمكانية الوصول إلى الموقع ومن منح الأذونات لموقع المجلد. - حدث خطأ غير معروف. تواصل مع الدعم. + حدث خطأ غير معروف. تواصل مع support@mega.nz. حدث خطأ ما. @@ -435,11 +435,11 @@ أضف تاغ Tag «#%1$s» - Existing tags + التاغات الموجودة - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + لا يمكن أن تحتوي التاغات بدون مسافات أو رموز غير أبجدية رقمية. سيتم عرض التاغات المكتوبة بأحرف كبيرة بأحرف صغيرة. - The maximum number of tags is %1$d + الحد الأقصى لعدد التاغات هو %1$d Tags must be %1$d characters or less @@ -447,7 +447,7 @@ لا يوجد وصف - Add to playlist + إضافة إلى قائمة التشغيل قائمة تشغيل جديدة @@ -455,17 +455,17 @@ سوف تفقدُ هذه الميزات - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + سيظل بإمكانك الوصول إلى هذه الميزات حتى انتهاء صلاحية باقة ميغا MEGA الخاصة بك بعد ذلك سيتم نقلك إلى حساب مجاني. - You are currently using %1s of storage, which you will risk losing. + أنت تستخدم حاليًا %1s من مساحة التخزين الذي ستخاطر بفقدانه. ميزة Free مساحة التخزين - - 20 GB + + %1s غيغابايت التحميل @@ -480,30 +480,30 @@ ترجيع حتى 30 يومًا (للعرض فقط) - - ما يصل إلى 180 يوماً + + يصل إلى %1s يوم MEGA VPN - Call &amp; meeting duration + مدة المكالمة والاجتماع ما يصل إلى 1 ساعة غير محدود - Call &amp; meeting participants + المشاركون في الاتصال والاجتماعات ما يصل إلى 100 غير محدود - Keep %1s + الإبقاء على %1s تابع الإلغاء الحد الأقصى 32 محرفاً - Hidden item + عنصر مخفي تم تعيين هذا العنصر ليكون مخفيًا. بمجرد مشاركة العنصر، سيتمكن أي شخص لديه الرابط من رؤيته. ستظل مخفية في السواقة السحابية الخاص بك. @@ -511,59 +511,59 @@ إلغاء الاشتراك - Reactivate subscription + إعادة تفعيل الاشتراك - Your subscription is not managed by Google + لا تتم إدارة اشتراكك بواسطة غوغل Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + هذا لأنك اشتركت في ميغا MEGA عبر آبل Apple. لإلغاء اشتراكك، ستحتاج إلى: - On a iOS Device + على جهاز أي أو إس iOS - 1. Open the Settings app. + 1. افتح [A]إعدادات[/A] التطبيق. - 2. Tap on your name. + 2. انقر على اسمك. - 3. Tap Subscriptions. + 3. انقر على [A]الإشتراكات[/A]. - 4. Tap your MEGA subscription. + 4. انقر على اشتراك ميغا MEGA الخاص بك. - 5. Tap Cancel subscription. + 5. انقر على [A]إلغاء الاشتراك[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]انقر هنا[/A] للحصول على تعليمات مفصلة حول كيفية إلغاء اشتراكك على الكمبيوتر أو أي جهاز آخر. تحتاج إلى إلغاء اشتراكك باستخدام متصفح الويب - You need to reactivate your subscription using a web browser + تحتاج إلى إعادة تفعيل اشتراكك باستخدام متصفح الويب - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + هذا لأنك اشتركت في ميغا MEGA في متصفح الويب الخاص بك. لإعادة تفعيل اشتراكك، ستحتاج إلى: هذا لأنك اشتركت في ميغا MEGA في متصفح الويب الخاص بك. لإلغاء اشتراكك، ستحتاج إلى: على الحاسوب - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. قم بزيارة [A]www.mega.nz[/A] في متصفح الويب الخاص بك. 2. قم بتسجيل الدخول إلى حساب ميغا MEGA الخاص بك. - 3. Click the main menu. + 3. انقر على القائمة الرئيسية. - 4. Click [A]Settings.[/A] + 4. انقر على [A]إعدادات.[/A] - 5. Click [A]Plan[/A]. + 5. انقر على [A]الباقة[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. انقر على [A]إلغاء الاشتراك[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. انقر على [A]إعادة تفعيل الاشتراك[/A]. على هاتف محمول - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. قم بزيارة [A]www.mega.nz[/A] في متصفح الويب الخاص بك. 2. قم بتسجيل الدخول إلى حساب ميغا MEGA الخاص بك. 3. انقر على الصورة الرمزية avatar الخاصة بك. - 4. Tap [A]Cancel subscription[/A]. + 4. انقر على [A]إلغاء الاشتراك[/A]. لا يوجد اتصال بالإنترنت @@ -582,4 +582,6 @@ هناك مجلد بنفس الاسم المحارف التالية غير مسموح بها: %1$s + + مزامنة \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 3cf149af53..66340e439f 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -65,7 +65,7 @@ Die FSID eines Synchronisierungs-Stammordners konnte nicht abgerufen werden. - Ein unbekannter Fehler ist aufgetreten. Wenden Sie sich an den Support. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -151,7 +151,7 @@ Freigaben - Dauer + Länge Alle Längen @@ -223,7 +223,7 @@ Begrenzt - Free + Kostenlos Fortfahren @@ -432,8 +432,8 @@ Free Speicher - - 20 GB + + %1s GB Transfer @@ -448,8 +448,8 @@ Wiederherstellen Bis zu 30 Tage (nur Ansicht) - - Bis zu 180 Tage + + Bis zu %1s Tage MEGA VPN @@ -457,13 +457,13 @@ Bis zu 1 Stunde - UNBEGRENZT + Unbegrenzt Anruf- und Meeting-Teilnehmer Bis zu 100 - UNBEGRENZT + Unbegrenzt %1s behalten @@ -487,15 +487,15 @@ Auf einem iOS-Gerät - 1. Öffnen Sie die App Einstellungen. + 1. Öffnen Sie die App [A]Einstellungen[/A]. 2. Tippen Sie auf Ihren Namen. - 3. Tippen Sie auf Abos. + 3. Tippen Sie auf [A]Abos[/A]. 4. Tippen Sie auf Ihr MEGA-Abonnement. - 5. Tippen Sie auf Abonnement kündigen. + 5. Tippen Sie auf [A]Abonnement kündigen[/A]. [A]Tippen Sie hier[/A] für detaillierte Anweisungen zum Kündigen Ihres Abonnements auf einem Computer oder einem anderen Gerät. @@ -550,4 +550,6 @@ Ein Ordner dieses Namens existiert bereits Die folgenden Zeichen sind nicht zulässig: %1$s + + Synchronisierung \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 3ce3697f2c..66f8e7d99b 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -65,7 +65,7 @@ No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Se ha producido un error. Ponte en contacto con soporte. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -440,8 +440,8 @@ Free Almacenamiento - - 20 GB + + %1s GB Transferencia @@ -456,8 +456,8 @@ Rebobinar Hasta 30 días (solo lectura) - - Hasta 180 días + + Up to %1s days MEGA VPN @@ -465,13 +465,13 @@ Hasta 1 hora - Ilimitado + Ilimitadas Call &amp; meeting participants Hasta 100 - Ilimitado + Ilimitados Keep %1s @@ -493,17 +493,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -521,7 +521,7 @@ 2. Inicia sesión en tu cuenta de MEGA. - 3. Click the main menu. + 3. Haz clic en el menú principal. 4. Click [A]Settings.[/A] @@ -558,4 +558,6 @@ Ya existe una carpeta con el mismo nombre Los siguientes caracteres no están permitidos: %1$s + + Sincronizar \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index e5138b7c4c..ce9733c6cd 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -65,7 +65,7 @@ Impossible de lire l’emplacement de la synchronisation. Vérifiez que l’emplacement est accessible et que les droits ont été accordés pour l’emplacement du dossier. - Un erreur inconnue est survenue. Contactez l’assistance. + An unknown error occurred. Contact support@mega.nz. Un problème est survenu @@ -417,7 +417,7 @@ Le nombre maximal d’étiquettes est de %1$d - Les étiquettes doivent comprendre %1$d caractères ou moins + Tags must be %1$d characters or less Étiquettes @@ -440,8 +440,8 @@ Gratuit Espace de stockage - - 20 Go + + %1s Go Transferts @@ -456,8 +456,8 @@ Retour en arrière Jusqu’à 30 jours (visualiser seulement) - - Jusqu’à 180 jours + + Jusqu’à %1s jours RPV MEGA VPN @@ -495,15 +495,15 @@ Sur un appareil iOS - 1. Ouvrez l’appli Paramètres. + 1. Ouvrez l’appli [A]Paramètres[/A]. 2. Touchez votre nom. - 3. Touchez Abonnements. + 3.. Touchez [A]Abonnements[/A]. 4. Touchez votre abonnement MEGA. - 5. Touchez Annuler l’abonnement. + 5. Touchez [A]Annuler l’abonnement[/A]. [A]Touchez ici[/A] pour obtenir des instructions détaillées sur la manière d’annuler votre abonnement sur un ordinateur ou sur un autre appareil. @@ -558,4 +558,6 @@ Un dossier porte déjà ce nom Les caractères suivants ne sont pas autorisés : %1$s + + Synchronisations \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 7e41db1ac5..d33e828a3a 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -65,7 +65,7 @@ Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Terjadi kesalahan yang tidak diketahui. Hubungi Bantuan. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -427,8 +427,8 @@ Free Gudang - - 20 GB + + %1s GB Transfer @@ -443,8 +443,8 @@ Putar balik Hingga 30 hari (hanya lihat) - - Hingga 180 days + + Up to %1s days MEGA VPN @@ -480,17 +480,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -545,4 +545,6 @@ Sudah ada folder dengan nama yang sama Karakter berikut tidak diperbolehkan: %1$s + + Sinkronkan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 72506b841e..2ebfc0ec38 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -65,7 +65,7 @@ Impossibile leggere la posizione della sincronizzazione. Controlla che la posizione sia accessibile e i permessi per la cartella della posizione siano garantiti. - Si è verificato un errore sconosciuto. Contatta il supporto. + Si è verificato un errore sconosciuto. Contatta support@mega.nz. Something went wrong. @@ -383,7 +383,7 @@ Non adesso - Uploads folder conflict + Conflitto tra cartelle di caricamento La cartella dei Caricamenti da fotocamera e la cartella dei caricamenti multimediali secondari non possono essere correlate tra loro. Scegli una cartella diversa. @@ -440,8 +440,8 @@ Free Archivio - - 20 GB + + %1s GB Trasferisci @@ -456,8 +456,8 @@ Ripristina Fino a 30 giorni (solo visualizzazione) - - Fino a 180 giorni + + Fino a %1s giorni MEGA VPN @@ -465,13 +465,13 @@ Fino a 1 ora - ILLIMITATA + Illimitata Partecipanti alle chiamate e ai meeting Fino a 100 - ILLIMITATA + Illimitati Mantieni %1s @@ -487,59 +487,59 @@ Annulla Iscrizione - Reactivate subscription + Riattiva l\’abbonamento - Your subscription is not managed by Google + Il tuo abbonamento non è gestito da Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Questo perché hai creato l\’abbonamento a MEGA tramite Apple. Per annullare l\’abbonamento, dovrai: - On a iOS Device + Su un dispositivo iOS - 1. Open the Settings app. + 1. Aprire l\’app [A]Impostazioni[/A]. - 2. Tap on your name. + 2. Toccare il tuo nome. - 3. Tap Subscriptions. + 3. Toccare [A]Abbonamenti[/A]. - 4. Tap your MEGA subscription. + 4. Toccare il tuo abbonamento MEGA. - 5. Tap Cancel subscription. + 5. Toccare [A]Annulla abbonamento[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Tocca qui[/A] per istruzioni dettagliate su come annullare l\’abbonamento su un computer o un altro dispositivo. Devi annullare l\’abbonamento utilizzando un web browser - You need to reactivate your subscription using a web browser + È necessario riattivare l\’abbonamento utilizzando un browser web - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Questo perché hai creato l\’abbonamento a MEGA nel tuo browser web. Per riattivare l\’abbonamento, dovrai: - Questo perché ti sei iscritto a MEGA tramite un web browser. Per annullare l\’abbonamento, dovrai: + Questo perché hai creato l\’abbonamento a MEGA tramite un web browser. Per annullare l\’abbonamento, dovrai: Su un computer - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visitare [A]www.mega.nz[/A] nel tuo browser web. 2. Accedi al tuo account MEGA. - 3. Click the main menu. + 3. Cliccare sul menu principale. - 4. Click [A]Settings.[/A] + 4. Cliccare su [A]Impostazioni[/A]. - 5. Click [A]Plan[/A]. + 5. Cliccare su [A]Piano[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Cliccare su [A]Annulla abbonamento[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Cliccare su [A]Riattiva abbonamento[/A]. Su un dispositivo mobile - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visitare [A]www.mega.nz[/A] nel tuo browser web. 2. Accedi al tuo account MEGA. 3. Tocca il tuo avatar. - 4. Tap [A]Cancel subscription[/A]. + 4. Toccare [A]Annulla abbonamento[/A]. Nessuna connessione Internet @@ -558,4 +558,6 @@ C\’è già una cartella con lo stesso nome I seguenti caratteri non sono ammessi: %1$s + + Sincronizza \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index c7ccccf523..518af61b8d 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -65,7 +65,7 @@ 同期の場所を読み取れませんでした。場所がアクセス可能であること、およびフォルダの場所に対するアクセス許可が付与されていることを確認してください。 - 不明なエラーが発生しました。サポートにご連絡ください。 + 不明なエラーが発生しました。support@mega.nzにご連絡ください。 何か問題が発生しました。 @@ -424,8 +424,8 @@ 無料 ストレージ - - 20 GB + + %1s GB 転送 @@ -440,8 +440,8 @@ 巻き戻す 最大30日間(閲覧のみ) - - 最大180日 + + 最大%1s日 MEGA VPN @@ -479,15 +479,15 @@ iOSデバイスで - 1. 設定アプリを開く。 + 1.[A]設定[/A]アプリを開く。 2. 自分の名前をタップする。 - 3. 「サブスクリプション」をタップする。 + 3.「[A]定期購入[/A]」をタップする。 4. MEGAサブスクリプションをタップする。 - 5. 「サブスクリプションをキャンセル」をタップする。 + 5.[A]「サブスクリプションをキャンセル」[/A]をタップする。 [A]こちらをタップ[/A]すると、コンピューターまたはその他のデバイスでサブスクリプションをキャンセルする方法の詳細な手順が表示されます。 @@ -542,4 +542,6 @@ 同じ名前のフォルダがすでにあります 次の文字は許可されていません:%1$s + + 同期 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index e98812987b..945ee6b038 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -65,7 +65,7 @@ 동기화 위치를 읽을 수 없습니다. 위치에 접근 가능한지 여부와 폴더 위치에 대한 권한이 승인 되었는지 확인하세요. - 알 수 없는 오류가 발생하였습니다. 지원에 연락하세요. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -91,7 +91,7 @@ 다시는 데이터를 잃지 마세요 - Rewind to restore files and folders back to any date up to 180 days, so your data is accident and tamper-proof. + 당신의 데이터가 사고로 인해 변경되는 것을 막을 수 있도록, 파일과 폴더를 최대 180일까지 되돌려서 복원하세요. MEGA VPN @@ -275,7 +275,7 @@ 업그레이드 - Upload paused, device is not charging + 장치가 충전 중이 아니어서, 업로드가 일시정지 되었습니다 설정된 동기화가 없습니다 @@ -299,7 +299,7 @@ 해결된 문제 - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + 이 폴더는 동기화할 수 없습니다. 카메라 업로드를 이용하여 동기화를 설정하세요. 설명 @@ -361,53 +361,53 @@ Pro로 업그레이드 - Unlock the power to sync your mobile device to the cloud with our Pro plans. + Pro 요금제로 휴대 장치에서 클라우드로 동기화하는 기능을 잠금 해제하세요. 업그레이드 나중에 - Uploads folder conflict + 업로드 폴더 충돌 - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + 카메라 업로드 폴더와 보조 미디어 업로드 폴더는 서로 연관 관계가 있을 수 없습니다. 다른 폴더를 선택하세요. - Okay, got it + 알겠습니다 - This device doesn’t have an app to select folders + 이 장치에 폴더를 선택할 앱이 없습니다 - • Automatically sync the folders on your mobile device + • 휴대 장치의 폴더를 자동으로 동기화 - Your syncs have been paused. Syncing is a Pro plan feature. + 동기화가 일시정지 되었습니다. 동기화는 Pro 요금제 기능입니다. Ok - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + 당신의 MEGA Pro 요금제가 취소되어 동기화가 일시정지 되었습니다. 동기화를 계속하려면 업그레이드 하세요. 숨겨진 항목 Pro 전용 - Tags + 태그 - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + 데이터를 찾고 정리하는데에 도움을 받기 위해 태그를 이용하세요. 연도, 위치, 프로젝트, 또는 제목으로 태그해보세요. - Tag + 태그 - Add “#%1$s” tag + “#%1$s” 태그 추가함 - Existing tags + 존재하는 태그 - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + 태그는 공백 또는 영숫자가 아닌 기호를 포함할 수 없습니다. 대문자로 쓴 태그는 소문자로 표기됩니다. - The maximum number of tags is %1$d + 최대 태그 수는 %1$d입니다. Tags must be %1$d characters or less - Tags + 태그 설명 없음 - Add to playlist + 재생목록에 추가 새 재생 목록 @@ -415,17 +415,17 @@ 이러한 기능들을 잃게 됩니다 - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + MEGA 요금제가 만료되기 전까지는 이러한 기능들에 접근할 수 있지만, 그 이후에는 무료 계정으로 바뀝니다. - You are currently using %1s of storage, which you will risk losing. + 현재 저장소의 %1s만큼 이용 중이며, 손실의 위험이 있습니다. 기능 Free 저장소 - - 20 GB + + %1s GB 전송 @@ -440,24 +440,24 @@ 되감기 최대 30일 (보기 전용) - - 최대 180일 + + Up to %1s days MEGA VPN - Call &amp; meeting duration + 통화 &amp; 회의 길이 - Up to 1 hour + 최대 1시간 무제한 - Call &amp; meeting participants + 통화 &amp; 회의 참여자 - Up to 100 + 최대 100명 무제한 - Keep %1s + %1s 유지 취소 진행 @@ -471,59 +471,59 @@ 구독 취소 - Reactivate subscription + 구독 재활성화 - Your subscription is not managed by Google + 당신의 구독은 Google에서 관리되지 않습니다 - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + 이것은 당신이 Apple을 통해 MEGA를 구독하였기 때문입니다. 구독을 취소하려면, 다음을 하세요: - On a iOS Device + iOS 장치에서 - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. - 2. Tap on your name. + 2. 이름을 탭합니다. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. - 4. Tap your MEGA subscription. + 4. 당신의 MEGA 구독을 탭합니다. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + 컴퓨터 또는 다른 장치에서 구독을 취소하는 자세한 방법은 [A]여기를 탭[/A]하세요. - You need to cancel your subscription using a web browser + 웹 브라우저를 이용하여 구독을 취소하여야 합니다 - You need to reactivate your subscription using a web browser + 웹 브라우저를 이용하여 구독을 재활성화하여야 합니다 - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + 당신이 웹 브라우저에서 MEGA를 구독하였기 때문입니다.\n구독을 재활성화 하려면, 다음을 해야 합니다: - This is because you subscribed to MEGA in your web browser. To cancel your subscription, you will need to: + 당신이 웹 브라우저에서 MEGA를 구독하였기 때문입니다.\n구독을 취소 하려면, 다음을 해야 합니다: - On a computer + 컴퓨터에서 - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. 웹 브라우저에서 [A]www.mega.nz[/A]에 방문합니다. - 2. Log in to your MEGA account. + 2. MEGA 계정에 로그인합니다. - 3. Click the main menu. + 3. 메인 메뉴를 클릭합니다. - 4. Click [A]Settings.[/A] + 4. [A]설정[/A]을 클릭합니다. - 5. Click [A]Plan[/A]. + 5. [A]요금제[/A]를 클릭합니다 - 6. Click [A]Cancel subscription[/A]. + 6. [A]구독 취소[/A]를 클릭합니다. - 6. Click [A]Reactivate subscription[/A]. + 6. [A]구독 재활성화[/A]를 클릭합니다. - On a mobile device + 휴대 장치에서 - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. 웹 브라우저에서 [A]www.mega.nz[/A]에 방문합니다. - 2. Log in to your MEGA account. + 2. MEGA 계정에 로그인합니다. - 3. Tap on your avatar. + 3. 아바타를 탭합니다. - 4. Tap [A]Cancel subscription[/A]. + 4. [A]구독 취소[/A]를 탭합니다. 인터넷 연결이 없습니다 @@ -542,4 +542,6 @@ 이미 같은 이름을 가진 폴더가 존재합니다 다음의 문자는 허용되지 않습니다: %1$s + + 동기화 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 4ba75a7e78..4a4293f40e 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -65,7 +65,7 @@ Kan de synchronisatielocatie niet lezen. Controleer of de locatie toegankelijk is en of er machtigingen voor de maplocatie zijn verleend. - Er is een onbekende fout opgetreden. Neem contact op met de klantenservice. + An unknown error occurred. Contact support@mega.nz. Er is iets misgegaan. @@ -432,8 +432,8 @@ Free Opslag - - 20   GB + + %1s  GB Overdracht @@ -448,8 +448,8 @@ Terugspoelen Tot 30 dagen (alleen weergeven) - - Tot op 180 dagen + + Tot %1s dagen MEGA VPN @@ -457,13 +457,13 @@ Tot 1 uur - ONBEPERKT + Onbeperkt Deelnemers aan de oproep en vergadering Tot 100 - ONBEPERKT + Onbeperkt %1s behouden @@ -487,15 +487,15 @@ Op een iOS-apparaat - 1. Open de Instellingen-applicatie. + 1. Open het [A]Instellingen[/A] applicatie. 2. tik op uw naam. - 3. Tik op Abonnementen. + 3. Tik [A]Abonnementen[/A]. 4. tik op uw MEGA-abonnement. - 5. tik op Abonnement annuleren. + 5. Tik [A]Abonnement opzeggen[/A]. [A]Tik hier[/A] voor gedetailleerde instructies voor het opzeggen van uw abonnement op een computer of ander apparaat. @@ -550,4 +550,6 @@ Er is al een map met dezelfde naam De volgende tekens zijn niet toegestaan: %1$s + + Synchroniseren \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index a303e0e786..a880bfad06 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -65,7 +65,7 @@ Nie można odczytać lokalizacji synchronizacji. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu. - Wystąpił nieznany błąd. Skontaktuj się z pomocą techniczną. + Wystąpił nieznany błąd. Skontaktuj się z support@mega.nz. Something went wrong. @@ -448,8 +448,8 @@ Free Pojemności - - 20   GB + + %1s  GB Przesyłanie @@ -464,8 +464,8 @@ Przewiń Do 30 dni (tylko podgląd) - - Do 180 dni + + Do %1s dni MEGA VPN @@ -495,59 +495,59 @@ Anuluj subskrypcję - Reactivate subscription + Ponownie aktywuj subskrypcję - Your subscription is not managed by Google + Twoja subskrypcja nie jest zarządzana przez Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Dzieje się tak, ponieważ subskrybowałeś MEGA za pośrednictwem Apple. Aby anulować subskrypcję, musisz: - On a iOS Device + Na urządzeniu z systemem iOS - 1. Open the Settings app. + 1. Otwórz [A]Ustawienia[/A] aplikacji. - 2. Tap on your name. + 2. Kliknij w swoje imię. - 3. Tap Subscriptions. + 3. Kliknij [A]subskrypcje[/A]. - 4. Tap your MEGA subscription. + 4. Kliknij subskrypcja MEGA. - 5. Tap Cancel subscription. + 5. Kliknij [A]aby anulować subskrypcję[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Kliknij tutaj[/A] po szczegółowe instrukcje dotyczące anulowania subskrypcji na komputerze lub innym urządzeniu. Musisz anulować subskrypcję za pomocą przeglądarki internetowej - You need to reactivate your subscription using a web browser + Musisz ponownie aktywować subskrypcję za pomocą przeglądarki internetowej - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Dzieje się tak, ponieważ subskrybowałeś MEGA w swojej przeglądarce internetowej. Aby ponownie aktywować subskrypcję, musisz: Dzieje się tak, ponieważ subskrybowałeś MEGA w swojej przeglądarce internetowej. Aby anulować subskrypcja, musisz: Na komputerze - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Odwiedź [A]www.mega.nz[/A] w przeglądarce internetowej. 2. Zaloguj się na swoje konto MEGA. - 3. Click the main menu. + 3. Kliknij menu główne. - 4. Click [A]Settings.[/A] + 4. Kliknij [A]Ustawienia.[/A] - 5. Click [A]Plan[/A]. + 5. Kliknij [A]plan[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Kliknij [A]Anuluj subskrypcję[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Kliknij [A]Ponownie aktywuj subskrypcję[/A]. Na urządzeniu mobilnym - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Odwiedź [A]www.mega.nz[/A] w przeglądarce internetowej. 2. Zaloguj się na swoje konto MEGA. 3. Kliknij swojego awatara - 4. Tap [A]Cancel subscription[/A]. + 4. Kliknij [A]Anuluj subskrypcję[/A]. Brak połączenia z internetem @@ -566,4 +566,6 @@ Istnieje już katalog o takiej nazwie Następujące znaki są niedozwolone: %1$s + + Sync \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index d767a1dc18..225313b1ed 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -65,7 +65,7 @@ Não foi possível ler a localização da sincronização. Verifique se o local está acessível e se as permissões para a localização da pasta foram concedidas. - Ocorreu um erro desconhecido - entre em contato com o Suporte. + Ocorreu um erro desconhecido - entre em contato com support@mega.nz. Algo deu errado. @@ -285,7 +285,7 @@ Agora não - Se você errou ao digitar o seu e-mail, corrija e pressione [A]Reenviar[/A]. + Se você errou ao digitar o seu email, corrija e pressione [A]Reenviar[/A]. A sincronização foi pausada porque o seu plano do MEGA já não tem armazenamento disponível @@ -373,7 +373,7 @@ Mantenha a sua informação sincronizada e atualizada fazendo o upgrade a um dos nossos planos Pro. - Upgrade + Fazer upgrade Fazer o upgrade a Pro @@ -395,7 +395,7 @@ As suas sincronizações foram pausadas: sincronizar é um recurso dos planos Pro. - Ok + OK A sincronização foi pausada porque o seu plano Pro do MEGA foi cancelado. Faça upgrade para continuar sincronizando. @@ -437,15 +437,15 @@ Recurso - Free + Grátis Armazenamento - - 20 GB + + %1s GB Transferência - Limitado + Limitada Links protegidos por senha @@ -456,8 +456,8 @@ Retroceder Até 30 dias (somente visualização) - - Até 180 dias + + Até %1s dias MEGA VPN @@ -465,13 +465,13 @@ Até 1 hora - ILIMITADO + Ilimitada Participantes em reuniões e chamadas Até 100 - ILIMITADO + Ilimitado Manter o plano %1s @@ -495,15 +495,15 @@ Em um dispositivo iOS - 1. Acesse o aplicativo das Configurações. + 1. Acesse o aplicativo das [A]Configurações[/A]. 2. Pressione o seu nome. - 3. Pressione Assinaturas. + 3. Pressione [A]Assinaturas[/A]. 4. Selecione a sua assinatura do MEGA. - 5. Pressionar Cancelar assinatura. + 5. Pressione [A]Cancelar assinatura[/A]. [A]Veja aqui[/A] instruções detalhadas sobre como cancelar a sua assinatura em um computador ou outro dispositivo. @@ -541,7 +541,7 @@ 4. Pressione [A]Cancelar assinatura[/A]. - Não há conexão à Internet + Não há conexão à internet Criar nova pasta @@ -558,4 +558,6 @@ Já existe uma pasta com o mesmo nome Os seguintes caracteres não são permitidos: %1$s + + Sincronizar \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 579e94c162..00fca90584 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat Folderul ales nu poate fi sincronizat @@ -61,19 +61,19 @@ Unable to open state cache database - Spațiu de stocare insuficient pe dispozitiv + Spațiu de stocare insuficient pe aparat Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. - A apărut o eroare necunoscută. Contactați asistența. + An unknown error occurred. Contact support@mega.nz. Something went wrong. Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din dispozitiv nu poate fi localizat chiar acum. Încercați din nou mai târziu. + Folderul din aparat nu poate fi localizat chiar acum. Încercați din nou mai târziu. - Folderul din dispozitiv dvs. nu poate fi localizat + Folderul din aparat dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați Asistența. @@ -85,7 +85,7 @@ Sincronizarea întreruptă, nivelul bateriei prea scăzut. Încărcați bateria pentru a relua sincronizarea. - Partajare de fișiere ușoară și sigură + Partajarea de fișiere ușoară și sigură Partajați fișiere mari datorită unei cote generoase de transfer și asigurați securitatea cu link-uri protejate prin parolă. @@ -291,7 +291,7 @@ Upgradează - Încărcarea este întreruptă, deoarece dispozitivul nu se încarcă + Încărcarea este întreruptă, deoarece aparatul nu se încarcă Nu este configurată nicio sincronizare @@ -305,11 +305,11 @@ Essential - Încărcările vor fi întrerupte până când începeți să încărcați dispozitivul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. + Încărcările vor fi întrerupte până când începeți să încărcați aparatul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. Nu este configurată nicio sincronizare - Sincronizați un folder local de pe dispozitiv cu un folder de pe MEGA. + Sincronizați un folder local de pe aparat cu un folder de pe MEGA. Adăugați o nouă sincronizare @@ -319,7 +319,7 @@ Descriere - Adaugă o descriere + Adăugați o descriere A fost adăugată o descriere @@ -327,9 +327,9 @@ Și acces la aceste beneficii interesante: - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil\n• Fără reclame + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil\n• Fără reclame - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil Nicio problemă rezolvată @@ -349,7 +349,7 @@ Adăugați contacte, creați o rețea, colaborați și efectuați apeluri vocale și video fără a părăsi MEGA. - Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. Întâlnire video criptată cu zero cunoștințe. @@ -377,7 +377,7 @@ Upgradează la Pro - Abonamentele noastre Pro dezlănțuie puterea de sincronizare a dispozitivului dvs. mobil cu MEGA. + Abonamentele noastre Pro dezlănțuie puterea de sincronizare a aparatului dvs. mobil cu MEGA. Upgradează @@ -389,9 +389,9 @@ Bine, am înțeles - Acest dispozitiv nu are o aplicație care să selecteze foldere + Acest aparat nu are o aplicație care să selecteze foldere - • Sincronizați automat folderele de pe dispozitivul mobil + • Sincronizați automat folderele de pe aparatul mobil Sincronizările dvs. au fost întrerupte. Sincronizarea este o funcție a abonamentelor Pro. @@ -440,8 +440,8 @@ Gratuit Spațiu de stocare - - 20 GB + + %1s GB Transferuri @@ -456,8 +456,8 @@ Derulare înapoi Până la 30 de zile (numai vizualizare) - - Până la 180 de zile + + Până la %1s de zile MEGA VPN @@ -493,19 +493,19 @@ V-ați abonat la MEGA cu Apple. Pentru a vă anula abonamentul, trebuie să: - Pe un dispozitiv iOS + Pe un aparat iOS - 1. Deschideți aplicația Setări. + 1. Deschideți aplicația [A]Setări[/A]. 2. Atingeți numele dvs. - 3. Atingeți Abonamente. + 3. Atingeți [A]Abonamente[/A]. 4. Atingeți abonamentul MEGA. - 5. Atingeți Anulați abonamentul. + 5. Atingeți [A]Anulați abonamentul[/A]. - [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt dispozitiv. + [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt aparat. Trebuie să vă anulați abonamentul folosind un browser web @@ -531,7 +531,7 @@ 6. Dați clic pe [A]Reactivați abonamentul[/A]. - Pe un dispozitiv mobil + Pe un aparat mobil 1. Accesați [A]www.mega.nz[/A] în browserul web. @@ -558,4 +558,6 @@ Există deja un folder cu același nume Următoarele caractere nu sunt permise: %1$s + + Sincronizează \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 455f4f353e..91ef1207b2 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -65,7 +65,7 @@ Не удалось прочитать расположение синхронизации. Убедитесь, что расположение папки доступно и предоставлены права доступа к нему. - Произошла неизвестная ошибка. Обратитесь в поддержку. + Произошла неизвестная ошибка. Напишите на support@mega.nz. Something went wrong. @@ -448,8 +448,8 @@ Free Хранилище - - 20 ГБ + + %1s ГБ Передача данных @@ -464,8 +464,8 @@ Перемотка До 30 дней (только просмотр) - - До 180 дней + + До %1s дней MEGA VPN @@ -503,15 +503,15 @@ На устройстве iOS - 1. Откройте приложение «Настройки». + 1. Откройте приложение [A]«Настройки»[/A]. 2. Нажмите на своё имя. - 3. Нажмите «Подписки». + 3. Нажмите [A]«Подписки»[/A]. 4. Нажмите на свою подписку MEGA. - 5. Нажмите «Отменить подписку». + 5. Нажмите [A]«Отменить подписку»[/A]. [A]Нажмите здесь[/A], чтобы получить подробные инструкции о том, как отменить подписку на компьютере или другом устройстве. @@ -566,4 +566,6 @@ Папка с таким именем уже существует Следующие символы не допускаются: %1$s + + Синхронизация \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index e9d239f863..700d1eb76f 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -65,7 +65,7 @@ ไม่สามารถอ่านตำแหน่งที่ตั้งการซิงค์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ - เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ ติดต่อฝ่ายสนับสนุน + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -424,8 +424,8 @@ Free พื้นที่เก็บข้อมูล - - 20 GB + + %1s GB ถ่ายโอน @@ -440,8 +440,8 @@ มีกระบวนการย้อนกลับไฟล์ได้ สูงสุด 30 วัน (ดูอย่างเดียว) - - นานถึง 180 วัน + + Up to %1s days MEGA VPN @@ -477,17 +477,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -542,4 +542,6 @@ มีโฟลเดอร์ชื่อเดียวกันอยู่แล้ว ไม่อนุญาตให้ใช้อักขระต่อไปนี้: %1$s + + ซิงค์ \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 4bbb5394b3..f12c5a6f3f 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -65,7 +65,7 @@ Không thể đọc được vị trí thư mục. Kiểm tra xem vị trí có thể truy cập được hay không và quyền đi tới vị trí thư mục đã được cấp phép. - Một lỗi không xác định được đã xảy ra. Hãy liên hệ với bộ phận Hỗ trợ. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -424,8 +424,8 @@ Free Lưu trữ - - 20 GB + + %1s GB Truyền Tải @@ -440,8 +440,8 @@ Tua lại Lên đến 30 ngày (chỉ được xem) - - Lên đến 180 ngày + + Up to %1s days MEGA VPN @@ -449,13 +449,13 @@ Lên đến 1 tiếng - KHÔNG GIỚI HẠN + Không giới hạn Số người tham gia cuộc gọi $ cuộc họp Lên đến 100 người - KHÔNG GIỚI HẠN + Không giới hạn Giữ %1s @@ -471,59 +471,59 @@ Hủy Gói Đăng Ký Dịch Vụ - Reactivate subscription + Kích hoạt lại gói đăng ký - Your subscription is not managed by Google + Gói đăng ký của bạn không có quản lý bởi Google. - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Điều này là do bạn đã đăng ký MEGA thông qua Apple. Để hủy gói đăng ký, bạn sẽ cần: - On a iOS Device + Trên thiết bị iOS - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. - 2. Tap on your name. + 2. Chạm vào tên của bạn. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. - 4. Tap your MEGA subscription. + 4. Chạm vào gói đăng ký MEGA. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Chạm vào đây[/A] để được hướng dẫn chi tiết về cách hủy gói đăng ký của bạn trên máy tính hoặc loại thiết bị khác. Bạn cần phải hủy gói đăng ký của mình bằng trình duyệt web - You need to reactivate your subscription using a web browser + Bạn cần phải sử dụng trình duyệt web để kích hoạt lại gói đăng ký của mình - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Điều này là do bạn đã đăng ký gói MEGA bằng trình duyệt web. Để hủy gói đăng ký, bạn sẽ cần: Điều này là do bạn đã đăng ký gói MEGA trong trình duyệt web của mình. Để hủy gói đăng ký, bạn sẽ cần: Trên máy tính - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Ghé trang [A]www.mega.nz[/A] trong trình duyệt web của bạn. 2. Đăng nhập vào tài khoản MEGA của bạn. - 3. Click the main menu. + 3. Click vào menu chính. - 4. Click [A]Settings.[/A] + 4. Click vào [A]Thiết Đặt.[/A] - 5. Click [A]Plan[/A]. + 5. Click vào [A]Gói[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Click vào [A]Hủy đăng ký[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Click vào [A]Kích hoạt lại gói đăng ký[/A]. Trên thiết bị di động - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Ghé trang [A]www.mega.nz[/A] trong trình duyệt web của bạn. 2. Đăng nhập vào tài khoản MEGA của bạn. 3. Chạm vào ảnh đại diện của bạn. - 4. Tap [A]Cancel subscription[/A]. + 4. Chạm vào [A]Hủy đăng ký[/A]. Không có kết nối internet @@ -542,4 +542,6 @@ Đã có một thư mục với cái tên này rồi Các ký tự này không được phép sử dụng: %1$s + + Đồng bộ \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 56d78af611..91e386c317 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -65,7 +65,7 @@ 无法读取同步位置。检查该位置是否可访问以及是否已授予该文件夹位置的权限。 - 出现未知错误。请联系客服。 + 出现未知错误。请联系support@mega.nz。 Something went wrong. @@ -424,8 +424,8 @@ 免费 存储空间 - - 20 GB + + %1s GB 传输 @@ -440,8 +440,8 @@ 还原 最多30天(仅限查看) - - 最长可达180天 + + 长达%1s天 MEGA VPN @@ -479,15 +479,15 @@ 在iOS设备上 - 1. 打开应用程序的设置。 + 1.打开应用程序的[A]设置[/A]。 2. 点按您的名字。 - 3. 点按订阅。 + 3.点按[A]订阅[/A]。 4. 点按您的MEGA订阅。 - 5. 点按取消订阅。 + 5.点按[A]取消订阅[/A]。 [A]点按这里[/A]了解有关如何在计算机或其它设备上取消订阅的详细说明。 @@ -542,4 +542,6 @@ 已经有一个相同名称的文件夹 不允许使用这些字符:%1$s + + 同步 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index f9a4a95d8a..bd3248c242 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -65,7 +65,7 @@ 無法讀取同步位置。檢查該位置是否可用,而且是否已授予該資料夾位置的權限。 - 發生未知錯誤。聯繫客服。 + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -424,8 +424,8 @@ 免費 儲存空間 - - 20 GB + + %1s GB 傳輸 @@ -440,8 +440,8 @@ 回溯 最多30天(僅能檢視) - - 長達180天 + + 長達%1s天 MEGA VPN @@ -479,15 +479,15 @@ 在iOS裝置上 - 1. 開啟設定應用程式。 + 1.打開應用程式的[A]設定[/A]。 2. 點選您的名稱。 - 3. 點選訂閱。 + 3.點選[A]訂閱[/A]。 4. 點選您的MEGA訂閱。 - 5. 點選取消訂閱。 + 5.點選[A]取消訂閱[/A]。 [A]點選此處[/A]以取得如何在電腦或其它裝置上取消訂閱的詳細說明。 @@ -542,4 +542,6 @@ 已經有一個同名的資料夾 不允許使用以下字元:%1$s + + 同步 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index a897990df5..fb1378cca9 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -65,7 +65,7 @@ Couldn’t read sync location. Check the location is accessible and permissions for the folder location are granted. - An unknown error occurred. Contact Support. + An unknown error occurred. Contact support@mega.nz. Something went wrong. @@ -432,8 +432,8 @@ Free Storage - - 20 GB + + %1s GB Transfer @@ -448,8 +448,8 @@ Rewind Up to 30 days (view only) - - Up to 180 days + + Up to %1s days MEGA VPN @@ -485,17 +485,17 @@ This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: - On a iOS Device + On an iOS Device - 1. Open the Settings app. + 1. Open the [A]Settings[/A] app. 2. Tap on your name. - 3. Tap Subscriptions. + 3. Tap [A]Subscriptions[/A]. 4. Tap your MEGA subscription. - 5. Tap Cancel subscription. + 5. Tap [A]Cancel subscription[/A]. [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. @@ -550,4 +550,6 @@ There is already a folder with the same name The following characters are not allowed: %1$s + + Sync \ No newline at end of file From 3005b3f5a95115ac71bc058d347fb4505bd8cb7e Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Tue, 30 Jul 2024 16:50:23 +0900 Subject: [PATCH 191/261] Update strings --- app/src/main/res/values-it/strings.xml | 10 ++++++---- .../src/main/res/values-ar/strings_shared.xml | 4 ++-- .../src/main/res/values-de/strings_shared.xml | 2 +- .../src/main/res/values-es/strings_shared.xml | 2 +- .../src/main/res/values-fr/strings_shared.xml | 2 +- .../src/main/res/values-in/strings_shared.xml | 2 +- .../src/main/res/values-it/strings_shared.xml | 2 +- .../src/main/res/values-ja/strings_shared.xml | 2 +- .../src/main/res/values-ko/strings_shared.xml | 2 +- .../src/main/res/values-nl/strings_shared.xml | 2 +- .../src/main/res/values-pl/strings_shared.xml | 2 +- .../src/main/res/values-pt/strings_shared.xml | 2 +- .../src/main/res/values-ro/strings_shared.xml | 2 +- .../src/main/res/values-ru/strings_shared.xml | 2 +- .../src/main/res/values-th/strings_shared.xml | 2 +- .../src/main/res/values-vi/strings_shared.xml | 2 +- .../src/main/res/values-zh-rCN/strings_shared.xml | 2 +- .../src/main/res/values-zh-rTW/strings_shared.xml | 2 +- .../resources/src/main/res/values/strings_shared.xml | 2 +- 19 files changed, 25 insertions(+), 23 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index cfbc77c5b8..272b5f91cf 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -5552,15 +5552,17 @@ Hai alzato la tua mano - You and %1$d other raised your hands - You and %1$d others raised your hands + Tu e %1$d altra persona avete alzato la mano + Tu e %1$d di altre persone avete alzato la mano + Tu e altre %1$d persone avete alzato la mano %1$s ha alzato la mano - %1$s and %2$d other raised their hands - %1$s and %2$d others raised their hands + %1$s e %2$d altra persona hanno alzato la mano + %1$s e %2$d di altre persone hanno alzato la mano + %1$s e altre %2$d persone hanno alzato la mano Ci sono oggetti nascosti in questo album. Condividere l\’album significa che gli oggetti nascosti saranno visibili alle persone con cui condividi. Gli oggetti saranno comunque nascosti nel tuo Cloud drive. diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index e07ee62aa3..033f184fa8 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -65,7 +65,7 @@ تعذرت قراءة موقع المزامنة. تحقق من إمكانية الوصول إلى الموقع ومن منح الأذونات لموقع المجلد. - حدث خطأ غير معروف. تواصل مع الدعم. + حدث خطأ غير معروف. تواصل مع support@mega.nz. حدث خطأ ما. @@ -563,7 +563,7 @@ 3. انقر على الصورة الرمزية avatar الخاصة بك. - 4. Tap [A]Cancel subscription[/A]. + 4. انقر على [A]إلغاء الاشتراك[/A]. لا يوجد اتصال بالإنترنت diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index ef067f46c6..66340e439f 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -65,7 +65,7 @@ Die FSID eines Synchronisierungs-Stammordners konnte nicht abgerufen werden. - Ein unbekannter Fehler ist aufgetreten. Wenden Sie sich an den Support. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 923077bf00..66f8e7d99b 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -65,7 +65,7 @@ No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - Se ha producido un error. Ponte en contacto con soporte. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 43a85f363b..ce9733c6cd 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -65,7 +65,7 @@ Impossible de lire l’emplacement de la synchronisation. Vérifiez que l’emplacement est accessible et que les droits ont été accordés pour l’emplacement du dossier. - Un erreur inconnue est survenue. Contactez l’assistance. + An unknown error occurred. Contact support@mega.nz. Un problème est survenu diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 792758e7c3..d33e828a3a 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -65,7 +65,7 @@ Tidak dapat membaca lokasi sinkronisasi. Periksa lokasi dapat diakses dan izin untuk lokasi folder diberikan. - Terjadi kesalahan yang tidak diketahui. Hubungi Bantuan. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index cc17085349..2ebfc0ec38 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -65,7 +65,7 @@ Impossibile leggere la posizione della sincronizzazione. Controlla che la posizione sia accessibile e i permessi per la cartella della posizione siano garantiti. - Si è verificato un errore sconosciuto. Contatta il supporto. + Si è verificato un errore sconosciuto. Contatta support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index b29be12184..518af61b8d 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -65,7 +65,7 @@ 同期の場所を読み取れませんでした。場所がアクセス可能であること、およびフォルダの場所に対するアクセス許可が付与されていることを確認してください。 - 不明なエラーが発生しました。サポートにご連絡ください。 + 不明なエラーが発生しました。support@mega.nzにご連絡ください。 何か問題が発生しました。 diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 1000b46cf7..945ee6b038 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -65,7 +65,7 @@ 동기화 위치를 읽을 수 없습니다. 위치에 접근 가능한지 여부와 폴더 위치에 대한 권한이 승인 되었는지 확인하세요. - 알 수 없는 오류가 발생하였습니다. 지원에 연락하세요. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index e9a832a3d4..4a4293f40e 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -65,7 +65,7 @@ Kan de synchronisatielocatie niet lezen. Controleer of de locatie toegankelijk is en of er machtigingen voor de maplocatie zijn verleend. - Er is een onbekende fout opgetreden. Neem contact op met de klantenservice. + An unknown error occurred. Contact support@mega.nz. Er is iets misgegaan. diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 670bc7ea0d..a880bfad06 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -65,7 +65,7 @@ Nie można odczytać lokalizacji synchronizacji. Sprawdź, czy lokalizacja jest dostępna i czy przyznano uprawnienia do lokalizacji katalogu. - Wystąpił nieznany błąd. Skontaktuj się z pomocą techniczną. + Wystąpił nieznany błąd. Skontaktuj się z support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 72110de316..225313b1ed 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -65,7 +65,7 @@ Não foi possível ler a localização da sincronização. Verifique se o local está acessível e se as permissões para a localização da pasta foram concedidas. - Ocorreu um erro desconhecido - entre em contato com o Suporte. + Ocorreu um erro desconhecido - entre em contato com support@mega.nz. Algo deu errado. diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 36c6e0a826..00fca90584 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -65,7 +65,7 @@ Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. - A apărut o eroare necunoscută. Contactați asistența. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 001e4ebddc..91ef1207b2 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -65,7 +65,7 @@ Не удалось прочитать расположение синхронизации. Убедитесь, что расположение папки доступно и предоставлены права доступа к нему. - Произошла неизвестная ошибка. Обратитесь в поддержку. + Произошла неизвестная ошибка. Напишите на support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 1ce7fc0369..700d1eb76f 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -65,7 +65,7 @@ ไม่สามารถอ่านตำแหน่งที่ตั้งการซิงค์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ - เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ ติดต่อฝ่ายสนับสนุน + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 387b0d8cb6..f12c5a6f3f 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -65,7 +65,7 @@ Không thể đọc được vị trí thư mục. Kiểm tra xem vị trí có thể truy cập được hay không và quyền đi tới vị trí thư mục đã được cấp phép. - Một lỗi không xác định được đã xảy ra. Hãy liên hệ với bộ phận Hỗ trợ. + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index b05be66800..91e386c317 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -65,7 +65,7 @@ 无法读取同步位置。检查该位置是否可访问以及是否已授予该文件夹位置的权限。 - 出现未知错误。请联系客服。 + 出现未知错误。请联系support@mega.nz。 Something went wrong. diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 646e4aa583..bd3248c242 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -65,7 +65,7 @@ 無法讀取同步位置。檢查該位置是否可用,而且是否已授予該資料夾位置的權限。 - 發生未知錯誤。聯繫客服。 + An unknown error occurred. Contact support@mega.nz. Something went wrong. diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index fb6ef8c441..fb1378cca9 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -65,7 +65,7 @@ Couldn’t read sync location. Check the location is accessible and permissions for the folder location are granted. - An unknown error occurred. Contact Support. + An unknown error occurred. Contact support@mega.nz. Something went wrong. From 3853e791714c1c1a9d3e41a3400b0c97ae7edc95 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Fri, 26 Jul 2024 17:02:39 +1200 Subject: [PATCH 192/261] Temporarily do not upload release notes to Google Play Alpha channel --- jenkinsfile/android_release.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkinsfile/android_release.groovy b/jenkinsfile/android_release.groovy index aaaf1c0df5..dbee7d969d 100644 --- a/jenkinsfile/android_release.groovy +++ b/jenkinsfile/android_release.groovy @@ -462,7 +462,7 @@ pipeline { rolloutPercentage: '0', additionalVersionCodes: '487,233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", - recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), +// recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), releaseName: common.readAppVersion1() } } From 6600a221fa895d1bd8c5f31886e82acc384e1efe Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Wed, 31 Jul 2024 09:38:26 +1200 Subject: [PATCH 193/261] Revert "Temporarily do not upload release notes to Google Play Alpha channel" This reverts commit 3853e791714c1c1a9d3e41a3400b0c97ae7edc95. --- jenkinsfile/android_release.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkinsfile/android_release.groovy b/jenkinsfile/android_release.groovy index dbee7d969d..aaaf1c0df5 100644 --- a/jenkinsfile/android_release.groovy +++ b/jenkinsfile/android_release.groovy @@ -462,7 +462,7 @@ pipeline { rolloutPercentage: '0', additionalVersionCodes: '487,233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", -// recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), + recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), releaseName: common.readAppVersion1() } } From 3bd0798d63d75cc8569be30da6c893447dca9b57 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Thu, 1 Aug 2024 06:33:43 +0800 Subject: [PATCH 194/261] T17151275 When multiselection is enabled the Delete option does not work --- .../videosection/view/VideoSectionComposeView.kt | 7 +++---- .../videosection/view/playlist/VideoPlaylistsView.kt | 8 ++++++-- .../presentation/videosection/VideoPlaylistsViewTest.kt | 4 +++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/VideoSectionComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/VideoSectionComposeView.kt index 18704703f2..05ebca3137 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/VideoSectionComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/VideoSectionComposeView.kt @@ -134,10 +134,8 @@ internal fun VideoSectionComposeView( videoSectionViewModel.clearAllSelectedVideoPlaylists() } - is VideoSectionMenuAction.VideoSectionRemoveAction -> { + is VideoSectionMenuAction.VideoSectionRemoveAction -> showDeleteVideoPlaylist = true - videoSectionViewModel.clearAllSelectedVideoPlaylists() - } else -> onMenuAction(action) } @@ -244,7 +242,8 @@ internal fun VideoSectionComposeView( } videoSectionViewModel.removeVideoPlaylists(removedPlaylists) onDeleteDialogButtonClicked() - } + }, + onDeleteDialogNegativeButtonClicked = videoSectionViewModel::clearAllSelectedVideoPlaylists ) }, selectedTab = tabState.selectedTab, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt index e25e4710d0..22c196b8f5 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/view/playlist/VideoPlaylistsView.kt @@ -75,6 +75,7 @@ internal fun VideoPlaylistsView( onCreateDialogPositiveButtonClicked: (String) -> Unit, onRenameDialogPositiveButtonClicked: (playlistID: NodeId, newTitle: String) -> Unit, onDeleteDialogPositiveButtonClicked: (VideoPlaylistUIEntity) -> Unit, + onDeleteDialogNegativeButtonClicked: () -> Unit, onDeletePlaylistsDialogPositiveButtonClicked: () -> Unit, setInputValidity: (Boolean) -> Unit, onClick: (item: VideoPlaylistUIEntity, index: Int) -> Unit, @@ -236,6 +237,7 @@ internal fun VideoPlaylistsView( }, onDismiss = { updateShowDeleteVideoPlaylist(false) + onDeleteDialogNegativeButtonClicked() clickedItem = -1 } ) @@ -421,7 +423,8 @@ private fun VideoPlaylistsViewPreview() { onDeleteDialogPositiveButtonClicked = {}, onDeletedMessageShown = {}, setInputValidity = {}, - onDeletePlaylistsDialogPositiveButtonClicked = {} + onDeletePlaylistsDialogPositiveButtonClicked = {}, + onDeleteDialogNegativeButtonClicked = {} ) } } @@ -450,7 +453,8 @@ private fun VideoPlaylistsViewCreateDialogShownPreview() { onDeleteDialogPositiveButtonClicked = {}, setInputValidity = {}, onDeletedMessageShown = {}, - onDeletePlaylistsDialogPositiveButtonClicked = {} + onDeletePlaylistsDialogPositiveButtonClicked = {}, + onDeleteDialogNegativeButtonClicked = {} ) } } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoPlaylistsViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoPlaylistsViewTest.kt index 68558716f4..09255c09c9 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoPlaylistsViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/videosection/VideoPlaylistsViewTest.kt @@ -54,6 +54,7 @@ class VideoPlaylistsViewTest { errorMessage: Int? = null, onLongClick: ((item: VideoPlaylistUIEntity, index: Int) -> Unit) = { _, _ -> }, onDeletePlaylistsDialogPositiveButtonClicked: () -> Unit = {}, + onDeleteDialogNegativeButtonClicked: () -> Unit = {} ) { composeTestRule.setContent { VideoPlaylistsView( @@ -79,7 +80,8 @@ class VideoPlaylistsViewTest { deletedVideoPlaylistTitles = deletedVideoPlaylistTitles, onDeleteDialogPositiveButtonClicked = onDeleteDialogPositiveButtonClicked, onRenameDialogPositiveButtonClicked = onRenameDialogPositiveButtonClicked, - onDeletePlaylistsDialogPositiveButtonClicked = onDeletePlaylistsDialogPositiveButtonClicked + onDeletePlaylistsDialogPositiveButtonClicked = onDeletePlaylistsDialogPositiveButtonClicked, + onDeleteDialogNegativeButtonClicked = onDeleteDialogNegativeButtonClicked ) } } From 0e2d9996057271b9977e7857602519884d7d10c8 Mon Sep 17 00:00:00 2001 From: Yenel Date: Fri, 2 Aug 2024 13:35:19 +0200 Subject: [PATCH 195/261] TRAN-492 AND - Collision dialogue gets stuck when uploading multiple files --- .../privacy/android/app/namecollision/NameCollisionActivity.kt | 3 ++- .../android/app/namecollision/NameCollisionViewModel.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionActivity.kt b/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionActivity.kt index fef42624be..2b65a3bff3 100644 --- a/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionActivity.kt @@ -195,7 +195,7 @@ class NameCollisionActivity : PasscodeActivity() { createStartTransferView( this, viewModel.uiState.map { it.uploadEvent }, - viewModel::consumeUploadEvent, + { }, ) { transferEvent -> ((transferEvent as StartTransferEvent.FinishUploadProcessing).triggerEvent as TransferTriggerEvent.StartUpload.CollidedFiles).let { setResult( @@ -208,6 +208,7 @@ class NameCollisionActivity : PasscodeActivity() { shouldFinish = viewModel.shouldFinish() ) ) + viewModel.consumeUploadEvent() } } ) diff --git a/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionViewModel.kt b/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionViewModel.kt index 703a99c0ac..407c9c9236 100644 --- a/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/namecollision/NameCollisionViewModel.kt @@ -542,6 +542,7 @@ class NameCollisionViewModel @Inject constructor( uploadFiles( mapOf(path to name), NodeId(parentId), + choice ) } else { uploadUseCase.upload(context, currentCollision, rename) @@ -832,7 +833,7 @@ class NameCollisionViewModel @Inject constructor( } } - fun uploadFiles( + internal fun uploadFiles( pathsAndNames: Map, destinationId: NodeId, choice: NameCollisionChoice? = null, From fc3e16b80a51fc1ba5c519c4e9329aca90e00716 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Sat, 3 Aug 2024 03:03:52 +1200 Subject: [PATCH 196/261] T17158759: Sync transfers with the MEGA app removed from recent apps cause the... --- .../active/HandleTransferEventUseCase.kt | 2 +- .../sd/GetTransferDestinationUriUseCase.kt | 1 + .../active/HandleTransferEventUseCaseTest.kt | 32 ------------------- .../GetTransferDestinationUriUseCaseTest.kt | 9 ++++++ .../data/service/SyncBackgroundService.kt | 23 +++++++++---- 5 files changed, 27 insertions(+), 40 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCase.kt index 31ad9ee2b8..733a8a5e01 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCase.kt @@ -36,7 +36,7 @@ class HandleTransferEventUseCase @Inject internal constructor( suspend operator fun invoke(vararg events: TransferEvent) { val transferEvents = events.filterNot { event -> event.transfer.isVoiceClip() || event.transfer.isBackgroundTransfer() - || event.transfer.isStreamingTransfer || event.transfer.isSyncTransfer + || event.transfer.isStreamingTransfer || event.transfer.isBackupTransfer } if (transferEvents.isEmpty()) return diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCase.kt index 5894494627..5271a5b023 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCase.kt @@ -24,6 +24,7 @@ class GetTransferDestinationUriUseCase @Inject constructor( suspend operator fun invoke(transfer: Transfer): DestinationUriAndSubFolders? { return when { transfer.transferType != TransferType.DOWNLOAD -> null + transfer.isSyncTransfer -> null transfer.isRootTransfer -> { transfer.getSDCardTransferUri()?.let { diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCaseTest.kt index d10cf17105..7fd29ad2d6 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/active/HandleTransferEventUseCaseTest.kt @@ -122,38 +122,6 @@ class HandleTransferEventUseCaseTest { verifyNoInteractions(transferRepository) } - @Test - fun `test that upload sync transfer does not invoke repository nor GetTransferDestinationUriUseCase when event is TransferFinishEvent`() = - runTest { - val transfer = mock { - on { this.transferType } doReturn TransferType.GENERAL_UPLOAD - on { this.isSyncTransfer } doReturn true - } - val transferEvent = mock { - on { this.transfer }.thenReturn(transfer) - } - - underTest.invoke(transferEvent) - verifyNoInteractions(getTransferDestinationUriUseCase) - verifyNoInteractions(transferRepository) - } - - @Test - fun `test that download sync transfer does not invoke repository nor GetTransferDestinationUriUseCase when event is TransferFinishEvent`() = - runTest { - val transfer = mock { - on { this.transferType } doReturn TransferType.DOWNLOAD - on { this.isSyncTransfer } doReturn true - } - val transferEvent = mock { - on { this.transfer }.thenReturn(transfer) - } - - underTest.invoke(transferEvent) - verifyNoInteractions(getTransferDestinationUriUseCase) - verifyNoInteractions(transferRepository) - } - @Test fun `test that backups transfer does not invoke repository nor GetTransferDestinationUriUseCase when event is TransferFinishEvent`() = runTest { diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCaseTest.kt index 7ec6106667..4941e0f371 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/transfers/sd/GetTransferDestinationUriUseCaseTest.kt @@ -46,6 +46,15 @@ class GetTransferDestinationUriUseCaseTest { assertThat(underTest(transfer)).isNull() } + @Test + fun `test that null is returned when is a sync transfer`() = runTest { + val transfer = mock { + on { it.transferType } doReturn TransferType.DOWNLOAD + on { it.isSyncTransfer } doReturn true + } + assertThat(underTest(transfer)).isNull() + } + @Test fun `test that transfer's targetUri is returned when it's a root transfer`() = runTest { val expected = "destinationUri" diff --git a/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt b/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt index 963f25b270..7ed06f16b6 100644 --- a/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt +++ b/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt @@ -11,23 +11,24 @@ import androidx.core.app.NotificationCompat import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.withContext +import mega.privacy.android.data.extensions.collectChunked import mega.privacy.android.domain.entity.AccountType import mega.privacy.android.domain.entity.BatteryInfo import mega.privacy.android.domain.entity.account.AccountDetail -import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.qualifier.LoginMutex import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.environment.MonitorBatteryInfoUseCase import mega.privacy.android.domain.usecase.login.BackgroundFastLoginUseCase import mega.privacy.android.domain.usecase.network.MonitorConnectivityUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase -import mega.privacy.android.domain.usecase.transfers.completed.AddCompletedTransferUseCase +import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.feature.sync.R import mega.privacy.android.feature.sync.domain.usecase.sync.PauseResumeSyncsBasedOnBatteryAndWiFiUseCase import mega.privacy.android.feature.sync.domain.usecase.sync.PauseSyncUseCase @@ -35,6 +36,8 @@ import mega.privacy.android.feature.sync.domain.usecase.sync.ResumeSyncUseCase import mega.privacy.android.feature.sync.domain.usecase.sync.option.MonitorSyncByWiFiUseCase import timber.log.Timber import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds /** * The service runs SDK in the background and synchronizes folders automatically @@ -74,7 +77,7 @@ internal class SyncBackgroundService : LifecycleService() { internal lateinit var monitorTransferEventsUseCase: MonitorTransferEventsUseCase @Inject - internal lateinit var addCompletedTransferUseCase: AddCompletedTransferUseCase + internal lateinit var handleTransferEventUseCase: HandleTransferEventUseCase override fun onCreate() { super.onCreate() @@ -158,10 +161,16 @@ internal class SyncBackgroundService : LifecycleService() { lifecycleScope.launch { monitorTransferEventsUseCase() .catch { Timber.e(it) } - .filterIsInstance() .filter { it.transfer.isSyncTransfer } - .collect { transferEvent -> - addCompletedTransferUseCase(transferEvent.transfer, transferEvent.error) + .collectChunked( + chunkDuration = 2.seconds, + flushOnIdleDuration = 200.milliseconds, + ) { transferEvents -> + withContext(NonCancellable) { + launch { + handleTransferEventUseCase(events = transferEvents.toTypedArray()) + } + } } } } From 3f54951ab4b5504af6619b0d6f3f80a3afa066d9 Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Mon, 5 Aug 2024 12:14:24 +0900 Subject: [PATCH 197/261] T17142684 Dismiss storage overquota dialog when use clicks "Upgrade" --- .../android/feature/sync/ui/newfolderpair/SyncNewFolderScreen.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/sync/src/main/java/mega/privacy/android/feature/sync/ui/newfolderpair/SyncNewFolderScreen.kt b/feature/sync/src/main/java/mega/privacy/android/feature/sync/ui/newfolderpair/SyncNewFolderScreen.kt index c1773ba9d3..e07238ad6a 100644 --- a/feature/sync/src/main/java/mega/privacy/android/feature/sync/ui/newfolderpair/SyncNewFolderScreen.kt +++ b/feature/sync/src/main/java/mega/privacy/android/feature/sync/ui/newfolderpair/SyncNewFolderScreen.kt @@ -193,6 +193,7 @@ private fun SyncNewFolderScreenContent( confirmButtonText = stringResource(sharedResR.string.sync_error_dialog_insufficient_storage_confirm_button), cancelButtonText = stringResource(sharedResR.string.sync_error_dialog_insufficient_storage_cancel_button), onConfirm = { + onDismissStorageOverQuota() onOpenUpgradeAccount() }, onDismiss = { From c4df1388d32b0d47584aab97856393cbab47d1fc Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Mon, 5 Aug 2024 20:00:13 +0900 Subject: [PATCH 198/261] T17169939 Fix Kotlin Flow leaks on SyncBackgroundService (cherry picked from commit 6a4dd2d5d8499cca9ad017e52aeb2d248e7eabba) 6a4dd2d5 T17169939 Fix Kotlin Flow leaks on SyncBackgroundService --- .../data/service/SyncBackgroundService.kt | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt b/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt index 7ed06f16b6..cb76bd0505 100644 --- a/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt +++ b/feature/sync/src/main/java/mega/privacy/android/feature/sync/data/service/SyncBackgroundService.kt @@ -84,6 +84,27 @@ internal class SyncBackgroundService : LifecycleService() { Timber.d("SyncBackgroundService created") serviceInstance = this startForegroundOnAndroid14() + monitorCompletedSyncTransfers() + lifecycleScope.launch { + combine( + monitorConnectivityUseCase(), + monitorSyncByWiFiUseCase(), + monitorBatteryInfoUseCase(), + monitorAccountDetailUseCase() + ) { connectedToInternet: Boolean, syncByWifi: Boolean, batteryInfo: BatteryInfo, accountDetail: AccountDetail -> + Triple( + batteryInfo, + Pair( + connectedToInternet, + syncByWifi, + ), + accountDetail.levelDetail?.accountType == AccountType.FREE + ) + }.collect { (batteryInfo, connectionDetails, isFreeAccount) -> + val (connectedToInternet, syncByWifi) = connectionDetails + updateSyncState(connectedToInternet, syncByWifi, batteryInfo, isFreeAccount) + } + } } /* @@ -133,27 +154,6 @@ internal class SyncBackgroundService : LifecycleService() { runCatching { backgroundFastLoginUseCase() }.getOrElse(Timber::e) } } - monitorCompletedSyncTransfers() - lifecycleScope.launch { - combine( - monitorConnectivityUseCase(), - monitorSyncByWiFiUseCase(), - monitorBatteryInfoUseCase(), - monitorAccountDetailUseCase() - ) { connectedToInternet: Boolean, syncByWifi: Boolean, batteryInfo: BatteryInfo, accountDetail: AccountDetail -> - Triple( - batteryInfo, - Pair( - connectedToInternet, - syncByWifi, - ), - accountDetail.levelDetail?.accountType == AccountType.FREE - ) - }.collect { (batteryInfo, connectionDetails, isFreeAccount) -> - val (connectedToInternet, syncByWifi) = connectionDetails - updateSyncState(connectedToInternet, syncByWifi, batteryInfo, isFreeAccount) - } - } return START_STICKY } From 3e891afee95f1e657f5ee3d30d84c99a7aeffe6c Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Tue, 6 Aug 2024 13:36:17 +0530 Subject: [PATCH 199/261] Update strings --- app/src/main/res/values-ar/strings.xml | 10 +- app/src/main/res/values-de/strings.xml | 10 +- app/src/main/res/values-es/strings.xml | 10 +- app/src/main/res/values-fr/strings.xml | 18 +- app/src/main/res/values-in/strings.xml | 10 +- app/src/main/res/values-it/strings.xml | 10 +- app/src/main/res/values-ja/strings.xml | 10 +- app/src/main/res/values-ko/strings.xml | 10 +- app/src/main/res/values-nl/strings.xml | 10 +- app/src/main/res/values-pl/strings.xml | 10 +- app/src/main/res/values-pt/strings.xml | 10 +- app/src/main/res/values-ro/strings.xml | 182 +++++++++--------- .../values-ro/strings_document_scanner.xml | 2 +- app/src/main/res/values-ru/strings.xml | 10 +- app/src/main/res/values-th/strings.xml | 12 +- app/src/main/res/values-vi/strings.xml | 20 +- app/src/main/res/values-zh-rCN/strings.xml | 10 +- app/src/main/res/values-zh-rTW/strings.xml | 10 +- .../strings_device_center_feature.xml | 24 +-- .../res/values-ro/strings_sync_feature.xml | 10 +- .../src/main/res/values-ar/strings_shared.xml | 48 ++++- .../src/main/res/values-de/strings_shared.xml | 50 ++++- .../src/main/res/values-es/strings_shared.xml | 48 ++++- .../src/main/res/values-fr/strings_shared.xml | 53 ++++- .../src/main/res/values-in/strings_shared.xml | 48 ++++- .../src/main/res/values-it/strings_shared.xml | 48 ++++- .../src/main/res/values-ja/strings_shared.xml | 44 ++++- .../src/main/res/values-ko/strings_shared.xml | 56 +++++- .../src/main/res/values-nl/strings_shared.xml | 50 ++++- .../src/main/res/values-pl/strings_shared.xml | 52 ++++- .../src/main/res/values-pt/strings_shared.xml | 51 ++++- .../src/main/res/values-ro/strings_shared.xml | 84 ++++++-- .../src/main/res/values-ru/strings_shared.xml | 56 +++++- .../src/main/res/values-th/strings_shared.xml | 92 ++++++--- .../src/main/res/values-vi/strings_shared.xml | 54 +++++- .../main/res/values-zh-rCN/strings_shared.xml | 48 ++++- .../main/res/values-zh-rTW/strings_shared.xml | 46 ++++- .../src/main/res/values/strings_shared.xml | 50 ++++- 38 files changed, 1104 insertions(+), 272 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 937504544e..480c3cf15a 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -665,7 +665,7 @@ حول - سياسة الخصوصية + سياسة الخصوصية والبيانات شروط الخدمة @@ -6108,13 +6108,13 @@ [A]باقتك المجانية لها حد 60 دقيقة للاجتماعات. يتمتع مستخدمو برو Pro بمكالمات غير محدودة وما يصل إلى 1000 مشارك.[/A] [B]قم بالترقية الآن.[/B] - سيتم محاسبتك بمبلغ %1$s على الفور وسيتم تجديد اشتراكك تلقائيًا بعد 1 شهر بمبلغ %2$s في الشهر. سيتم فرض رسوم على حساب غوغل بلاي Google Play الخاص بك للتجديد في غضون 24 ساعة من نهاية كل فترة دفع. لإلغاء اشتراكك يجب عليك إيقاف التجديد التلقائي لاشتراك MEGA Pro ميغا برو الخاص بك قبل 24 ساعة على الأقل من نهاية فترة الفاتورة عبر الاشتراكات في [A]غوغل بلاي Google Play[/A].\nمن خلال ترقية حسابك فإنك توافق على [B]شروط خدمة[/B] و [C]سياسة الخصوصية[/C] الخاصين بميغا MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - سيتم محاسبتك %1$s على الفور وسيتم تجديد اشتراكك تلقائيًا بعد 12 شهرًا بمبلغ %2$s في السنة. سيتم فرض رسوم على حساب غوغل بلاي Google Play الخاص بك للتجديد في غضون 24 ساعة من نهاية كل فترة دفع. لإلغاء اشتراكك يجب عليك إلغاء التجديد التلقائي لاشتراك ميغا برو MEGA Pro الخاص بك قبل 24 ساعة على الأقل من نهاية فترة الفاتورة عبر الاشتراكات في [A]غوغل بلاي Google Play[/A].\nمن خلال ترقية حسابك فإنك توافق على[B]شروط الخدمة[/B] و [C]سياسة الخصوصية[/C] الخاصين بميغا MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - سيتم محاسبتك بمبلغ %1$s على الفور وسيتم تجديد اشتراكك تلقائيًا بعد 1 شهر. سيتم فرض رسوم على حساب غوغل بلاي Google Play الخاص بك للتجديد في غضون 24 ساعة من نهاية كل فترة دفع. لإلغاء اشتراكك يجب عليك إيقاف التجديد التلقائي لاشتراك MEGA Pro ميغا برو الخاص بك قبل 24 ساعة على الأقل من نهاية فترة الفاتورة عبر الاشتراكات في [A]غوغل بلاي Google Play[/A].\nمن خلال ترقية حسابك فإنك توافق على [B]شروط خدمة[/B] و [C]سياسة الخصوصية[/C] الخاصين بميغا MEGA. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - سيتم محاسبتك على الفور وسيتم تجديد اشتراكك تلقائيًا بعد 12 شهر. سيتم فرض رسوم على حساب غوغل بلاي Google Play الخاص بك للتجديد في غضون 24 ساعة من نهاية كل فترة دفع. لإلغاء اشتراكك يجب عليك إيقاف التجديد التلقائي لاشتراك MEGA Pro ميغا برو الخاص بك قبل 24 ساعة على الأقل من نهاية فترة الفاتورة عبر الاشتراكات في [A]غوغل بلاي Google Play[/A].\nمن خلال ترقية حسابك فإنك توافق على [B]شروط خدمة[/B] و [C]سياسة الخصوصية[/C] الخاصين بميغا MEGA. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. تم إلغاء تفعيل حساب الأعمال Business diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 8ec9224e71..7029ae41b2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -633,7 +633,7 @@ Version - Datenschutzerklärung + Datenschutzrichtlinien Allgemeine Geschäftsbedingungen @@ -5176,13 +5176,13 @@ [A]Bei Ihrem kostenlosen Paket sind Meetings auf 60 Minuten begrenzt. Pro-Pakete unterliegen keinen zeitlichen Begrenzungen und erlauben bis zu 1000 Teilnehmer.[/A] [B]Jetzt upgraden.[/B] - Ihnen werden sofort %1$s abgebucht, und Ihr Abonnement wird nach einem Monat automatisch für %2$s pro Monat verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und der [C]Datenschutzerklärung[/C] von MEGA einverstanden. + Ihnen werden sofort %1$s abgebucht, und Ihr Abonnement wird nach einem Monat automatisch für %2$s pro Monat verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und den [C]Datenschutzrichtlinien[/C] von MEGA einverstanden. - Ihnen werden sofort %1$s abgebucht, und Ihr Abonnement wird nach 12 Monaten automatisch für %2$s pro Jahr verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und der [C]Datenschutzerklärung[/C] von MEGA einverstanden. + Ihnen werden sofort %1$s abgebucht, und Ihr Abonnement wird nach 12 Monaten automatisch für %2$s pro Jahr verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und den [C]Datenschutzrichtlinien[/C] von MEGA einverstanden. - Die Abbuchung erfolgt sofort, und Ihr Abonnement wird nach einem Monat automatisch verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und der [C]Datenschutzerklärung[/C] von MEGA einverstanden. + Die Abbuchung erfolgt sofort, und Ihr Abonnement wird nach einem Monat automatisch verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und den [C]Datenschutzrichtlinien[/C] von MEGA einverstanden. - Die Abbuchung erfolgt sofort, und Ihr Abonnement wird nach 12 Monaten automatisch verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und der [C]Datenschutzerklärung[/C] von MEGA einverstanden. + Die Abbuchung erfolgt sofort, und Ihr Abonnement wird nach 12 Monaten automatisch verlängert. Die Verlängerung wird innerhalb von 24 Stunden vor Ende des Abrechnungszeitraums von Ihrem Google-Play-Account abgebucht. Um Ihr Abonnement zu kündigen, müssen Sie die automatische Verlängerung Ihres MEGA-Pro-Abonnements mindestens 24 Stunden vor Ablauf Ihres Abrechnungszeitraums in [A]Google Play[/A] unter Abonnements deaktivieren.\nIndem Sie Ihren Account upgraden, erklären Sie sich mit den [B]Nutzungsbedingungen[/B] und den [C]Datenschutzrichtlinien[/C] von MEGA einverstanden. Business-Account deaktiviert diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 906297ba17..c98f939999 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -641,7 +641,7 @@ Acerca de - Política de privacidad + Política de privacidad y datos Términos de servicio @@ -5409,13 +5409,13 @@ [A]Tu plan gratuito tiene un límite de 60 minutos por reunión. Los usuarios Pro tienen llamadas ilimitadas y hasta 1000 participantes.[/A] [B]Amplía ahora.[/B] - Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 1 mes a %2$s por mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 1 mes a %2$s por mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad y de datos[/C] de MEGA. - Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 12 meses a %2$s por año. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + Se te cobrarán %1$s de inmediato y tu suscripción se renovará de forma automática después de 12 meses a %2$s al año. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad y de datos[/C] de MEGA. - Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 1 mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 1 mes. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad y de datos[/C] de MEGA. - Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 12 meses. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad[/C] de MEGA. + Se te cobrará de inmediato y tu suscripción se renovará de forma automática después de 12 meses. La renovación se cobrará a tu cuenta de Google Play dentro de las 24 horas posteriores al final de cada período de facturación. Para cancelar la suscripción, debes desactivar la renovación automática de tu suscripción a MEGA Pro al menos 24 horas antes del final de tu período de facturación a través de Suscripciones en [A]Google Play[/A].\nAl ampliar tu cuenta, aceptas los [B]Términos de servicio[/B] y la [C]Política de privacidad y de datos[/C] de MEGA. Cuenta Business desactivada diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9c6d0975c3..29760f16aa 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -641,7 +641,7 @@ À propos - Politique de protection des renseignements personnels + Politique de protection des renseignements personnels et des données Conditions générales d’utilisation @@ -1047,7 +1047,7 @@ %1$s a quitté la conversation de groupe - Copié dans le presse-papiers + A été copié dans le presse-papiers Erreur de dialogue en ligne @@ -1741,7 +1741,7 @@ Le mot de passe est erroné.\nSauvegardez votre clé de récupération dès que possible. - Copier vers le presse-papiers + Copier dans le presse-papiers Poursuivre la déconnexion @@ -1997,7 +1997,7 @@ Envoyer des contacts - Déconnecté + Déconnexion Votre compte a été activé. Veuillez vous connecter. @@ -4887,7 +4887,7 @@ Quiconque disposant de ces liens peut consulter et télécharger vos données - Enregistrer sur Disque nuagique + Enregistrer sur mon Disque nuagique Enregistrement… @@ -5409,13 +5409,13 @@ [A]Votre abonnement gratuit limite les réunions à 60 minutes. Les utilisateurs MEGA Pro bénéficient d’une durée d’appel illimitée et d’un maximum de 1 000 participants.[/A] [B]Surclassez votre compte maintenant.[/B] - %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 1 mois pour %2$s par mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels[/C] de MEGA. + %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 1 mois pour %2$s par mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels et des données[/C] de MEGA. - %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 12 mois pour %2$s par an. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels[/C] de MEGA. + %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 12 mois pour %2$s par an. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels et des données[/C] de MEGA. - %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 1 mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels[/C] de MEGA. + %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 1 mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels et des données[/C] de MEGA. - %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 12 mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels[/C] de MEGA. + %1$s vous seront facturés immédiatement et votre abonnement sera renouvelé automatiquement après 12 mois. Le renouvellement sera débité de votre compte Google Play dans les 24 heures suivant la fin de chaque période de facturation. Pour annuler votre abonnement, vous devez désactiver le renouvellement automatique de votre abonnement MEGA Pro au moins 24 heures avant la fin de votre période de facturation dans la section Abonnements de [A]Google Play[/A].\nEn surclassant votre compte, vous acceptez les [B]Conditions générales d’utilisation[/B] et la [C]Politique de protection des renseignements personnels et des données[/C] de MEGA. Le compte Pour entreprise a été désactivé diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 998c89788a..70b59d2db4 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -625,7 +625,7 @@ Tentang - Kebijakan Privasi + Privacy and Data Policy Persyaratan Layanan @@ -4943,13 +4943,13 @@ [A]Paket gratis anda memiliki batas 60 menit untuk rapat. Pengguna pro memiliki panggilan tak terbatas dan hingga 1000 peserta.[/A] [B]Tingkatkan sekarang.[/B] - Anda akan dikenakan biaya %1$s segera dan langganan anda akan diperpanjang secara otomatis setelah 1 bulan untuk %2$s per bulan. Akun Google Play anda akan dikenakan biaya untuk pembaruan dalam waktu 24 jam setelah akhir setiap periode penagihan. Untuk membatalkan langganan anda, anda harus menonaktifkan perpanjangan otomatis langganan MEGA Pro anda setidaknya 24 jam sebelum akhir periode penagihan anda melalui Langganan di [A]Google Play[/A].\nDengan memutakhirkan akun anda, anda menyetujui [B]Ketentuan Layanan[/B] dan [C]Kebijakan Privasi[/C] MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Anda akan dikenakan biaya %1$s segera dan langganan anda akan diperpanjang secara otomatis setelah 12 bulan untuk %2$s per tahun. Akun Google Play anda akan dikenakan biaya untuk pembaruan dalam waktu 24 jam setelah akhir setiap periode penagihan. Untuk membatalkan langganan anda, anda harus menonaktifkan perpanjangan otomatis langganan MEGA Pro anda setidaknya 24 jam sebelum akhir periode penagihan anda melalui Langganan di [A]Google Play[/A].\nDengan memutakhirkan akun anda, anda menyetujui [B]Ketentuan Layanan[/B] dan [C]Kebijakan Privasi[/C] MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Anda akan ditagih segera dan langganan anda akan diperpanjang secara otomatis setelah 1 bulan. Akun Google Play anda akan dikenakan biaya untuk pembaruan dalam waktu 24 jam setelah akhir setiap periode penagihan. Untuk membatalkan langganan anda, anda harus menonaktifkan perpanjangan otomatis langganan MEGA Pro anda setidaknya 24 jam sebelum akhir periode penagihan anda melalui Langganan di [A]Google Play[/A].\nDengan memutakhirkan akun anda, anda menyetujui [B]Ketentuan Layanan[/B] dan [C]Kebijakan Privasi[/C] MEGA. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Anda akan ditagih segera dan langganan anda akan diperpanjang secara otomatis setelah 12 bulan. Akun Google Play anda akan dikenakan biaya untuk pembaruan dalam waktu 24 jam setelah akhir setiap periode penagihan. Untuk membatalkan langganan anda, anda harus menonaktifkan perpanjangan otomatis langganan MEGA Pro anda setidaknya 24 jam sebelum akhir periode penagihan anda melalui Langganan di [A]Google Play[/A].\nDengan memutakhirkan akun anda, anda menyetujui [B]Ketentuan Layanan[/B] dan [C]Kebijakan Privasi[/C] MEGA. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Akun bisnis dinonaktifkan diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 272b5f91cf..561ba607fa 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -641,7 +641,7 @@ Info - Politica sulla privacy + Politica sulla Privacy e sui Dati Termini di Servizio @@ -5409,13 +5409,13 @@ [A]Il tuo piano gratuito prevede un limite di 60 minuti per i meeting. Gli utenti Pro hanno chiamate illimitate e fino a 1000 partecipanti.[/A] [B]Effettua l\’upgrade adesso.[/B] - Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese al costo di %2$s al mese. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Ti verrà addebitato %1$s immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 12 mesi al costo di %2$s all\’anno. Il rinnovo verrà addebitato sul tuo account Google Play entro 24 ore dalla fine di ogni periodo di fatturazione. Per annullare l\’abbonamento, devi disattivare il rinnovo automatico dell\’abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - L\’addebito avverrà immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 1 mese. Il tuo account Google Play riceverà un addebito per il rinnovo entro le 24 ore precedenti la fine del periodo di fatturazione. Per annullare il tuo abbonamento, devi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - L\’addebito avverrà immediatamente e l\’abbonamento si rinnoverà automaticamente dopo 12 mesi. Il tuo account Google Play riceverà un addebito per il rinnovo entro le 24 ore precedenti la fine del periodo di fatturazione. Per annullare il tuo abbonamento, devi disattivare il rinnovo automatico del tuo abbonamento MEGA Pro almeno 24 ore prima della fine del periodo di fatturazione tramite Abbonamenti nel [A]Google Play[/A].\nEffettuando l\’upgrade del tuo account, accetti i [B]Termini di servizio[/B] e la [C]Politica sulla privacy[/C] di MEGA. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Account Business disattivato diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 3256401849..7f73da5629 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -625,7 +625,7 @@ 会社概要 - プライバシーポリシー + プライバシーおよびデータポリシー ご利用規約 @@ -4943,13 +4943,13 @@ [A]無料プランではミーティングに60分の制限があります。Proユーザー様は無制限の通話と、最大1000人の参加者まで可能です。[/A][B]ぜひ今すぐアップグレードしてください。[/B] - すぐに%1$sが請求され、お客様のサブスクリプションは1 か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + すぐに%1$sが請求され、お客様のサブスクリプションは1か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーおよびデータポリシー[/C]に同意されたことになります。 - すぐに%1$sが請求され、お客様のサブスクリプションは12 か月後に月額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + すぐに%1$sが請求され、お客様のサブスクリプションは12か月後に年額%2$sで自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーおよびデータポリシー[/C]に同意されたことになります。 - すぐに請求され、お客様のサブスクリプションは1 か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + すぐに請求され、お客様のサブスクリプションは1か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーおよびデータポリシー[/C]に同意されたことになります。 - すぐに請求され、お客様のサブスクリプションは12 か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24 時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーポリシー[/C]に同意されたことになります。 + すぐに請求され、お客様のサブスクリプションは12 か月後に自動的に更新されます。Google Playアカウントには、各請求期間の終了から24 時間以内に更新料金が請求されます。サブスクリプションをキャンセルするには、請求期間が終了する少なくとも24 時間前に、[A]Google Play[/A]のサブスクリプション経由でMEGA Proサブスクリプションの自動更新を無効にする必要があります。\nアカウントをアップグレードすると、MEGAの[B]ご利用規約[/B]および[C]プライバシーおよびデータポリシー[/C]に同意されたことになります。 ビジネスアカウントの停止 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 85bac34d01..c3c0a73565 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -625,7 +625,7 @@ 대하여 - 개인정보 보호 정책 + 개인정보 및 데이터 처리 방침 이용 약관 @@ -4943,13 +4943,13 @@ [A]무료 요금제는 회의에 60분 제한이 있습니다. Pro 이용자는 무제한 통화와 최대 1,000명의 참여자가 가능합니다.[/A] [B]지금 업그레이드.[/B] - 즉시 %1$s이/가 청구될 것이며 구독은 1개월 후 자동으로 매월 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + 즉시 %1$s이/가 청구될 것이며 구독은 1개월 후 자동으로 매월 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 및 데이터 정책[/C]에 동의하는 것입니다. - 즉시 %1$s이/가 청구될 것이며 구독은 12개월 후 자동으로 매년 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + 즉시 %1$s이/가 청구될 것이며 구독은 12개월 후 자동으로 매년 %2$s으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 및 데이터 정책[/C]에 동의하는 것입니다. - 요금이 즉시 청구될 것이며 구독은 1개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + 요금이 즉시 청구될 것이며 구독은 1개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 및 데이터 정책[/C]에 동의하는 것입니다. - 요금이 즉시 청구될 것이며 구독은 12개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 처리 방침[/C]에 동의하는 것입니다. + 요금이 즉시 청구될 것이며 구독은 12개월 후 자동으로 갱신됩니다. 당신의 Google Play 계정은 매 결제 주기 말일로부터 24시간 내에 청구될 것입니다. 구독을 취소하려면 [A]Google Play[/A]의 구독을 통해 결제 주기 말일의 24시간 전에 MEGA Pro 구독의 자동 갱신을 비활성화해야 합니다.\n계정을 업그레이드 함으로써, 당신은 MEGA의 [B]이용 약관[/B]과 [C]개인정보 및 데이터 정책[/C]에 동의하는 것입니다. 비즈니스 계정이 비활성화됨 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b19879bb9e..33e9fa2407 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -633,7 +633,7 @@ Over - Privacybeleid + Privacy- en Gegevensbeleid Algemene Voorwaarden @@ -5176,13 +5176,13 @@ [A]Uw gratis abonnement heeft een limiet van 60 minuten voor vergaderingen. Pro-gebruikers kunnen onbeperkt bellen en tot 1000 deelnemers.[/A] [B]Nu upgraden.[/B] - Er worden onmiddelijk kosten in rekening gebracht %1$s en uw abonnement wordt na 1   maand automatisch verlengd voor %2$s per maand. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + Er word onmiddelijk %1$s afgeschreven en uw abonnement wordt na 1 maand automatisch verlengd voor %2$s per maand. Uw Google   Play-account wordt binnen 24 uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24 uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacy- en Gegevensbeleid[/C]. - Er worden onmiddelijk kosten in rekening gebracht %1$s en uw abonnement wordt na 12   maanden automatisch verlengd voor %2$s per jaar. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + Er word onmiddelijk %1$s afgeschreven en uw abonnement wordt na 12 maanden automatisch verlengd voor %2$s per jaar. Uw Google   Play-account wordt binnen 24 uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24 uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacy- en Gegevensbeleid[/C]. - Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 1   maand automatisch verlengd. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 1 maand automatisch verlengd. Uw Google   Play-account wordt binnen 24 uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24 uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacy- en Gegevensbeleid[/C]. - Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 12   maanden automatisch verlengd. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacybeleid[/C]. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Zakelijke account gedeactiveerd diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 688ca3a323..9d52c1fd0c 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -649,7 +649,7 @@ O Nas - Polityka Prywatności + Polityka prywatności i danych Regulamin serwisu @@ -5642,13 +5642,13 @@ [A]Twój darmowy plan ma limit 60 minut na spotkania. Użytkownicy Pro mają nieograniczoną liczbę połączeń i do 1000 uczestników.[/A] [B]Uaktualnij teraz.[/B] - Zostaniesz obciążony %1$s natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 1   miesiącu %2$s miesięcznie. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godziny przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Zostaniesz obciążony %1$s natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 12   miesiącach %2$s rocznie. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Zostaniesz obciążony natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 1   miesiącach. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Zostaniesz obciążony natychmiast, a Twoja subskrypcja zostanie automatycznie odnowiona po 12   miesiącach. Twoje konto Google   Play zostanie obciążone opłatą za odnowienie w ciągu 24 godzin od zakończenia każdego okresu rozliczeniowego. Aby anulować subskrypcję, musisz wyłączyć automatyczne odnawianie subskrypcji MEGA   Pro co najmniej 24   godzin przed końcem okresu rozliczeniowego za pośrednictwem Subskrypcji w [A]Google   Play[/A].\nUaktualniając swoje konto, zgadzasz się na MEGA [B]Regulamin[/B] a [C]Politykę prywatności[/C]. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Biznes firmowe dezaktywowane diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a9f56927e7..7f5c2fd800 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -641,7 +641,7 @@ Sobre - Política de privacidade + Política de privacidade e de dados Termos de serviço @@ -5409,13 +5409,13 @@ [A]O seu plano gratuito tem um limite de 60 minutos para reuniões. Usuários com planos Pro podem fazer chamadas ilimitadas com até 1000 participantes.[/A] [B]Faça um upgrade.[/B] - Neste momento, você receberá uma cobrança no valor de %1$s e a sua assinatura será renovada automaticamente depois de 1 mês por %2$s ao mês. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada mês do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do mês adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade[/C] do MEGA. + Neste momento, você receberá uma cobrança no valor de %1$s e a sua assinatura será renovada automaticamente depois de 1 mês por %2$s ao mês. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada mês do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do mês adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade e de dados[/C] do MEGA. - Neste momento, você receberá uma cobrança no valor de %1$s e a sua assinatura será renovada automaticamente depois de 12 meses por %2$s ao ano. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada mês do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do mês adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade[/C] do MEGA. + Neste momento, você receberá uma cobrança no valor de %1$s e a sua assinatura será renovada automaticamente depois de 12 meses por %2$s ao ano. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada mês do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do mês adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade e de dados[/C] do MEGA. - Neste momento, você receberá uma cobrança e a sua assinatura será renovada automaticamente depois de 1 mês. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada ano do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do ano adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade[/C] do MEGA. + Neste momento, você receberá uma cobrança e a sua assinatura será renovada automaticamente depois de 1 mês. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada ano do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do ano adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade e de dados[/C] do MEGA. - Neste momento, você receberá uma cobrança e a sua assinatura será renovada automaticamente depois de 12 meses. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada ano do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do ano adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade[/C] do MEGA. + Neste momento, você receberá uma cobrança e a sua assinatura será renovada automaticamente depois de 12 meses. A sua conta da Google Play Store receberá a cobrança pela renovação durante as 24 horas posteriores ao final de cada ano do plano. Para cancelar o seu plano, você deve desativar a renovação automática da sua assinatura Pro do MEGA ao menos 24 horas antes do final do ano adquirido por meio das Assinaturas da [A]Google Play Store[/A].\nAo fazer o upgrade da conta, você concorda com os [B]Termos de serviço[/B] e a [C]Política de privacidade e de dados[/C] do MEGA. Conta Business desativada diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 73de30ce83..786c83a087 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -129,7 +129,7 @@ Conectați-vă - E-mail + Adresa de e-mail Parolă @@ -147,7 +147,7 @@ Nicio conexiune la rețea - Ai fost deconectat de pe acest aparat dintr-o altă locație + Ați fost deconectat de pe acest dispozitiv dintr-o altă locație Se generează cheile de criptare @@ -167,7 +167,7 @@ Prenume - Nume + Nume de familie Sunt de acord cu [A]Termenii de utilizare a serviciului[/A] MEGA @@ -273,7 +273,7 @@ Adaugă contacte noi folosind butonul de mai jos - Spațiu liber insuficient pe aparat + Spațiu liber insuficient pe dispozitiv Cheie de decriptare @@ -293,15 +293,15 @@ Vezi transferurile - Nu există nicio aplicație disponibilă pentru a executa acest fișier pe aparat + Nu există nicio aplicație disponibilă pentru a executa acest fișier pe dispozitiv - Nu există aplicații disponibile pe aparat pentru a deschide această locație + Nu există aplicații disponibile pe dispozitiv pentru a deschide această locație Este posibil să nu ai instalate aplicații care acceptă acest tip de fișiere Partajează linkul - Șterge linkul + Ștergeți linkul Părăsește partajarea @@ -363,9 +363,9 @@ Gestionează partajarea - Șterge + Ștergeți - Cerere ștearsă + Cerere a fost ștearsă Cerere retrimisă @@ -473,7 +473,7 @@ Ultima sesiune - Se modifică parola + Se schimbă parola Parolă nouă @@ -515,7 +515,7 @@ Opțiuni pentru codul de acces - Comprimarea video folosește cantități considerabile de electricitate. Conectați aparatul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. + Comprimarea video folosește cantități considerabile de electricitate. Conectați dispozitivul la priză pentru încărcare dacă videoclipurile care urmează să fie comprimate sunt mai mari de %s. Dacă este activată, informațiile despre locație vor fi incluse în imaginile dvs. Vă rugăm să aveți grijă când le împărtășiți. @@ -525,7 +525,7 @@ Șterge fișierele offline - Șterge contul + Ștergeți contul În prezent folosind %s @@ -591,9 +591,9 @@ Include etichetele locațiilor - Solicită-mi încărcarea activă a aparatului + Solicită-mi încărcarea activă a dispozitivului - Păstrează numele fișierelor precum în aparat + Păstrează numele fișierelor precum în dispozitiv Folder local pentru cameră @@ -627,7 +627,7 @@ %1$d de încercări eșuate pentru codul de acces - Vei fi deconectat(ă) și fișierele tale offline vor fi șterse după 10 încercări eșuate. + Veți fi deconectat și fișierele dvs. offline vor fi șterse după 10 încercări eșuate Codurile de acces nu coincid. Încearcă din nou. @@ -641,7 +641,7 @@ Despre - Politica de confidențialitate + Politica privind confidențialitatea și datele Termenii de utilizare a serviciului @@ -731,7 +731,7 @@ parola se introduce aici - Acesta este ultimul pas pentru a vă șterge contul. Veți pierde definitiv toate datele stocate în cloud. Vă rugăm să introduceți parola mai jos. + Acesta este ultimul pas pentru a vă șterge contul. Veți pierde definitiv toate datele stocate în cloud. Introduceți parola mai jos. Verificarea adresei de e-mail @@ -781,13 +781,13 @@ Acesta este ultimul pas pentru a vă schimba adresa dvs. de e-mail. Introduceți parola mai jos. - Modifică e-mailul + Schimbați adresa de e-mail - Capturează + Capturați - Alege poza + Alegeți poza - Șterge poza + Ștergeți poza Cheia pe care ați furnizat-o nu se potrivește cu acest cont. Asigurați-vă că folosiți cheia de recuperare corectă și încercați din nou. @@ -797,7 +797,7 @@ Noua dvs. adresă de e-mail trebuie validată. Verificați căsuța de e-mail a noii adrese de e-mail pentru a continua. - Îți ștergi poza de profil? + Ștergeți fotografia de profil? Editează @@ -1001,7 +1001,7 @@ (editat) - Schimbă titlul + Schimbați titlul Dacă părăsești chatul de grup, nu vei mai avea acces să citești sau să scrii mesaje. @@ -1095,7 +1095,7 @@ Temă cromatică - Înlătură + Închideți Mesaj nerecunoscut @@ -1288,7 +1288,7 @@ Eroare la schimbarea pozei de profil - Poza de profil ștearsă + Poza de profil a fost ștearsă Eroare la ștergerea pozei de profil @@ -1310,11 +1310,11 @@ Contact - Anulează contul + Ștergeți contul - Dacă ștergi contul, nu vei putea accesa datele contului, contactele sau conversațiile MEGA.\nNu vei putea anula această acțiune. + Dacă ștergeți contul, nu veți putea accesa datele contului, contactele MEGA sau conversațiile.\nNu veți putea anula această acțiune. - Șterge + Ștergeți Informații @@ -1336,7 +1336,7 @@ Elimini atașamentul? - Vezi fișierele (%1$d șterse) + Afișați fișierele (%1$d șters) Silențios @@ -1366,7 +1366,7 @@ Mutați în Coșul de gunoi? - Ștergi de pe MEGA? + Ștergeți de pe MEGA? Notificări de chat @@ -1440,7 +1440,7 @@ Vă rugăm să furnizați feedback-ul dvs. aici: - Modelul aparatului + Modelul dispozitivului Versiunea Android @@ -1502,7 +1502,7 @@ Resetează codul QR - Șterge codul QR + Ștergeți codul QR În Unitatea cloud @@ -1518,7 +1518,7 @@ Codul QR nu este resetat din cauza unei erori. Vă rugăm să încercați din nou. - Codul QR nu a fost șters din cauza unei erori. Vă rugăm să încercați din nou. + Codul QR nu a fost șters din cauza unei erori. Încercați din nou. Invitația a fost trimisă @@ -1550,7 +1550,7 @@ Creează cod QR - Aliniați codul QR pentru a-l digitaliza cu camera aparatului dvs. + Aliniați codul QR pentru a-l digitaliza cu camera dispozitivului dvs. Vezi @@ -1655,9 +1655,9 @@ Restabilește - Ștergi versiunea? - Ștergi versiunile? - Ștergi versiunile? + Ștergeți versiunea? + Ștergeți versiunile? + Ștergeți versiunile? Această versiune va fi eliminată definitiv. @@ -1707,7 +1707,7 @@ În acest fel, vei vedea instantaneu mesaje noi\npe telefonul Android. - Deschide [A]Setările[/A] de pe aparatul Android + Deschide [A]Setările[/A] de pe dispozitivul Android Deschide [A]Aplicații și notificări[/A] @@ -1743,7 +1743,7 @@ Copiază în clipboard - Continuă pentru a te deconecta + Continuați să vă deconectați Cheie de recuperare @@ -1825,7 +1825,7 @@ Scanează sau copiază sămânța în aplicația de autentificare. - Asigurați-vă că faceți backupul acestei semințe într-un loc sigur în cazul în care vă pierdeți aparatul. + Asigurați-vă că faceți backupul acestei semințe într-un loc sigur în cazul în care vă pierdeți dispozitivul. Vă rugăm să introduceți codul din 6 cifre generat de aplicația dvs. de autentificare. @@ -1841,17 +1841,17 @@ Cod nevalid - Ți-ai pierdut aparatul pentru autentificare? + Ați pierdut dispozitivul de autentificare? Verificarea autentificării - Modifică parola + Schimbați parola - Modifică e-mailul + Schimbați adresa de e-mail - Șterge contul + Ștergeți contul - Dezactivează + Dezactivați A apărut o eroare la încercarea de a dezactiva autentificarea cu doi factori. Vă rugăm să încercați din nou. @@ -1863,7 +1863,7 @@ Deschide în - Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe aparat + Nu există nicio aplicație disponibilă care să permită autentificarea cu doi factori pe dispozitiv Închide @@ -1969,7 +1969,7 @@ Managementul fișierelor - Șterge toate versiunile mai vechi ale fișierelor mele + Ștergeți toate versiunile mai vechi ale fișierelor mele Toate fișierele actuale vor rămâne. Doar versiunile istorice ale fișierelor vor fi șterse. @@ -2099,7 +2099,7 @@ [A]%1$s[/A][B] a eliminat linkul chatului.[/B] - Șterge linkul chatului + Ștergeți linkul chatului Link al chatului @@ -2131,7 +2131,7 @@ Fișiere - Salvează pe aparat + Salvați pe dispozitiv Încarcă pe MEGA @@ -2155,7 +2155,7 @@ Contact șters - [A]%s [/A][B]te-a șters ca contact.[/B] + [A]%s [/A][B]v-a șters ca contact.[/B] Contact blocat @@ -2229,7 +2229,7 @@ Dimensiunea comprimării video este prea mare - Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți aparatul la taxarea pentru a continua. + Dimensiunea totală a videoclipurilor de comprimat depășește %s, vă rugăm să puneți dispozitivul la taxarea pentru a continua. Această setare se va aplica data viitoare când rulează Încărcări cameră @@ -2389,7 +2389,7 @@ %1$s . %2$s - Încă îi poți acorda lui MEGA permisiuni în setările aparatului + Încă îi poți acorda lui MEGA permisiuni în setările dispozitivului Mesaj redirecționat @@ -2425,7 +2425,7 @@ Trimite ca mesaj. - Șterge versiunile anterioare + Ștergeți versiunile anterioare Ștergi versiunile anterioare? @@ -2463,7 +2463,7 @@ Fotografiile dvs. în cloud - Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. Introduceți parola dvs. @@ -2529,7 +2529,7 @@ Niciun link de chat disponibil. - Link-ul de chat șters + Link-ul de chat a fost șters Versiunea a fost restaurată @@ -2627,11 +2627,11 @@ Contactează administratorul contului business pentru a rezolva problema și a-ți activa contul. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat. + Când vă deconectați, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv. Când te deconectezi, transferurile în curs vor fi anulate. - Când te deconectezi, fișierele din secțiunea Offline vor fi șterse de pe aparat și transferurile în curs vor fi anulate. + Când vă deconectați, fișierele din secțiunea Offline vor fi șterse de pe dispozitiv și transferurile în curs vor fi anulate. Nume necunoscut @@ -2821,11 +2821,11 @@ [A]%1$s[/A][B] a dezactivat ștergerea mesajelor.[/B] - Șterge toate mesajele și fișierele partajate în această conversație. Această acțiune este ireversibilă. + Ștergeți toate mesajele și fișierele partajate în această conversație. Această acțiune este ireversibilă. Ștergerea istoricului - Șterge automat mesajele mai vechi de o anumită perioadă de timp. + Ștergeți automat mesajele mai vechi de o anumită perioadă de timp. Dezactivat @@ -2839,7 +2839,7 @@ Gestionează istoricul chatului - Șterge automat mesajele mai vechi de: + Ștergeți automat mesajele mai vechi de: Sigur vreți să ștergeți istoricul complet al mesajelor din această conversație? @@ -3049,7 +3049,7 @@ Producție - Schimbă serverul + Schimbați serverul Afișează numerele liniilor @@ -3135,13 +3135,13 @@ Îți mai aduci aminte parola?\nMEGA nu îți poate reseta parola dacă o uiți. - Schimbați numele + Schimbați nume Schimbați imaginea profilului Adaugă un număr de telefon - MEGA are nevoie de permisiuni de scriere în spațiul de stocare al aparatului pentru a continua. + MEGA are nevoie de permisiuni de scriere în spațiul de stocare al dispozitivului pentru a continua. Mâine, %1$s @@ -3289,7 +3289,7 @@ Vizualizare principală - Deconectarea îți șterge conținutul offline. + Deconectarea șterge conținutul dvs. offline. Interfața utilizatorului @@ -3399,7 +3399,7 @@ Aveți deja un abonament. Dacă cumpărați altul, veți fi taxat de două ori. Pentru a evita acest lucru, anulați abonamentul curent accesând MEGA într-un browser web desktop sau mobil. Vizitați Centrul nostru de ajutor pentru mai multe informații. - Accesați Setări pentru a permite MEGA permisiunea de a accesa aparatele din apropiere utilizând Bluetooth. + Accesați Setări pentru a permite MEGA permisiunea de a accesa dispozitivele din apropiere utilizând Bluetooth. Nu putem continua cu facturarea. Dacă utilizați o aplicație duală, vă rugăm să luați în considerare conectarea la MEGA fără ea. Dacă nu, încercați să actualizați prin browserul dvs. web. @@ -3407,7 +3407,7 @@ Aveți un abonament MEGA activ cu %1$s. Trebuie să o anulați separat prin %2$s, deoarece MEGA nu este în măsură să o anuleze pentru dvs. Vizitați Centrul nostru de ajutor pentru mai multe informații. - Ai un abonament MEGA activ. Acesta va fi anulat automat după ștergerea contului. Vizitează centrul nostru de asistență pentru mai multe informații. + Aveți un abonament MEGA activ. Acesta va fi anulat automat după ștergerea contului. Pentru mai multe informații, accesați Centrul nostru de ajutor. Aveți un abonament MEGA activ cu Apple. Trebuie să îl anulați separat de contul dvs. Apple, deoarece MEGA nu îl poate anula pentru dvs. Vizitați Centrul nostru de ajutor pentru mai multe informații. @@ -3437,7 +3437,7 @@ A încălcat Termenii de utilizare a serviciului - Acest aparat nu are o aplicație care să selecteze foldere. + Acest dispozitiv nu are o aplicație care să selecteze foldere. Următorul fișier audio @@ -3487,9 +3487,9 @@ %1$s și alți %2$d au părăsit apelul - Șterge definitiv + Ștergeți definitiv - Șterge + Ștergeți [A]Se reînnoiește [/A] [B]%s[/B] @@ -3539,35 +3539,35 @@ Înlocuiește fișierul în folderul de destinație cu fișierul pe care îl muți. - Mută și înlocuiește + Mutați și înlocuiți Nu muta Fișierul pe care îl muți va fi redenumit sub numele: - Mută și redenumește + Mutați și redenumiți Înlocuiește fișierul în folderul de destinație cu fișierul pe care îl copiezi. - Copiază și înlocuiește + Copiați și înlocuiți Nu copia Fișierul pe care îl copiezi va fi redenumit sub numele: - Copiază și redenumește + Copiați și redenumiți Îmbină folderul la destinație cu folderul pe care îl copiezi. - Copiază și îmbină + Copiați și fuzionați Îmbină folderul la destinație cu folderul pe care îl copiezi. - Mută și îmbină + Mutați și fuzionați Îmbină folderul la destinație cu folderul pe care îl încarci. - Încarcă și îmbină + Încărcați și fuzionați Niciun fișier nu va fi modificat. Vei păstra fișierul de mai jos: @@ -3715,7 +3715,7 @@ Începe să chatuiești acum - Chatuiește securizat și privat, cu oricine și de pe orice aparat, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. + Chatuiește securizat și privat, cu oricine și de pe orice dispozitiv, știind că nimeni nu îți poate citi chaturile, nici măcar MEGA. Începe întâlnirea acum @@ -3805,7 +3805,7 @@ Ați adăugat deja toate contactele dvs. la acest chat. Dacă doriți să adăugați mai mulți participanți, invitați-i mai întâi la lista dvs. de contacte. - Imagine salvată în galeria aparatului + Imagine salvată în galeria dispozitivului Introduceți numele albumului @@ -3859,14 +3859,14 @@ „%s” a fost ștearsă - %d albume au fost șterse - %d albume șterse + %d albume au fost șterse + %d albume au fost șterse - Ștergi albumul? - Ștergi albumele? - Ștergi albumele? + Ștergeți albumul? + Ștergeți albumele? + Ștergeți albumele? @@ -3895,7 +3895,7 @@ Elimini din album? - Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe aparat. + Pentru a activa încărcările camerei, permiteți MEGA accesul la fotografiile și alte suporturi media de pe dispozitiv. Activează accesul @@ -3933,7 +3933,7 @@ Acces refuzat - Ați refuzat accesul MEGA la fișierele de stocare și media ale aparatului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. + Ați refuzat accesul MEGA la fișierele de stocare și media ale dispozitivului dvs. Dacă doriți să continuați partajarea, permiteți permisiunea MEGA. Acordă permisiunea @@ -4759,7 +4759,7 @@ Amintiți-vă preferințele - Centrul de aparate + Centrul de dispozitive În fiecare zi @@ -5267,7 +5267,7 @@ Acest apel este înregistrat - Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe aparatul persoanei care o înregistrează. + Rămânând în apel, dați permisiunea de a fi înregistrat. Înregistrarea este stocată numai pe dispozitivul persoanei care o înregistrează. Bine, am înțeles @@ -5409,13 +5409,13 @@ [A]Abonamentul dvs. gratuit are o limită de 60 de minute pentru întâlniri. Utilizatorii Pro au apeluri nelimitate și până la 1000 de participanți.[/A] [B]Upgradați acum.[/B] - Veți fi taxat %1$s imediat și abonamentul dvs. se va reînnoi automat după 1 lună pentru %2$s pe lună. Contul dvs. Google Play va fi taxat pentru reînnoire în termen de 24 de ore de la sfârșitul fiecărei perioade de facturare. Pentru a vă anula abonamentul, trebuie să dezactivați reînnoirea automată a abonamentului MEGA Pro cu cel puțin 24 de ore înainte de sfârșitul perioadei de facturare prin Abonamente în [A]Google Play[/A].\nPrin actualizarea contului dvs., sunteți de acord cu MEGA [B]Termenii de utilizare a serviciului[/B] și [C]Politica de confidențialitate[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Veți fi taxat %1$s imediat iar abonamentul dvs. se va reînnoi automat după 12 luni la %2$s pe an. Contul dvs. Google Play va fi taxat pentru reînnoire în termen de 24 de ore de la sfârșitul fiecărei perioade de facturare. Pentru a vă anula abonamentul, trebuie să dezactivați reînnoirea automată a abonamentului MEGA Pro cu cel puțin 24 de ore înainte de sfârșitul perioadei de facturare prin Abonamente în [A]Google Play[/A].\nPrin actualizarea contului dvs., sunteți de acord cu MEGA [B]Termenii de utilizare a serviciului[/B] și [C]Politica de confidențialitate[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Veți fi taxat imediat, iar abonamentul dvs. se va reînnoi automat după 1 lună. Contul dvs. Google Play va fi taxat pentru reînnoire în termen de 24 de ore de la sfârșitul fiecărei perioade de facturare. Pentru a vă anula abonamentul, trebuie să dezactivați reînnoirea automată a abonamentului MEGA Pro cu cel puțin 24 de ore înainte de sfârșitul perioadei de facturare prin Abonamente în [A]Google Play[/A].\nPrin actualizarea contului dvs., sunteți de acord cu MEGA [B]Termenii de utilizare a serviciului[/B] și [C]Politica de confidențialitate[/C]. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Veți fi taxat imediat, iar abonamentul dvs. se va reînnoi automat după 12 luni. Contul dvs. Google Play va fi taxat pentru reînnoire în termen de 24 de ore de la sfârșitul fiecărei perioade de facturare. Pentru a vă anula abonamentul, trebuie să dezactivați reînnoirea automată a abonamentului MEGA Pro cu cel puțin 24 de ore înainte de sfârșitul perioadei de facturare prin Abonamente în [A]Google Play[/A].\nPrin actualizarea contului dvs., sunteți de acord cu MEGA [B]Termenii de utilizare a serviciului[/B] și [C]Politica de confidențialitate[/C]. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Contul Business a fost dezactivat diff --git a/app/src/main/res/values-ro/strings_document_scanner.xml b/app/src/main/res/values-ro/strings_document_scanner.xml index 8ad875eaf1..dd3ec1a89b 100644 --- a/app/src/main/res/values-ro/strings_document_scanner.xml +++ b/app/src/main/res/values-ro/strings_document_scanner.xml @@ -35,7 +35,7 @@ Înlătură - Ștergi scanarea actuală? + Ștergeți scanarea actuală? Permisiunea Cameră este necesară pentru a scana documente diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4229dd3fbf..bdff061122 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -649,7 +649,7 @@ О программе - Политика конфиденциальности + Политика конфиденциальности и данных Условия использования @@ -5642,13 +5642,13 @@ [A]В бесплатном плане встречи ограничены 60 минутами. У пользователей Pro звонки не ограничены по длительности и могут включать до 1000 участников.[/A] [B]Улучшить план.[/B] - У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 1 месяц за %2$s в месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 1 месяц за %2$s в месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности и данных[/C]. - У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 12 месяцев за %2$s в год. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + У вас будет сразу же списано %1$s, и подписка будет автоматически продлена через 12 месяцев за %2$s в год. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности и данных[/C]. - У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 1 месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 1 месяц. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности и данных[/C]. - У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 12 месяцев. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности[/C]. + У вас будет сразу же списана сумма оплаты, и подписка будет автоматически продлена через 12 месяцев. Плата за продление будет взиматься с вашего аккаунта Google Play в течение 24 часов после окончания каждого расчётного периода. Чтобы отменить подписку MEGA Pro, вам нужно отключить её автоматическое продление как минимум за 24 часа до окончания расчётного периода в меню «Подписки» в [A]Google Play[/A].\nУлучшая аккаунт, вы соглашаетесь с [B]Условиями использования[/B] и [C]Политикой конфиденциальности и данных[/C]. Бизнес-аккаунт деактивирован diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index e3c5e7d6cd..988122c823 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -625,7 +625,7 @@ เกี่ยวกับ - นโยบายสิทธิส่วนบุคคล + นโยบายความเป็นส่วนตัวและข้อมูล เงื่อนไขการให้บริการ @@ -4943,13 +4943,13 @@ [A]แผนฟรีของคุณมีข้อจำกัดเวลาการประชุม 60 นาที ผู้ใช้ Pro สามารถโทรได้ไม่จำกัดและมีผู้เข้าร่วมประชุมได้สูงสุด 1000 คน[/A] [B]อัปเกรดเลย[/B] - คุณจะถูกเรียกเก็บเงิน %1$s ทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน ในราคา %2$s ต่อเดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - คุณจะถูกเรียกเก็บเงิน %1$s ทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 12 เดือน ในราคา %2$s ต่อปี บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุโดยอัตโนมัติหลังจาก 1 เดือน บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - คุณจะถูกเรียกเก็บเงินทันที และการสมัครใช้งานของคุณจะต่ออายุหลังจาก 12 เดือนโดยอัตโนมัติ บัญชี Google Play ของคุณจะถูกเรียกเก็บเงินเพื่อใช้ในการต่ออายุภายใน 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินแต่ละรอบ หากต้องการยกเลิกการสมัครใช้งาน คุณต้องปิดการต่ออายุการสมัครใช้งาน MEGA Pro ของคุณแบบอัตโนมัติอย่างน้อย 24 ชั่วโมงก่อนสิ้นสุดรอบการเรียกเก็บเงินของคุณ ผ่านเมนูการสมัครใช้งานใน [A]Google Play[/A] \nเมื่อคุณอัปเกรดบัญชีของคุณ แสดงว่าคุณยอมรับ[B]เงื่อนไขการให้บริการ[/B]และ[C]นโยบายสิทธิส่วนบุคคล[/C]ของ MEGA + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. บัญชีธุรกิจถูกปิดการใช้งานแล้ว @@ -5099,5 +5099,5 @@ ตำแหน่งที่ตั้ง - No location information + ไม่มีข้อมูลเกี่ยวกับตำแหน่งที่ตั้ง \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 70c34a1f71..06c4f6bc7e 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -625,7 +625,7 @@ Thông Tin - Chính Sách Riêng Tư + Chính Sách Dữ Liệu và Riêng Tư Điều Khoản Dịch Vụ @@ -1701,7 +1701,7 @@ Xem Trước Nội Dung URL - Luôn Luôn Thực Hiện + Luôn luôn cho phép Không phải lúc này @@ -1757,9 +1757,9 @@ Mã không phù hợp - Thiết bị có cài app Lập Xác Thực đã bị mất? + Thiết bị có cài app lập xác thực đã bị mất? - Xác Thực Đăng Nhập + Xác thực đăng nhập Đổi mật khẩu @@ -1841,9 +1841,9 @@ Bảo lưu - Chuyển Vào Bảo Lưu + Bảo lưu lại - Chuyển Khỏi Bảo Lưu + Bỏ bảo lưu %s đã được bảo lưu @@ -4943,13 +4943,13 @@ [A]Gói miễn phí của bạn có giới hạn cuộc họp là 60 phút. Người dùng Pro có thời lượng cuộc gọi không giới hạn và có tối đa 1000 người tham gia.[/A] [B]Nâng cấp ngay bây giờ.[/B] - Quý khách sẽ phải chi trả %1$s ngay lập tức và gói đăng ký của quý khách sẽ tự động gia hạn sau 1 tháng với giá %2$s mỗi tháng. Tài khoản Google Play của quý khách sẽ bị tính phí gia hạn trong vòng 24 giờ từ thời điểm kết thúc của mỗi kỳ thanh toán. Để hủy gói đăng ký của mình, quý khách phải tắt tự động gia hạn gói đăng ký MEGA Pro của mình ít nhất là 24 giờ trước lúc kết thúc thời hạn thanh toán trong trang Gói thuê bao của [A]Google Play[/A].\nVới việc nâng cấp tài khoản của mình, quý khách đồng ý với[B]Điều Khoản Dịch Vụ[/B] và [C]Chính Sách Riêng Tư[/C] của MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Quý khách sẽ phải chi trả %1$s ngay lập tức và gói đăng ký của quý khách sẽ tự động gia hạn sau 12 tháng với giá %2$s mỗi năm. Tài khoản Google Play của quý khách sẽ bị tính phí gia hạn trong vòng 24 giờ từ thời điểm kết thúc của mỗi kỳ thanh toán. Để hủy gói đăng ký của mình, quý khách phải tắt tự động gia hạn gói đăng ký MEGA Pro của mình ít nhất là 24 giờ trước lúc kết thúc thời hạn thanh toán trong trang Gói thuê bao của [A]Google Play[/A].\nVới việc nâng cấp tài khoản của mình, quý khách đồng ý với[B]Điều Khoản Dịch Vụ[/B] và [C]Chính Sách Riêng Tư[/C] của MEGA. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Quý khách sẽ phải chi trả ngay lập tức và gói đăng ký của quý khách sẽ tự động gia hạn sau 1 tháng. Tài khoản Google Play của quý khách sẽ bị tính phí gia hạn trong vòng 24 giờ từ thời điểm kết thúc của mỗi kỳ thanh toán. Để hủy gói đăng ký của mình, quý khách phải tắt tự động gia hạn gói đăng ký MEGA Pro của mình ít nhất là 24 giờ trước lúc kết thúc thời hạn thanh toán trong trang Gói thuê bao của [A]Google Play[/A].\nVới việc nâng cấp tài khoản của mình, quý khách đồng ý với[B]Điều Khoản Dịch Vụ[/B] và [C]Chính Sách Riêng Tư[/C] của MEGA. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - Quý khách sẽ phải chi trả ngay lập tức và gói đăng ký của quý khách sẽ tự động gia hạn sau 12 tháng. Tài khoản Google Play của quý khách sẽ bị tính phí gia hạn trong vòng 24 giờ từ thời điểm kết thúc của mỗi kỳ thanh toán. Để hủy gói đăng ký của mình, quý khách phải tắt tự động gia hạn gói đăng ký MEGA Pro của mình ít nhất là 24 giờ trước lúc kết thúc thời hạn thanh toán trong trang Gói thuê bao của [A]Google Play[/A].\nVới việc nâng cấp tài khoản của mình, quý khách đồng ý với[B]Điều Khoản Dịch Vụ[/B] và [C]Chính Sách Riêng Tư[/C] của MEGA. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Tài khoản Doanh Nghiệp bị vô hiệu hóa diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 30135039ad..a31aaed770 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -625,7 +625,7 @@ 关于 - 隐私政策 + 隐私与数据政策 服务条款 @@ -4943,13 +4943,13 @@ [A]您的免费方案有60分钟的会议时间限制。Pro会员用户具有无限通话时间,并且最多可达1000名参与者。[/A][B]立即升级。[/B] - 您将被立即收取%1$s的费用,并且您的订阅将在1 个月后自动以每月%2$s续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您将被立即收取%1$s的费用,并且您的订阅将在12 个月后自动以每年%2$s续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您将立即被收取费用,并且您的订阅将在1 个月后自动续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您将立即被收取费用,并且您的订阅将在12 个月后自动续订。您的Google Play帐户将在每个计费周期结束后的24 小时内被收取续订费用。若要取消订阅,您必须在计费周期结束前至少24 小时通过[A]Google Play[/A]中的订阅停用MEGA Pro订阅的自动续订。\n升级您的帐户即表示您同意MEGA的[B]服务条款[/B]和[C]隐私政策[/C]。 + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. 企业帐户已停用 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 81ada6f08d..e2c47676c2 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -625,7 +625,7 @@ 關於 - 私隱權政策 + 隱私和資料政策 服務條款 @@ -4943,13 +4943,13 @@ [A]您的免費方案有60分鐘的會議時間限制。Pro會員的通話時間不受限制,而且最多可容納1000位與會者。[/A][B]立即升級。[/B] - 您將立即被收取%1$s的費用,而且您的訂閱將在1 個月後自動以每月%2$s續訂。您的Google Play帳戶將在每個計費週期結束後24 小時內被收取續訂費用。若要取消訂閱,您必須在計費週期結束前至少24 小時透過[A]Google Play[/A]中的訂閱停用MEGA Pro訂閱的自動續訂。\n升級您的帳戶即表示您同意MEGA的[B]服務條款[/B]和[C]隱私權政策[/C]。 + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您將立即被收取%1$s的費用,而且您的訂閱將在12 個月後自動以每年%2$s續訂。您的Google Play帳戶將在每個計費週期結束後24 小時內被收取續訂費用。若要取消訂閱,您必須在計費週期結束前至少24 小時透過[A]Google Play[/A]中的訂閱停用MEGA Pro訂閱的自動續訂。\n升級您的帳戶即表示您同意MEGA的[B]服務條款[/B]和[C]隱私權政策[/C]。 + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您將立即被收取費用,而且您的訂閱將在1 個月後自動續訂。您的Google Play帳戶將在每個計費週期結束後24 小時內被收取續訂費用。若要取消訂閱,您必須在計費週期結束前至少24 小時透過[A]Google Play[/A]中的訂閱停用MEGA Pro訂閱的自動續訂。\n升級您的帳戶即表示您同意MEGA的[B]服務條款[/B]和[C]隱私權政策[/C]。 + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - 您將立即被收取費用,而且您的訂閱將在12 個月後自動續訂。您的Google Play帳戶將在每個計費週期結束後24 小時內被收取續訂費用。若要取消訂閱,您必須在計費週期結束前至少24 小時透過[A]Google Play[/A]中的訂閱停用MEGA Pro訂閱的自動續訂。\n升級您的帳戶即表示您同意MEGA的[B]服務條款[/B]和[C]隱私權政策[/C]。 + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. 商業帳戶已停用 diff --git a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml index 700148b6ad..3e29b4669f 100644 --- a/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml +++ b/feature/devicecenter/src/main/res/values-ro/strings_device_center_feature.xml @@ -1,19 +1,19 @@ - Redenumire aparatul + Redenumire dispozitivul Redenumește Anulați - Acest aparat + Acest dispozitiv - Alte aparate + Alte dispozitive Stare necunoscută - Aparat necunoscut + Dispozitiv necunoscut La zi @@ -41,7 +41,7 @@ Blocat - Centrul de aparate + Centrul de dispozitive Încărcări cameră @@ -59,7 +59,7 @@ Nicio eroare de sincronizare - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat Folderul ales nu poate fi sincronizat @@ -111,9 +111,9 @@ Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din aparat nu poate fi localizat acum, încercați din nou mai târziu. + Folderul din dispozitiv nu poate fi localizat acum, încercați din nou mai târziu. - Folderul din aparat dvs. nu poate fi localizat + Folderul din dispozitiv dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați asistența. @@ -123,13 +123,13 @@ Încărcări camere sunt dezactivate - Introduceți un nume de aparat. + Introduceți un nume de dispozitiv. - Un aparat cu acest nume există deja. Introduceți un alt nume. + Un dispozitiv cu acest nume există deja. Introduceți un alt nume. Următoarele caractere nu sunt permise: %1$s - Aparat a fost redenumit + Dispozitiv a fost redenumit Maximum 32 de caractere @@ -145,7 +145,7 @@ Nimic nu este încă configurat - Căutarea aparatelor + Căutarea dispozitivelor Căutarea sincronizării diff --git a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml index 4db625810c..cfe48bf683 100644 --- a/feature/sync/src/main/res/values-ro/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-ro/strings_sync_feature.xml @@ -7,7 +7,7 @@ Sincronizează - MEGA trebuie să acceseze spațiul de stocare al aparatului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. + MEGA trebuie să acceseze spațiul de stocare al dispozitivului dvs. pentru a sincroniza folderul local. Atingeți aici pentru a permite accesul. Pentru a sincroniza continuu fișierele și folderele, permiteți MEGA să ruleze în fundal @@ -53,7 +53,7 @@ Conflictul a fost rezolvat - Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest aparat. Datele dvs. sunt întotdeauna în siguranță la noi. + Pentru backup-ul fișierelor dvs., MEGA are nevoie de acces la fișierele și folderele din acest dispozitiv. Datele dvs. sunt întotdeauna în siguranță la noi. Continuați @@ -69,7 +69,7 @@ Nicio problemă - Folderul aparatului + Folderul dispozitivului Folder MEGA @@ -81,7 +81,7 @@ Sincronizată - Folderul aparatului + Folderul dispozitivului Folder MEGA @@ -97,7 +97,7 @@ Numai Wi-Fi - Va trebui să configurați un folder local pe aparatul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud + Va trebui să configurați un folder local pe dispozitivul dvs. care se va sincroniza cu un folder ales de pe Unitatea dvs. cloud Monitorizarea sincronizărilor diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 033f184fa8..10b2373aee 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -333,7 +333,7 @@ لم يتم إعداد عمليات المزامنة - قم بمزامنة مجلد محلي على جهازك مع مجلد على ميغا MEGA. + Sync a folder on your device with a folder on MEGA. إضافة مزامنة جديدة @@ -584,4 +584,50 @@ المحارف التالية غير مسموح بها: %1$s مزامنة + + جاري انشاء مجلدات… + + Starting transfers… + + لا تغلق التطبيق. إذا أغلقته فستفقد عمليات تراسل المعطيات التي لم يتم وضعها في قائمة الانتظار. + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + إلغاء + + تابع + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + جاري إلغاء عمليات التراسل... + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 66340e439f..8176a54a22 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -65,7 +65,7 @@ Die FSID eines Synchronisierungs-Stammordners konnte nicht abgerufen werden. - An unknown error occurred. Contact support@mega.nz. + Ein unbekannter Fehler ist aufgetreten. Wenden Sie sich an support@mega.nz. Something went wrong. @@ -301,7 +301,7 @@ Keine Synchronisierungen eingerichtet - Synchronisieren Sie einen lokalen Ordner auf Ihrem Gerät mit einem Ordner auf MEGA. + Synchronisieren Sie einen Ordner auf Ihrem Gerät mit einem Ordner auf MEGA. Neue Synchronisierung hinzufügen @@ -552,4 +552,50 @@ Die folgenden Zeichen sind nicht zulässig: %1$s Synchronisierung + + Ordner werden erstellt… + + Transfers werden gestartet… + + Schließen Sie die App nicht. Andernfalls gehen Transfers, die noch nicht in die Warteschlange aufgenommen wurden, verloren. + + + 1 Ordner und %1$d Datei gefunden. + 1 Ordner und %1$d Dateien gefunden. + + + + %1$d Ordner + %1$d Ordner + + + + %1$d/%2$d Ordner + %1$d/%2$d Ordner + + + .debris (lokalen Cache) löschen + + Lokalen Cache löschen? + + Backups von früheren Versionen Ihrer synchronisierten Dateien werden dauerhaft von Ihrem Gerät gelöscht. \n\nÜberprüfen Sie den Ordner .debris auf Ihrem lokalen Gerät, um zu sehen, ob Sie Daten aus diesem Ordner wiederherstellen möchten. + + Abbrechen + + Fortfahren + + Ordner .debris erfolgreich geleert + + + %1$s Ordner und %2$d Datei gefunden. + %1$s und %2$d Dateien gefunden. + + + No tags + + Transfers werden abgebrochen… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 66f8e7d99b..e2099c10ea 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -309,7 +309,7 @@ Ninguna sincronización configurada - Sincroniza una carpeta local en tu dispositivo con una carpeta de MEGA. + Sync a folder on your device with a folder on MEGA. Añadir sincronización @@ -560,4 +560,50 @@ Los siguientes caracteres no están permitidos: %1$s Sincronizar + + Creando carpetas… + + Starting transfers… + + No cierres la aplicación. Si la cierras, las transferencias que aún no estén en cola se perderán. + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + Cancelar + + Continuar + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Cancelando transferencias… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index ce9733c6cd..fa06fb19f9 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -65,7 +65,7 @@ Impossible de lire l’emplacement de la synchronisation. Vérifiez que l’emplacement est accessible et que les droits ont été accordés pour l’emplacement du dossier. - An unknown error occurred. Contact support@mega.nz. + Un erreur inconnue est survenue. Contactez support@mega.nz. Un problème est survenu @@ -309,7 +309,7 @@ Aucune synchronisation n’est configurée - Synchronisez un dossier local sur votre appareil avec un dossier sur MEGA. + Synchronisez un dossier de votre appareil avec un dossier sur MEGA. Ajouter une nouvelle synchronisation @@ -560,4 +560,53 @@ Les caractères suivants ne sont pas autorisés : %1$s Synchronisations + + Création des dossiers… + + Démarrage des transferts… + + Ne fermez pas l’appli. Si vous la fermez, les transferts qui ne sont pas encore dans la file d’attente seront perdus. + + + 1 dossier et %1$d fichier ont été trouvés. + 1 dossier et %1$d fichiers ont été trouvés. + 1 dossier et %1$d fichiers ont été trouvés. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d dossier + %1$d/%2$d dossiers + %1$d/%2$d dossiers + + + Vider .debris (cache local) + + Nettoyer les débris ? + + Les sauvegardes des versions précédentes de vos fichiers synchronisés seront irrémédiablement supprimées de votre appareil.\n\nParcourez le dossier .debris de votre appareil local pour décider si vous devez restaurer quelque chose. + + Annuler + + Poursuivre + + Le dossier .debris a été vidé + + + %1$s et %2$d fichier ont été trouvés + %1$s et %2$d de fichiers ont été trouvés + %1$s et %2$d fichiers ont été trouvés + + + No tags + + Annulation des transferts… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index d33e828a3a..b4661f86c0 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -296,7 +296,7 @@ No syncs set up - Sync a local folder on your device with a folder on MEGA. + Sync a folder on your device with a folder on MEGA. Add new sync @@ -547,4 +547,50 @@ Karakter berikut tidak diperbolehkan: %1$s Sinkronkan + + Membuat folder… + + Starting transfers… + + Jangan tutup aplikasi. Jika anda menutup, transfer yang belum masuk antrian akan hilang. + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + Batal + + Lanjutkan + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Membatalkan transfer… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 2ebfc0ec38..690574f239 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -309,7 +309,7 @@ Nessuna sincronizzazione configurata - Sincronizza una cartella locale sul tuo dispositivo con una cartella su MEGA. + Sync a folder on your device with a folder on MEGA. Aggiungi una nuova sincronizzazione @@ -560,4 +560,50 @@ I seguenti caratteri non sono ammessi: %1$s Sincronizza + + Sto creando le cartelle… + + Starting transfers… + + Non chiudere l\’app. Se la chiudi, i trasferimenti non ancora completati saranno persi. + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + Annulla + + Continua + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Sto annullando i trasferimenti… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 518af61b8d..9ff8ebac8e 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -293,7 +293,7 @@ 同期が設定されていません - デバイス上のローカルフォルダをMEGA上のフォルダと同期します。 + デバイス上のフォルダをMEGA上のフォルダと同期します。 新しい同期を追加する @@ -544,4 +544,46 @@ 次の文字は許可されていません:%1$s 同期 + + フォルダを作成中… + + 転送を開始しています... + + アプリを閉じないでください。閉じると、まだキューに入れられていない転送は失われます。 + + + 1個のフォルダと%1$d個のファイルが見つかりました。 + + + + %1$d個のフォルダ + + + + %1$d/%2$dフォルダ + + + .debris(ローカルキャッシュ)をクリア + + debrisをクリアしますか? + + 同期されたファイルの以前のバージョンのバックアップはデバイスから完全に削除されます。\n\nローカルデバイスの.debrisフォルダをチェックして、復元する必要があるものがないか確認してください。 + + キャンセル + + 続ける + + .debrisフォルダが正常にクリアされました + + + %1$s個のフォルダと%2$d個のファイルが見つかりました。 + + + タグなし + + 転送をキャンセル中… + + お問い合わせは10文字以上でお願いします + + 問題を10文字以上でご説明ください \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 945ee6b038..9f29673c9c 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -65,7 +65,7 @@ 동기화 위치를 읽을 수 없습니다. 위치에 접근 가능한지 여부와 폴더 위치에 대한 권한이 승인 되었는지 확인하세요. - An unknown error occurred. Contact support@mega.nz. + 알 수 없는 오류가 발생하였습니다. support@mega.nz에 연락하세요. Something went wrong. @@ -293,7 +293,7 @@ 설정된 동기화가 없습니다 - 장치의 로컬 폴더를 MEGA의 폴더와 동기화하세요. + 장치의 폴더를 MEGA의 폴더와 동기화하세요. 새 동기화 추가 @@ -425,7 +425,7 @@ 저장소 - %1s GB + %1sGB 전송 @@ -441,7 +441,7 @@ 최대 30일 (보기 전용) - Up to %1s days + 최대 %1s일 MEGA VPN @@ -479,15 +479,15 @@ iOS 장치에서 - 1. Open the [A]Settings[/A] app. + 1. [A]설정[/A] 앱을 엽니다. 2. 이름을 탭합니다. - 3. Tap [A]Subscriptions[/A]. + 3. [A]구독[/A]을 탭합니다. 4. 당신의 MEGA 구독을 탭합니다. - 5. Tap [A]Cancel subscription[/A]. + 5. [A]구독 취소[/A]를 탭합니다. 컴퓨터 또는 다른 장치에서 구독을 취소하는 자세한 방법은 [A]여기를 탭[/A]하세요. @@ -544,4 +544,46 @@ 다음의 문자는 허용되지 않습니다: %1$s 동기화 + + 폴더 생성 중... + + 전송 시작 중... + + 앱을 닫지 마세요. 만약 닫으면, 아직 대기열에 들어가지 않은 전송이 손실됩니다. + + + 폴더 1개와 파일 %1$d개 발견 + + + + 폴더 %1$d개 + + + + %1$d/%2$d 폴더 + + + .debris (로컬 캐시) 지우기 + + debris를 지울까요? + + 동기화된 파일의 이전 버전의 백업이 장치에서 영구적으로 삭제됩니다.\n\n복구해야 할 것이 있다면 로컬 장치의 .debris 폴더를 확인하세요. + + 취소 + + 계속 + + .debris 폴더를 성공적으로 지웠습니다 + + + %1$s와/과 파일 %2$d개 발견 + + + No tags + + 전송 취소 중... + + 문의사항은 최소 10자 이상이어야 합니다 + + 문제에 대한 설명을 최소 10자 이상을 입력하세요 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 4a4293f40e..821ad3e58a 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -65,7 +65,7 @@ Kan de synchronisatielocatie niet lezen. Controleer of de locatie toegankelijk is en of er machtigingen voor de maplocatie zijn verleend. - An unknown error occurred. Contact support@mega.nz. + Er is een onbekende fout opgetreden. Neem contact op support@mega.nz. Er is iets misgegaan. @@ -301,7 +301,7 @@ Geen synchronisaties ingesteld - Synchroniseer een lokale map op uw apparaat met een map op MEGA. + Synchroniseer een map op uw apparaat met een map op MEGA. Nieuwe synchronisatie toevoegen @@ -552,4 +552,50 @@ De volgende tekens zijn niet toegestaan: %1$s Synchroniseren + + Mappen creëren… + + Overdrachten starten... + + Sluit de applicatie niet. Als u sluit, gaan overdrachten die nog niet in de wachtrij staan ​​verloren. + + + Er is 1 map gevonden en %1$d bestand. + Er is 1 map gevonden en %1$d bestanden. + + + + %1$d map + %1$d mappen + + + + %1$d/%2$d map + %1$d/%2$d mappen + + + .Debris wissen (lokale cache) + + Puin opruimen? + + Back-ups van de vorige versies van uw gesynchroniseerde bestanden worden permanent van uw apparaat verwijderd. \n\nControleer de map .debris op uw lokale apparaat om te zien of u iets nodig hebt om te herstellen. + + Annuleren + + Doorgaan + + .debris map met succes gewist + + + %1$s map en %2$d bestand gevonden + %1$s mappen en %2$d bestanden gevonden + + + No tags + + Overdrachten annuleren... + + Vragen moeten minstens 10 tekens lang zijn + + Beschrijf het probleem met minstens 10 tekens \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index a880bfad06..71a9d828dd 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -317,7 +317,7 @@ Brak ustawień synchronizacji - Synchronizuj katalog lokalny na urządzeniu z katalogiem w MEGA. + Sync a folder on your device with a folder on MEGA. Dodaj nową synchronizację @@ -568,4 +568,54 @@ Następujące znaki są niedozwolone: %1$s Sync + + Tworzenie folderów... + + Rozpoczęcie transferów... + + Nie zamykaj aplikacji. Jeśli zamkniesz, przelewy, które jeszcze nie są w kolejce, zostaną utracone. + + + Znaleziono 1 katalog i %1$d plik. + Znaleziono 1 katalog i %1$d pliki. + Znaleziono 1 katalog i %1$d pliki. + Znaleziono 1 katalog i %1$d pliki. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d katalogów + %1$d/%2$d katalogów + %1$d/%2$d katalogów + %1$d/%2$d katalogów + + + Wyczyścić .debris (lokalna pamięć podręczna) + + Wyczyść pamięć podręczną? + + Kopie zapasowe poprzednich wersji zsynchronizowanych plik zostaną trwale usunięte z urządzenia. \n\nSprawdź katalog .debris na urządzeniu lokalnym, aby sprawdzić, czy musisz cokolwiek przywróć. + + Anuluj + + Kontynuuj + + Katalog .debris pomyślnie wyczyszczony + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Anulowanie transferów... + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 225313b1ed..63627a82ef 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -309,7 +309,7 @@ Não há sincronizações configuradas - Sincronize uma pasta local no seu dispositivo com uma pasta no MEGA. + Sincronize uma pasta no seu dispositivo com uma pasta no MEGA. Adicionar uma nova sincronização @@ -560,4 +560,53 @@ Os seguintes caracteres não são permitidos: %1$s Sincronizar + + Criando pastas… + + Iniciando transferências… + + Não feche o aplicativo. Ao fechar, as transferências que ainda não estiverem na lista serão perdidas. + + + 1 pasta e %1$d arquivo encontrados. + 1 pasta e %1$d de arquivos encontrados. + 1 pasta e %1$d arquivos encontrados. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d pasta + %1$d/%2$d de pastas + %1$d/%2$d pastas + + + Deletar .debris (cache local) + + Deletar debris? + + Os backups das versões anteriores dos seus arquivos sincronizados serão permanentemente excluídos do seu dispositivo. \n\nVerifique a pasta .debris no seu dispositivo local para ver se você precisa restaurar alguma coisa. + + Cancelar + + Continuar + + O conteúdo da pasta .debris foi deletado + + + %1$s pasta e %2$d arquivo encontrados. + %1$s e %2$d de arquivos encontrados. + %1$s e %2$d arquivos encontrados. + + + No tags + + Cancelando transferências… + + As perguntas devem ter pelo menos 10 caracteres + + Descreva o problema usando um mínimo de 10 caracteres \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 00fca90584..1dc8035707 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -3,7 +3,7 @@ No sync error - MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe aparat nu este acceptat + MEGA nu poate sincroniza sau backup pentru acest folder deoarece sistemul de fișiere de pe dispozitiv nu este acceptat Folderul ales nu poate fi sincronizat @@ -61,19 +61,19 @@ Unable to open state cache database - Spațiu de stocare insuficient pe aparat + Spațiu de stocare insuficient pe dispozitiv Nu am putut citi locația de sincronizare. Verificați dacă locația este accesibilă și permisiunile pentru locația folderului sunt acordate. - An unknown error occurred. Contact support@mega.nz. + A apărut o eroare necunoscută. Contactați support@mega.nz. Something went wrong. Folderul nu poate fi sincronizat sau backup-uite, deoarece folderul MEGA se află în Coșul de gunoi - Folderul din aparat nu poate fi localizat chiar acum. Încercați din nou mai târziu. + Folderul din dispozitiv nu poate fi localizat chiar acum. Încercați din nou mai târziu. - Folderul din aparat dvs. nu poate fi localizat + Folderul din dispozitiv dvs. nu poate fi localizat Problemă la sincronizarea sau backup a acestui folder din cauza modificărilor aduse folderului MEGA. Opriți sincronizarea sau backupul și încercați să o configurați din nou în aplicația desktop sau contactați Asistența. @@ -173,7 +173,7 @@ Ștergeți lista de redare? - Șterge + Ștergeți Nicio listă de redare găsită @@ -291,7 +291,7 @@ Upgradează - Încărcarea este întreruptă, deoarece aparatul nu se încarcă + Încărcarea este întreruptă, deoarece dispozitivul nu se încarcă Nu este configurată nicio sincronizare @@ -305,11 +305,11 @@ Essential - Încărcările vor fi întrerupte până când începeți să încărcați aparatul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. + Încărcările vor fi întrerupte până când începeți să încărcați dispozitivul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. Nu este configurată nicio sincronizare - Sincronizați un folder local de pe aparat cu un folder de pe MEGA. + Sync a folder on your device with a folder on MEGA. Adăugați o nouă sincronizare @@ -327,9 +327,9 @@ Și acces la aceste beneficii interesante: - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil\n• Fără reclame + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil\n• Fără reclame - • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe aparatul mobil + • MEGA VPN\n• Apeluri și întâlniri nerestricționate\n• Sincronizați automat folderele de pe dispozitivul mobil Nicio problemă rezolvată @@ -349,7 +349,7 @@ Adăugați contacte, creați o rețea, colaborați și efectuați apeluri vocale și video fără a părăsi MEGA. - Încărcările camerelor sunt o caracteristică esențială pentru orice aparat mobil și vă asigurăm. Creează-ți contul acum. + Încărcările camerelor sunt o caracteristică esențială pentru orice dispozitiv mobil și vă asigurăm. Creează-ți contul acum. Întâlnire video criptată cu zero cunoștințe. @@ -377,7 +377,7 @@ Upgradează la Pro - Abonamentele noastre Pro dezlănțuie puterea de sincronizare a aparatului dvs. mobil cu MEGA. + Abonamentele noastre Pro dezlănțuie puterea de sincronizare a dispozitivului dvs. mobil cu MEGA. Upgradează @@ -389,9 +389,9 @@ Bine, am înțeles - Acest aparat nu are o aplicație care să selecteze foldere + Acest dispozitiv nu are o aplicație care să selecteze foldere - • Sincronizați automat folderele de pe aparatul mobil + • Sincronizați automat folderele de pe dispozitivul mobil Sincronizările dvs. au fost întrerupte. Sincronizarea este o funcție a abonamentelor Pro. @@ -493,7 +493,7 @@ V-ați abonat la MEGA cu Apple. Pentru a vă anula abonamentul, trebuie să: - Pe un aparat iOS + Pe un dispozitiv iOS 1. Deschideți aplicația [A]Setări[/A]. @@ -505,7 +505,7 @@ 5. Atingeți [A]Anulați abonamentul[/A]. - [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt aparat. + [A]Atingeți aici[/A] pentru instrucțiuni detaliate despre cum să vă anulați abonamentul pe un calculator sau alt dispozitiv. Trebuie să vă anulați abonamentul folosind un browser web @@ -531,7 +531,7 @@ 6. Dați clic pe [A]Reactivați abonamentul[/A]. - Pe un aparat mobil + Pe un dispozitiv mobil 1. Accesați [A]www.mega.nz[/A] în browserul web. @@ -560,4 +560,52 @@ Următoarele caractere nu sunt permise: %1$s Sincronizează + + Se creează folderele… + + Începerea transferurilor… + + Nu închide aplicația. Dacă o închizi, transferurile care nu sunt încă în coadă vor fi pierdute. + + + Au fost găsite 1 folder și %1$d fișier. + Au fost găsite 1 folder și %1$d fișiere. + Au fost găsite 1 folder și %1$d de fișiere. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d foldere + %1$d/%2$d de foldere + + + Ștergeți .debris (cache local) + + Ștergeți resturile? + + Backup-uri ale versiunilor anterioare ale fișierelor sincronizate vor fi șterse definitiv de pe dispozitiv.\n\nVerificați folderul .debris în dispozitivul local pentru a vedea dacă trebuie să restaurați ceva. + + Anulați + + Continuați + + Folderul .debris a fost șters + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Se anulează transferurile… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 91ef1207b2..e639df502b 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -317,7 +317,7 @@ Синхронизация не настроена - Синхронизируйте локальную папку на устройстве с папкой в MEGA. + Синхронизируйте папку на устройстве с папкой в MEGA. Добавить синхронизацию @@ -568,4 +568,58 @@ Следующие символы не допускаются: %1$s Синхронизация + + Создание папок… + + Запуск передач… + + Не закрывайте приложение. Если закрыть, ещё не поставленные в очередь передачи будут потеряны. + + + Найдена 1 папка и %1$d файл. + Найдена 1 папка и %1$d файла. + Найдена 1 папка и %1$d файлов. + Найдена 1 папка и %1$d файла. + + + + %1$d папка + %1$d папки + %1$d папок + %1$d папки + + + + %1$d папка из %2$d + %1$d папки из %2$d + %1$d папок из %2$d + %1$d папки из %2$d + + + Очистить .debris (локальный кеш) + + Очистить .debris? + + Резервные копии предыдущих версий синхронизируемых файлов будут безвозвратно удалены с вашего устройства. \n\nПроверьте папку .debris на локальном устройстве, чтобы узнать, нужно ли что-то восстановить. + + Отмена + + Продолжить + + Папка .debris успешно очищена + + + Найдены %1$s и %2$d файл. + Найдены %1$s и %2$d файла. + Найдены %1$s и %2$d файлов. + Найдены %1$s и %2$d файла. + + + No tags + + Отмена передач… + + Сообщение должно содержать не менее 10 символов + + Опишите проблему, используя не менее 10 символов \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 700d1eb76f..33dc257329 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -65,7 +65,7 @@ ไม่สามารถอ่านตำแหน่งที่ตั้งการซิงค์ได้ กรุณาตรวจสอบว่าสามารถเข้าถึงได้และได้รับอนุญาตให้ใช้งานโฟลเดอร์ตามตำแหน่งที่ตั้งนี้หรือไม่ - An unknown error occurred. Contact support@mega.nz. + เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ ติดต่อ support@mega.nz Something went wrong. @@ -293,7 +293,7 @@ ยังไม่ได้ตั้งค่าการซิงค์ - ซิงค์โฟลเดอร์บนอุปกรณ์ของคุณกับโฟลเดอร์บน MEGA + Sync a folder on your device with a folder on MEGA. เพิ่มการซิงค์ใหม่ @@ -441,7 +441,7 @@ สูงสุด 30 วัน (ดูอย่างเดียว) - Up to %1s days + นานถึง %1s วัน MEGA VPN @@ -471,59 +471,59 @@ ยกเลิกการสมัครใช้งาน - Reactivate subscription + เปิดใช้งานการสมัครใช้งานอีกครั้ง - Your subscription is not managed by Google + การสมัครใช้งานของคุณไม่ได้จัดการโดย Google - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + เนื่องจากคุณสมัครใช้งาน MEGA ผ่าน Apple หากต้องการยกเลิกการสมัครใช้งาน คุณต้อง: - On an iOS Device + บนอุปกรณ์ iOS - 1. Open the [A]Settings[/A] app. + 1. เปิดแอป[A]การตั้งค่า[/A] - 2. Tap on your name. + 2. แตะที่ชื่อของคุณ - 3. Tap [A]Subscriptions[/A]. + 3. แตะ[A]การสมัครใช้งาน[/A] - 4. Tap your MEGA subscription. + 4. แตะการสมัครใช้งาน MEGA ของคุณ - 5. Tap [A]Cancel subscription[/A]. + 5. แตะ[A]ยกเลิกการสมัครใช้งาน[/A] - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]แตะที่นี่[/A]เพื่อดูวิธีการยกเลิกการสมัครใช้งานแบบละเอียดผ่านคอมพิวเตอร์หรืออุปกรณ์อื่น ๆ คุณต้องใช้เว็บเบราว์เซอร์เพื่อยกเลิกการสมัครใช้งานของคุณ - You need to reactivate your subscription using a web browser + คุณต้องใช้เว็บเบราว์เซอร์เพื่อเปิดใช้งานการสมัครใช้งานของคุณ - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + เนื่องจากคุณสมัครใช้งาน MEGA ในเว็บเบราว์เซอร์ หากต้องการเปิดใช้งานการสมัครใช้งาน คุณต้อง: เนื่องจากคุณสมัครใช้งาน MEGA ในเว็บเบราว์เซอร์ หากต้องการยกเลิกการสมัครใช้งาน คุณต้อง: บนคอมพิวเตอร์ - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. ไปที่ [A]www.mega.nz[/A] ในเว็บเบราว์เซอร์ของคุณ 2. เข้าสู่ระบบบัญชี MEGA ของคุณ - 3. Click the main menu. + 3. คลิกที่เมนูหลัก - 4. Click [A]Settings.[/A] + 4. คลิก[A]การตั้งค่า[/A] - 5. Click [A]Plan[/A]. + 5. คลิก[A]แผน[/A] - 6. Click [A]Cancel subscription[/A]. + 6. คลิก[A]ยกเลิกการสมัครใช้งาน[/A] - 6. Click [A]Reactivate subscription[/A]. + 6. คลิก[A]เปิดใช้งานการสมัครใช้งานอีกครั้ง[/A] บนอุปกรณ์มือถือ - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. ไปที่ [A]www.mega.nz[/A] ในเว็บเบราว์เซอร์ของคุณ 2. เข้าสู่ระบบบัญชี MEGA ของคุณ 3. แตะที่รูปประจำตัวของคุณ - 4. Tap [A]Cancel subscription[/A]. + 4. แตะ[A]ยกเลิกการสมัครใช้งาน[/A] ไม่มีการเชื่อมต่ออินเทอร์เน็ต @@ -539,9 +539,53 @@ กรอกชื่อโฟลเดอร์ - มีโฟลเดอร์ชื่อเดียวกันอยู่แล้ว + มีโฟลเดอร์ชื่อนี้อยู่แล้ว ไม่อนุญาตให้ใช้อักขระต่อไปนี้: %1$s ซิงค์ + + กำลังสร้างโฟลเดอร์… + + กำลังเริ่มถ่ายโอน… + + อย่าปิดแอป หากคุณปิด คิวการถ่ายโอนที่กำลังดำเนินการอยู่อาจสูญหายได้ + + + พบโฟลเดอร์ 1 รายการและไฟล์อีก %1$d รายการ + + + + %1$d folder + %1$d folders + + + + โฟลเดอร์ %1$d จาก %2$d รายการ + + + ล้างข้อมูล .debris (แคชในเครื่อง) + + ล้างไฟล์ขยะหรือไม่ + + ไฟล์สำรองข้อมูลที่คุณซิงค์ไว้ก่อนหน้านี้จะถูกลบออกจากอุปกรณ์ของคุณอย่างถาวร\n\nตรวจสอบโฟลเดอร์ .debris ในอุปกรณ์ของคุณ เพื่อดูว่ามีไฟล์ใดที่คุณต้องการกู้คืนหรือไม่ + + ยกเลิก + + ดำเนินการต่อ + + ลบโฟลเดอร์ .debris เรียบร้อยแล้ว + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + กำลังยกเลิกการถ่ายโอน… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index f12c5a6f3f..fa19f55f09 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -293,7 +293,7 @@ Không có đồng bộ nào đã lập - Đồng bộ một thư mục cục bộ trong thiết bị của bạn với một thư mục trên MEGA. + Sync a folder on your device with a folder on MEGA. Thêm đồng bộ mới @@ -441,7 +441,7 @@ Lên đến 30 ngày (chỉ được xem) - Up to %1s days + Lên đến %1s ngày MEGA VPN @@ -479,15 +479,15 @@ Trên thiết bị iOS - 1. Open the [A]Settings[/A] app. + 1. Mở app [A]Cài đặt[/A]. 2. Chạm vào tên của bạn. - 3. Tap [A]Subscriptions[/A]. + 3. Chạm vào [A]Gói thuê bao[/A]. 4. Chạm vào gói đăng ký MEGA. - 5. Tap [A]Cancel subscription[/A]. + 5. Chạm vào [A]Hủy đăng ký[/A]. [A]Chạm vào đây[/A] để được hướng dẫn chi tiết về cách hủy gói đăng ký của bạn trên máy tính hoặc loại thiết bị khác. @@ -544,4 +544,48 @@ Các ký tự này không được phép sử dụng: %1$s Đồng bộ + + Đang tạo các thư mục… + + Đang bắt đầu truyền tải… + + Xin đừng đóng ứng dụng. Nếu bạn đóng, các phiên truyền tải chưa được xếp hàng sẽ bị mất. + + + Tìm thấy 1 thư mục và %1$d tệp tin. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d thư mục + + + Dọn .debris (nhớ tạm cục bộ) + + Xóa rác vụn? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + Hủy + + Tiếp tục + + Thư mục chứa .debris đã được dọn sạch + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Đang hủy các phiên truyền tải… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 91e386c317..a6e606a9d9 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -293,7 +293,7 @@ 未设置同步 - 将设备上的本地文件夹与MEGA上的文件夹同步。 + Sync a folder on your device with a folder on MEGA. 添加新同步 @@ -544,4 +544,50 @@ 不允许使用这些字符:%1$s 同步 + + 正在创建文件夹... + + Starting transfers… + + 请不要关闭应用程序。关闭后,未在队列中的传输将丢失。 + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + 取消 + + 继续 + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + 正在取消传输... + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index bd3248c242..80f7d060cc 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -65,7 +65,7 @@ 無法讀取同步位置。檢查該位置是否可用,而且是否已授予該資料夾位置的權限。 - An unknown error occurred. Contact support@mega.nz. + 發生未知錯誤。請聯繫support@mega.nz。 Something went wrong. @@ -293,7 +293,7 @@ 未設定同步 - 將裝置上的本地資料夾與MEGA上的資料夾同步。 + 將裝置上的資料夾與MEGA上的資料夾同步。 加入新的同步 @@ -544,4 +544,46 @@ 不允許使用以下字元:%1$s 同步 + + 正在建立資料夾⋯ + + 開始傳輸⋯ + + 請不要關閉應用程式。如果關閉,未在佇列中的傳輸將遺失。 + + + 找到1個資料夾和%1$d個檔案。 + + + + %1$d個資料夾 + + + + %1$d/%2$d個資料夾 + + + 清除.debris(本地快取) + + 要清除同步碎片嗎? + + 同步檔案的先前版本的備份將從您的裝置中永久刪除。\n\n檢查本地裝置中的.debris資料夾,看看是否需要恢復任何內容。 + + 取消 + + 繼續 + + .Debris資料夾已成功清除 + + + 找到%1$s個和%2$d檔案。 + + + No tags + + 正在取消傳輸⋯ + + 查詢內容必須至少10個字元(5個中文字) + + 問題描述至少10個字元(5個中文字) \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index fb1378cca9..328bbcc88c 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -1,4 +1,4 @@ - + No sync error @@ -301,7 +301,7 @@ No syncs set up - Sync a local folder on your device with a folder on MEGA. + Sync a folder on your device with a folder on MEGA. Add new sync @@ -552,4 +552,50 @@ The following characters are not allowed: %1$s Sync + + Creating folders… + + Starting transfers… + + Don’t close the app. If you close, transfers not yet queued will be lost. + + + Found 1 folder and %1$d file. + Found 1 folder and %1$d files. + + + + %1$d folder + %1$d folders + + + + %1$d/%2$d folder + %1$d/%2$d folders + + + Clear .debris (local cache) + + Clear debris? + + Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + + Cancel + + Continue + + .debris folder successfully cleared + + + Found %1$s folder and %2$d file. + Found %1$s and %2$d files. + + + No tags + + Cancelling transfers… + + Enquiries must be at least 10 characters + + Describe the issue with at least 10 characters \ No newline at end of file From 201fd201bdafa543fef3d40becdfcfbe988f3892 Mon Sep 17 00:00:00 2001 From: Amr Date: Thu, 8 Aug 2024 12:53:01 +0800 Subject: [PATCH 200/261] Update SDKs. SDK(v7.8.0-rc.1), Chat(v6.0.0-rc.1) --- sdk/src/main/jni/mega/sdk | 2 +- sdk/src/main/jni/megachat/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index e0b68f94b5..60ecdf0d64 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit e0b68f94b554c88c0108613c2682de831c8c7066 +Subproject commit 60ecdf0d646645a35a515a6659456f701d635c02 diff --git a/sdk/src/main/jni/megachat/sdk b/sdk/src/main/jni/megachat/sdk index f502884bda..671e5429a8 160000 --- a/sdk/src/main/jni/megachat/sdk +++ b/sdk/src/main/jni/megachat/sdk @@ -1 +1 @@ -Subproject commit f502884bda2fefa15309aac3533d94cb217d8862 +Subproject commit 671e5429a87b4a864051c732470827a591398ef5 From 3d994f8d55e1c84180ccadab6fb994b2dd0fbaa3 Mon Sep 17 00:00:00 2001 From: Amr Date: Thu, 8 Aug 2024 17:51:54 +0800 Subject: [PATCH 201/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index ebc4418331..fdac4f4a95 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ shimmerlayout = 'io.supercharge:shimmerlayout:2.1.0' simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorage" } vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240731.123949" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 19e3dd67206f282fc0cd37d7d0777e8aa4ced571 Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Fri, 9 Aug 2024 13:25:18 +1200 Subject: [PATCH 202/261] Fix: Fix for wrong App Version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 99bc3e8d02..fe2759d487 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,7 +78,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "“14.1”" +extra["appVersion"] = "14.1" // Sdk and tools extra["compileSdkVersion"] = 35 From 95b2d05756b4dd73f55af88a3ad1c34b47ac6c2c Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Fri, 9 Aug 2024 11:53:56 +0530 Subject: [PATCH 203/261] Update Strings --- app/src/main/res/values-nl/strings.xml | 2 +- shared/resources/src/main/res/values-ar/strings_shared.xml | 2 +- shared/resources/src/main/res/values-de/strings_shared.xml | 4 ++-- shared/resources/src/main/res/values-es/strings_shared.xml | 2 +- shared/resources/src/main/res/values-fr/strings_shared.xml | 5 ++--- shared/resources/src/main/res/values-in/strings_shared.xml | 2 +- shared/resources/src/main/res/values-it/strings_shared.xml | 2 +- shared/resources/src/main/res/values-ko/strings_shared.xml | 3 ++- shared/resources/src/main/res/values-nl/strings_shared.xml | 6 +++--- shared/resources/src/main/res/values-pl/strings_shared.xml | 2 +- shared/resources/src/main/res/values-pt/strings_shared.xml | 5 ++--- shared/resources/src/main/res/values-ro/strings_shared.xml | 2 +- shared/resources/src/main/res/values-th/strings_shared.xml | 2 +- shared/resources/src/main/res/values-vi/strings_shared.xml | 2 +- .../resources/src/main/res/values-zh-rCN/strings_shared.xml | 2 +- .../resources/src/main/res/values-zh-rTW/strings_shared.xml | 5 +++-- 16 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 33e9fa2407..2575851a57 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -5182,7 +5182,7 @@ Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 1 maand automatisch verlengd. Uw Google   Play-account wordt binnen 24 uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24 uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacy- en Gegevensbeleid[/C]. - You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. + Er worden onmiddellijk kosten in rekening gebracht en uw abonnement wordt na 12   maanden automatisch verlengd. Uw Google   Play-account wordt binnen 24   uur na het einde van elke factureringsperiode in rekening gebracht voor verlenging. Om uw abonnement op te zeggen, moet u de automatische verlenging van uw MEGA   Pro-abonnement ten minste 24   uur voor het einde van uw factureringsperiode uitschakelen via Abonnementen in [A]Google   Play[/A].\nDoor uw account te upgraden, gaat u akkoord met MEGA\’s [B]Algemene Voorwaarden[/B] en [C]Privacy- en Gegevensbeleid[/C]. Zakelijke account gedeactiveerd diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 10b2373aee..9f021fc11f 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -619,7 +619,7 @@ .debris folder successfully cleared - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 8176a54a22..f9177a56bb 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -587,8 +587,8 @@ Ordner .debris erfolgreich geleert - %1$s Ordner und %2$d Datei gefunden. - %1$s und %2$d Dateien gefunden. + Found %1$s and %2$d file. + Found %1$s and %2$d files. No tags diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index e2099c10ea..7db281283e 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -595,7 +595,7 @@ .debris folder successfully cleared - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index fa06fb19f9..e8233bb6d4 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -597,9 +597,8 @@ Le dossier .debris a été vidé - %1$s et %2$d fichier ont été trouvés - %1$s et %2$d de fichiers ont été trouvés - %1$s et %2$d fichiers ont été trouvés + Found %1$s and %2$d file. + Found %1$s and %2$d files. No tags diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index b4661f86c0..2e2b26860a 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -582,7 +582,7 @@ .debris folder successfully cleared - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index 690574f239..fba2d075b6 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -595,7 +595,7 @@ .debris folder successfully cleared - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 9f29673c9c..db83b707d9 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -576,7 +576,8 @@ .debris 폴더를 성공적으로 지웠습니다 - %1$s와/과 파일 %2$d개 발견 + Found %1$s and %2$d file. + Found %1$s and %2$d files. No tags diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 821ad3e58a..bde745f6a5 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -587,11 +587,11 @@ .debris map met succes gewist - %1$s map en %2$d bestand gevonden - %1$s mappen en %2$d bestanden gevonden + Found %1$s and %2$d file. + Found %1$s and %2$d files. - No tags + Geen labels Overdrachten annuleren... diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index 71a9d828dd..4b0e0bed8d 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -607,7 +607,7 @@ Katalog .debris pomyślnie wyczyszczony - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 63627a82ef..b3e1ade8c9 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -597,9 +597,8 @@ O conteúdo da pasta .debris foi deletado - %1$s pasta e %2$d arquivo encontrados. - %1$s e %2$d de arquivos encontrados. - %1$s e %2$d arquivos encontrados. + Found %1$s and %2$d file. + Found %1$s and %2$d files. No tags diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 1dc8035707..6ee5de120c 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -597,7 +597,7 @@ Folderul .debris a fost șters - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 33dc257329..487ed583b1 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -577,7 +577,7 @@ ลบโฟลเดอร์ .debris เรียบร้อยแล้ว - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index fa19f55f09..b1588b8d04 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -577,7 +577,7 @@ Thư mục chứa .debris đã được dọn sạch - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index a6e606a9d9..5c2b549e08 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -579,7 +579,7 @@ .debris folder successfully cleared - Found %1$s folder and %2$d file. + Found %1$s and %2$d file. Found %1$s and %2$d files. diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 80f7d060cc..c1156f5174 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -576,10 +576,11 @@ .Debris資料夾已成功清除 - 找到%1$s個和%2$d檔案。 + Found %1$s and %2$d file. + Found %1$s and %2$d files. - No tags + 沒有標籤 正在取消傳輸⋯ From 6f1bb71ef0b125819d9feeb0cb967a96cb70f602 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Fri, 9 Aug 2024 12:14:14 +0530 Subject: [PATCH 204/261] Update String changes missed in last cherry pick for version v14.0 (242190824) --- app/src/main/res/values/strings.xml | 10 +++++----- .../src/main/res/values-pt/strings_shared.xml | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index efb89c246a..363dda3a1e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -633,7 +633,7 @@ About - Privacy Policy + Privacy and Data Policy Terms of Service @@ -5182,13 +5182,13 @@ [A]Your free plan has a 60-minute limit on meetings. Pro users have unlimited calls and up to 1000 participants.[/A] [B]Upgrade now.[/B] - You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 1 month for %2$s per month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + You will be charged %1$s immediately and your subscription will automatically renew after 12 months for %2$s per year. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + You will be charged immediately and your subscription will automatically renew after 1 month. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. - You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy Policy[/C]. + You will be charged immediately and your subscription will automatically renew after 12 months. Your Google Play account will be charged for renewal within 24 hours of the end of each billing period. To cancel your subscription, you must disable automatic renewal of your MEGA Pro subscription at least 24 hours before the end of your billing period via Subscriptions in [A]Google Play[/A].\nBy upgrading your account, you agree to MEGA’s [B]Terms of Service[/B] and [C]Privacy and Data Policy[/C]. Business account deactivated diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index b3e1ade8c9..443254bf1c 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -574,8 +574,9 @@ - %1$d folder - %1$d folders + %1$d pasta + %1$d de pastas + %1$d pastas @@ -601,7 +602,7 @@ Found %1$s and %2$d files. - No tags + Não há etiquetas Cancelando transferências… From 085da00af7cbf5fffe7cf6a3a94e73d14d80b45d Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Fri, 9 Aug 2024 21:08:33 +1200 Subject: [PATCH 205/261] Update SDK Version: Release v14.1 - SDK new version v7.8.0-rc.2 --- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fe2759d487..301a35b2ba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,7 +87,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "35.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240808.053359-rel" +extra["megaSdkVersion"] = "20240809.052113-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index 60ecdf0d64..bf06f9ff9a 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit 60ecdf0d646645a35a515a6659456f701d635c02 +Subproject commit bf06f9ff9a2eef491e13ce9f901d5b1c8e15b91e From 9aed8a0e1ed2acf6afed4dc3557990e2accf35e6 Mon Sep 17 00:00:00 2001 From: Bhavna Thacker Date: Fri, 9 Aug 2024 21:41:24 +1200 Subject: [PATCH 206/261] Task/pre release/v14.0 --- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5bb6e787ac..91c137c909 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,7 +87,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "35.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240724.055557-rel" +extra["megaSdkVersion"] = "20240809.085416-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index e0b68f94b5..9766be4a7a 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit e0b68f94b554c88c0108613c2682de831c8c7066 +Subproject commit 9766be4a7a9ccc9214c7d88f1f43e6d2799d0df9 From d78c8c8aff134b41fbfd8dedbffb9f90cdfe0da0 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Tue, 13 Aug 2024 10:05:21 +0800 Subject: [PATCH 207/261] CC-7874 AND - The play queue becomes unavailable when a media file is opened from Offline --- .../java/mega/privacy/android/app/nav/MegaNavigatorImpl.kt | 7 +++++++ .../offline/action/HandleOfflineNodeActions.kt | 2 +- .../java/mega/privacy/android/navigation/AppNavigator.kt | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/nav/MegaNavigatorImpl.kt b/app/src/main/java/mega/privacy/android/app/nav/MegaNavigatorImpl.kt index 2e2eb00419..9192c651e3 100644 --- a/app/src/main/java/mega/privacy/android/app/nav/MegaNavigatorImpl.kt +++ b/app/src/main/java/mega/privacy/android/app/nav/MegaNavigatorImpl.kt @@ -38,6 +38,7 @@ import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_MEDIA_QUEUE_TIT import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_MSG_ID import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_OFFLINE_PATH_DIRECTORY import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_ORDER_GET_CHILDREN +import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_PARENT_ID import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_PARENT_NODE_HANDLE import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_PATH import mega.privacy.android.app.utils.Constants.INTENT_EXTRA_KEY_PLACEHOLDER @@ -235,6 +236,7 @@ internal class MegaNavigatorImpl @Inject constructor( isMediaQueueAvailable: Boolean, viewType: Int? = null, path: String? = null, + offlineParentId: Int? = null, offlineParent: String? = null, searchedItems: List? = null, mediaQueueTitle: String? = null, @@ -256,6 +258,9 @@ internal class MegaNavigatorImpl @Inject constructor( path?.let { putExtra(INTENT_EXTRA_KEY_PATH, path) } + offlineParentId?.let { + putExtra(INTENT_EXTRA_KEY_PARENT_ID, it) + } offlineParent?.let { putExtra(INTENT_EXTRA_KEY_OFFLINE_PATH_DIRECTORY, offlineParent) } @@ -298,6 +303,7 @@ internal class MegaNavigatorImpl @Inject constructor( handle: Long, viewType: Int?, parentId: Long, + offlineParentId: Int?, fileTypeInfo: FileTypeInfo?, sortOrder: SortOrder, isFolderLink: Boolean, @@ -318,6 +324,7 @@ internal class MegaNavigatorImpl @Inject constructor( isFolderLink = isFolderLink, isMediaQueueAvailable = isMediaQueueAvailable, path = localFile.absolutePath, + offlineParentId = offlineParentId, offlineParent = localFile.parent, searchedItems = searchedItems ) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/offline/action/HandleOfflineNodeActions.kt b/app/src/main/java/mega/privacy/android/app/presentation/offline/action/HandleOfflineNodeActions.kt index 0ae0cf81df..90282474bf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/offline/action/HandleOfflineNodeActions.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/offline/action/HandleOfflineNodeActions.kt @@ -321,7 +321,7 @@ private suspend fun openVideoOrAudioFile( fileTypeInfo = content.fileTypeInfo, viewType = Constants.OFFLINE_ADAPTER, handle = content.nodeId.longValue, - parentId = content.parentId.toLong(), + offlineParentId = content.parentId, sortOrder = sortOrder, ) }.onFailure { diff --git a/navigation/src/main/java/mega/privacy/android/navigation/AppNavigator.kt b/navigation/src/main/java/mega/privacy/android/navigation/AppNavigator.kt index e0c3639693..249cc891ca 100644 --- a/navigation/src/main/java/mega/privacy/android/navigation/AppNavigator.kt +++ b/navigation/src/main/java/mega/privacy/android/navigation/AppNavigator.kt @@ -158,6 +158,7 @@ interface AppNavigator { * @param viewType the adapter type of the view * @param handle the handle of the node * @param parentId the parent id of the node + * @param offlineParentId the parent id of the offline * @param sortOrder SortOrder * @param isFolderLink whether the file is a folder link * @param isMediaQueueAvailable whether the media queue is available @@ -169,6 +170,7 @@ interface AppNavigator { handle: Long, viewType: Int? = null, parentId: Long = -1L, + offlineParentId: Int? = null, fileTypeInfo: FileTypeInfo? = null, sortOrder: SortOrder = SortOrder.ORDER_NONE, isFolderLink: Boolean = false, From 769b37f62160d8d98d7301aa015dc055921f220d Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 13 Aug 2024 13:13:54 +0700 Subject: [PATCH 208/261] T17260907: The bottom sheet disappears automatically. (cherry picked from commit 82a1d7291859c1be4162b9c73520902b24468bc0) --- .../photos/mediadiscovery/MediaDiscoveryFragment.kt | 2 ++ .../photos/mediadiscovery/view/MediaDiscoveryView.kt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt index 8843171958..64fb3f6792 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/MediaDiscoveryFragment.kt @@ -21,6 +21,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.core.os.bundleOf import androidx.core.view.MenuProvider import androidx.fragment.app.Fragment @@ -89,6 +90,7 @@ class MediaDiscoveryFragment : Fragment() { savedInstanceState: Bundle?, ): View { return ComposeView(requireContext()).apply { + setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { val mode by getThemeMode() .collectAsStateWithLifecycle(initialValue = ThemeMode.System) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt index 2f8fef79bb..6bc146a3f4 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/photos/mediadiscovery/view/MediaDiscoveryView.kt @@ -109,7 +109,6 @@ fun MediaDiscoveryView( val coroutineScope = rememberCoroutineScope() val modalSheetState = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, - confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, skipHalfExpanded = true, ) From ac9f4f90f35cc61c62b10b951197d54ad531f3b8 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Tue, 13 Aug 2024 15:00:11 +1200 Subject: [PATCH 209/261] AND-19269 Remove old release 487 from Google Play --- jenkinsfile/android_release.groovy | 2 +- jenkinsfile/android_release_internal.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jenkinsfile/android_release.groovy b/jenkinsfile/android_release.groovy index aaaf1c0df5..8031f55759 100644 --- a/jenkinsfile/android_release.groovy +++ b/jenkinsfile/android_release.groovy @@ -460,7 +460,7 @@ pipeline { filesPattern: 'archive/*-gms-release.aab', trackName: 'alpha', rolloutPercentage: '0', - additionalVersionCodes: '487,233140859', + additionalVersionCodes: '233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", recentChangeList: common.getRecentChangeList(RELEASE_NOTES_CONTENT), releaseName: common.readAppVersion1() diff --git a/jenkinsfile/android_release_internal.groovy b/jenkinsfile/android_release_internal.groovy index b932ce00ca..0cf64f4fcf 100644 --- a/jenkinsfile/android_release_internal.groovy +++ b/jenkinsfile/android_release_internal.groovy @@ -340,7 +340,7 @@ pipeline { filesPattern: 'archive/*-gms-release.aab', trackName: 'internal', rolloutPercentage: '100', - additionalVersionCodes: '487', + additionalVersionCodes: '233140859', nativeDebugSymbolFilesPattern: "archive/${NATIVE_SYMBOLS_FILE}", recentChangeList: common.getRecentChangeList(release_notes), releaseName: common.readAppVersion1() From b29e408e737a9c71a2e093d41b2bf535633bf539 Mon Sep 17 00:00:00 2001 From: Yenel Date: Tue, 13 Aug 2024 13:28:12 +0200 Subject: [PATCH 210/261] Hotfix: T17288279 The file context menu cannot be clicked when opening file link --- .../android/app/presentation/folderlink/view/FolderLinkView.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt index df821753eb..53e5147369 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/folderlink/view/FolderLinkView.kt @@ -152,7 +152,6 @@ internal fun FolderLinkView( val coroutineScope = rememberCoroutineScope() val modalSheetState = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, - confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, skipHalfExpanded = true, ) From 06df1d0e5affd08944b1902d7467501584ca3cb8 Mon Sep 17 00:00:00 2001 From: sq Date: Wed, 14 Aug 2024 11:05:04 +0800 Subject: [PATCH 211/261] SAO-1988 Fix Password Share Link --- .../java/mega/privacy/android/app/getLink/GetLinkActivity.kt | 1 + .../java/mega/privacy/android/app/getLink/GetLinkFragment.kt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/getLink/GetLinkActivity.kt b/app/src/main/java/mega/privacy/android/app/getLink/GetLinkActivity.kt index 49d7d0e446..0a0ac2e3b1 100644 --- a/app/src/main/java/mega/privacy/android/app/getLink/GetLinkActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/getLink/GetLinkActivity.kt @@ -106,6 +106,7 @@ class GetLinkActivity : PasscodeActivity(), SnackbarShower { if (handle != INVALID_HANDLE) { viewType = TYPE_NODE + viewModelNode.initNode(handle) } else if (handleList != null) { viewType = TYPE_LIST } diff --git a/app/src/main/java/mega/privacy/android/app/getLink/GetLinkFragment.kt b/app/src/main/java/mega/privacy/android/app/getLink/GetLinkFragment.kt index bbe353c4a6..43fc4341f1 100644 --- a/app/src/main/java/mega/privacy/android/app/getLink/GetLinkFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/getLink/GetLinkFragment.kt @@ -119,8 +119,6 @@ class GetLinkFragment : Fragment(), DatePickerDialog.OnDateSetListener, Scrollab if (getFeatureFlagValueUseCase(AppFeatures.HiddenNodes)) { checkSensitiveItems() } else { - initNode() - setupView() setupObservers() } From 1dd99319e67eed33bf535f96c8fb976dcc71c6c3 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 12 Aug 2024 08:29:04 +0700 Subject: [PATCH 212/261] AND-19191/T17263477: Snackbar overlap when showing on manage history screen (cherry picked from commit 59b0ef768178979e816626994ee5a03b15ee87d5) --- .../view/screen/ManageChatHistoryScreen.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/view/screen/ManageChatHistoryScreen.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/view/screen/ManageChatHistoryScreen.kt index 1b72465d21..076036ae8f 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/view/screen/ManageChatHistoryScreen.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/managechathistory/view/screen/ManageChatHistoryScreen.kt @@ -18,8 +18,8 @@ import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold -import androidx.compose.material.SnackbarHost import androidx.compose.material.SnackbarHostState +import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -102,12 +102,8 @@ internal fun ManageChatHistoryRoute( uiState = uiState, onNavigateUp = onNavigateUp, onConfirmClearChatClick = viewModel::clearChatHistory, - onSetChatRetentionTime = viewModel::setChatRetentionTime - ) - - SnackbarHost( - modifier = Modifier.align(Alignment.BottomCenter), - hostState = snackBarHostState + onSetChatRetentionTime = viewModel::setChatRetentionTime, + snackbarHostState = snackBarHostState ) } } @@ -119,6 +115,7 @@ internal fun ManageChatHistoryScreen( onConfirmClearChatClick: (chatRoomId: Long) -> Unit, onSetChatRetentionTime: (period: Long) -> Unit, modifier: Modifier = Modifier, + snackbarHostState: SnackbarHostState = remember { SnackbarHostState() }, ) { var shouldShowCustomTimePicker by rememberSaveable { mutableStateOf(false) } var shouldShowClearChatConfirmation by rememberSaveable { mutableStateOf(false) } @@ -127,6 +124,7 @@ internal fun ManageChatHistoryScreen( Scaffold( modifier = modifier, + scaffoldState = rememberScaffoldState(snackbarHostState = snackbarHostState), topBar = { MegaAppBar( appBarType = AppBarType.BACK_NAVIGATION, From 6b068f5c7bbc4f5cb49e04648b2eca2f7001a41b Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Wed, 14 Aug 2024 18:13:00 +0600 Subject: [PATCH 213/261] MEET-4301: Fix auto mic on when fragment resumed --- .../privacy/android/app/meeting/fragments/InMeetingFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt index 3ecaf3db5b..5e6a6c693c 100644 --- a/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/meeting/fragments/InMeetingFragment.kt @@ -32,6 +32,7 @@ import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Lifecycle import androidx.lifecycle.Observer import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.setViewTreeViewModelStoreOwner @@ -1040,7 +1041,7 @@ class InMeetingFragment : MeetingBaseFragment(), BottomFloatingPanelListener, Sn } viewLifecycleOwner.collectFlow(inMeetingViewModel.state.map { it.call?.callId } - .distinctUntilChanged()) { callId -> + .distinctUntilChanged(), minActiveState = Lifecycle.State.CREATED) { callId -> callId?.run { if (args.action == MEETING_ACTION_IN) { if (arguments?.getBoolean( From 25520d3a600d7819a71b1c1fd47d49719b76ce2d Mon Sep 17 00:00:00 2001 From: Amr Mohsen Date: Thu, 15 Aug 2024 18:17:30 +1200 Subject: [PATCH 214/261] Update SDK Version: Release v14.1 - SDK new version v7.8.0-rc.3 --- build.gradle.kts | 2 +- sdk/src/main/jni/mega/sdk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 301a35b2ba..8ddc2045f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,7 +87,7 @@ extra["targetSdkVersion"] = 34 extra["buildTools"] = "35.0.0" // Prebuilt MEGA SDK version -extra["megaSdkVersion"] = "20240809.052113-rel" +extra["megaSdkVersion"] = "20240815.052610-rel" //JDK and Java Version extra["jdk"] = "17" diff --git a/sdk/src/main/jni/mega/sdk b/sdk/src/main/jni/mega/sdk index bf06f9ff9a..da53a1319d 160000 --- a/sdk/src/main/jni/mega/sdk +++ b/sdk/src/main/jni/mega/sdk @@ -1 +1 @@ -Subproject commit bf06f9ff9a2eef491e13ce9f901d5b1c8e15b91e +Subproject commit da53a1319d911781dd3db3bab5beeebd9bb6384d From 055973fcb681e7fff7498cf2db95a204457a7bde Mon Sep 17 00:00:00 2001 From: Raquel Garcia Chico Date: Tue, 20 Aug 2024 01:31:06 +1200 Subject: [PATCH 215/261] AND-19285 Support Kotlin 2.0 (T17320522) --- .../meeting/view/ParticipantsFullListView.kt | 7 ++---- .../meeting/view/RecurringMeetingInfoView.kt | 6 +---- .../app/presentation/qrcode/QRCodeView.kt | 7 +----- .../view/TestPasswordComposeView.kt | 6 +---- ...ingMeetingOccurrenceBottomSheetViewTest.kt | 12 ++++++---- .../ui/controls/sheets/BottomSheetTest.kt | 23 ++++++++++++------- 6 files changed, 27 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsFullListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsFullListView.kt index e586899a99..0066717579 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsFullListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/ParticipantsFullListView.kt @@ -192,11 +192,8 @@ private fun ParticipantsFullListView( val scaffoldState = rememberScaffoldState() val snackbarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope() - val modalSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, - skipHalfExpanded = true, - ) + val modalSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) + var isAdmitAllButtonEnabled by rememberSaveable { mutableStateOf(true) } var isCallUserLimitWarningShown by rememberSaveable { mutableStateOf(false) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/RecurringMeetingInfoView.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/RecurringMeetingInfoView.kt index 94db8b02e7..dc583bb81a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/RecurringMeetingInfoView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/view/RecurringMeetingInfoView.kt @@ -110,11 +110,7 @@ fun RecurringMeetingInfoView( val scaffoldState = rememberScaffoldState() val snackbarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope() - val modalSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, - skipHalfExpanded = true, - ) + val modalSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) BackHandler(enabled = modalSheetState.isVisible) { coroutineScope.launch { modalSheetState.hide() } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/qrcode/QRCodeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/qrcode/QRCodeView.kt index b85de12496..f966368a81 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/qrcode/QRCodeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/qrcode/QRCodeView.kt @@ -143,12 +143,7 @@ internal fun QRCodeView( var showScannedContactLinkResult by remember { mutableStateOf(null) } var showInviteContactResult by remember { mutableStateOf(null) } var qrCodeComposableBounds by remember { mutableStateOf(null) } - - val modalSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, - skipHalfExpanded = true, - ) + val modalSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) BackHandler(enabled = modalSheetState.isVisible) { coroutineScope.launch { modalSheetState.hide() } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/testpassword/view/TestPasswordComposeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/testpassword/view/TestPasswordComposeView.kt index 717c718aec..79c51aa886 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/testpassword/view/TestPasswordComposeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/testpassword/view/TestPasswordComposeView.kt @@ -319,11 +319,7 @@ internal fun TestPasswordComposeView( } ) { padding -> val coroutineScope = rememberCoroutineScope() - val modalSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - confirmStateChange = { it != ModalBottomSheetValue.HalfExpanded }, - skipHalfExpanded = true, - ) + val modalSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) BackHandler(enabled = modalSheetState.isVisible) { coroutineScope.launch { modalSheetState.hide() } diff --git a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/view/sheet/RecurringMeetingOccurrenceBottomSheetViewTest.kt b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/view/sheet/RecurringMeetingOccurrenceBottomSheetViewTest.kt index 74518a5094..f86d53f068 100644 --- a/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/view/sheet/RecurringMeetingOccurrenceBottomSheetViewTest.kt +++ b/app/src/test/java/test/mega/privacy/android/app/presentation/meeting/view/sheet/RecurringMeetingOccurrenceBottomSheetViewTest.kt @@ -4,6 +4,7 @@ import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.test.onNodeWithTag import mega.privacy.android.app.presentation.meeting.view.sheet.CANCEL_OCCURRENCE_TAG import mega.privacy.android.app.presentation.meeting.view.sheet.RecurringMeetingOccurrenceBottomSheetView @@ -28,11 +29,6 @@ class RecurringMeetingOccurrenceBottomSheetViewTest { private val parentSchedId = 123456L private val schedId = 789123L - private val sheetState = ModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - isSkipHalfExpanded = false, - ) - @Test fun `test that Cancel button is shown`() { initComposeRuleContent( @@ -91,6 +87,12 @@ class RecurringMeetingOccurrenceBottomSheetViewTest { onEditClick: () -> Unit, ) { composeTestRule.setContent { + val sheetState = ModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + isSkipHalfExpanded = false, + density = LocalDensity.current, + ) + val coroutineScope = rememberCoroutineScope() RecurringMeetingOccurrenceBottomSheetView( diff --git a/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/sheets/BottomSheetTest.kt b/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/sheets/BottomSheetTest.kt index 6d0797873c..47ab76838e 100644 --- a/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/sheets/BottomSheetTest.kt +++ b/shared/original-core-ui/src/test/java/mega/privacy/android/shared/original/core/ui/controls/sheets/BottomSheetTest.kt @@ -10,6 +10,7 @@ import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsNotDisplayed @@ -34,11 +35,14 @@ class BottomSheetTest { fun `test that when view is set bottom sheet is not displayed to the user`() { val message = "message to test" val button = "show-bottom-sheet" - val sheetState = ModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - isSkipHalfExpanded = false, - ) + composeTestRule.setContent { + val sheetState = ModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + isSkipHalfExpanded = false, + density = LocalDensity.current, + ) + val coroutineScope = rememberCoroutineScope() BottomSheet( modalSheetState = sheetState, @@ -74,11 +78,14 @@ class BottomSheetTest { fun `test that when user clicks on button to show bottom sheet bottom sheet is shown to user`() { val message = "message to test" val button = "show-bottom-sheet" - val sheetState = ModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - isSkipHalfExpanded = false, - ) + composeTestRule.setContent { + val sheetState = ModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + isSkipHalfExpanded = false, + density = LocalDensity.current + ) + val coroutineScope = rememberCoroutineScope() BottomSheet( modalSheetState = sheetState, From 013cafccc88d8eb0fd2845ab025641c9ae1b7091 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Wed, 21 Aug 2024 15:49:19 +0530 Subject: [PATCH 216/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index ebc4418331..b36ebc4249 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ shimmerlayout = 'io.supercharge:shimmerlayout:2.1.0' simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorage" } vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240814.084644" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 943dc365e4cd877f73d5e26b2dae0d790764966a Mon Sep 17 00:00:00 2001 From: Yenel Date: Wed, 21 Aug 2024 17:12:29 +0200 Subject: [PATCH 217/261] Hotfix: Revert AND-19255 Optimize FastLoginUseCase --- .../domain/usecase/login/FastLoginUseCase.kt | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/FastLoginUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/FastLoginUseCase.kt index 1bf955c91f..2602ca98db 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/FastLoginUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/FastLoginUseCase.kt @@ -3,7 +3,6 @@ package mega.privacy.android.domain.usecase.login import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import mega.privacy.android.domain.entity.login.LoginStatus import mega.privacy.android.domain.exception.ChatNotInitializedErrorStatus @@ -40,44 +39,36 @@ class FastLoginUseCase @Inject constructor( ) = callbackFlow { loginMutex.lock() - val initialiseChatJob = launch { - runCatching { initialiseMegaChatUseCase(session) } - .onFailure { exception -> - if (exception is ChatNotInitializedErrorStatus) { - chatLogoutUseCase(disableChatApiUseCase) - } + runCatching { initialiseMegaChatUseCase(session) } + .onFailure { exception -> + if (exception is ChatNotInitializedErrorStatus) { + chatLogoutUseCase(disableChatApiUseCase) } - } - - val refreshChatUrlJob = if (refreshChatUrl) { - launch { loginRepository.refreshMegaChatUrl() } - } else null + } - val fastLoginJob = launch { - runCatching { - loginRepository.fastLoginFlow(session) - .collectLatest { loginStatus -> - if (loginStatus == LoginStatus.LoginSucceed) { - saveAccountCredentialsUseCase() - unlockLoginMutex() - } + if (refreshChatUrl) { + loginRepository.refreshMegaChatUrl() + } - trySend(loginStatus) + runCatching { + loginRepository.fastLoginFlow(session) + .collectLatest { loginStatus -> + if (loginStatus == LoginStatus.LoginSucceed) { + saveAccountCredentialsUseCase() + unlockLoginMutex() } - }.onFailure { - if (it !is LoginLoggedOutFromOtherLocation) { - chatLogoutUseCase(disableChatApiUseCase) - resetChatSettingsUseCase() + + trySend(loginStatus) } - unlockLoginMutex() - throw it + }.onFailure { + if (it !is LoginLoggedOutFromOtherLocation) { + chatLogoutUseCase(disableChatApiUseCase) + resetChatSettingsUseCase() } + unlockLoginMutex() + throw it } - initialiseChatJob.join() - refreshChatUrlJob?.join() - fastLoginJob.join() - awaitClose { unlockLoginMutex() } From 668599201ced14ab7e5413af35b27bcecc77d237 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 22 Aug 2024 09:59:46 +0700 Subject: [PATCH 218/261] AND-19330: Fix crash when open report issue screen (cherry picked from commit c742df9cbce8998f5c5cd88a09d459b261823db4) --- app/proguard-rules.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 0154b16978..d5605cb425 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -120,3 +120,11 @@ -keep public class androidx.compose.ui.platform.AndroidCompositionLocals_androidKt { public static *** getLocalLifecycleOwner(); } + +##################### +# Keep Fragment classes # +##################### +-keep class * extends androidx.fragment.app.Fragment { + # Keep the public no-argument constructor while allowing other methods to be optimized. + (); +} \ No newline at end of file From b6ee665cce81f91278af42db40749eefd28c0d77 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 22 Aug 2024 14:21:06 +0700 Subject: [PATCH 219/261] AND-19143: Fix stuck on login page when device is offline --- .../android/app/presentation/login/LoginActivity.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginActivity.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginActivity.kt index 9f4c8dc2be..cffa697ac8 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginActivity.kt @@ -27,6 +27,7 @@ import mega.privacy.android.app.extensions.isTablet import mega.privacy.android.app.globalmanagement.MegaChatRequestHandler import mega.privacy.android.app.interfaces.OnKeyboardVisibilityListener import mega.privacy.android.app.main.CreateAccountFragment +import mega.privacy.android.app.main.ManagerActivity import mega.privacy.android.app.presentation.extensions.toConstant import mega.privacy.android.app.presentation.login.confirmemail.ConfirmEmailFragment import mega.privacy.android.app.presentation.login.model.LoginFragmentType @@ -109,6 +110,15 @@ class LoginActivity : BaseActivity(), MegaRequestListenerInterface { Timber.d("onCreate") enableEdgeToEdge() super.onCreate(savedInstanceState) + if (intent.action == Intent.ACTION_MAIN + && intent.hasCategory(Intent.CATEGORY_LAUNCHER) + && !viewModel.isConnected + ) { + // in case offline mode, go to ManagerActivity + startActivity(Intent(this, ManagerActivity::class.java)) + finish() + return + } onBackPressedDispatcher.addCallback(this, onBackPressedCallback) chatRequestHandler.setIsLoggingRunning(true) binding = ActivityLoginBinding.inflate(layoutInflater) From 76558b6196dda4f8e86e47be975b5df460c7d572 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Fri, 23 Aug 2024 08:58:08 +0700 Subject: [PATCH 220/261] AND-19143: Crash when starting a call (cherry picked from commit 2650193a544bb3853a3764d7f5887aecb541a328) --- .../mega/privacy/android/app/utils/VideoCaptureUtils.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/utils/VideoCaptureUtils.java b/app/src/main/java/mega/privacy/android/app/utils/VideoCaptureUtils.java index a0725d5fb6..4e5e03c71c 100644 --- a/app/src/main/java/mega/privacy/android/app/utils/VideoCaptureUtils.java +++ b/app/src/main/java/mega/privacy/android/app/utils/VideoCaptureUtils.java @@ -2,6 +2,8 @@ import android.content.Context; +import androidx.annotation.Keep; + import org.webrtc.Camera1Enumerator; import org.webrtc.CameraEnumerator; import org.webrtc.CapturerObserver; @@ -13,6 +15,11 @@ import nz.mega.sdk.MegaChatApiAndroid; import timber.log.Timber; +/** + * The class can call from JNI to manage the video capture devices. + * Don't move package name and change class name + */ +@Keep public class VideoCaptureUtils { static private VideoCapturer videoCapturer = null; From 9a0b061bfa8d48ac0842feb9ed42125d99aa18c8 Mon Sep 17 00:00:00 2001 From: Robin Shi Date: Fri, 23 Aug 2024 17:57:53 +1200 Subject: [PATCH 221/261] AND-19143 Fix log missing issue --- app/proguard-rules.pro | 8 +++++++- .../mega/privacy/android/data/gateway/TimberChatLogger.kt | 2 ++ .../mega/privacy/android/data/gateway/TimberMegaLogger.kt | 2 ++ .../privacy/android/data/logging/LineNumberDebugTree.kt | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index d5605cb425..815b8a7d92 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -127,4 +127,10 @@ -keep class * extends androidx.fragment.app.Fragment { # Keep the public no-argument constructor while allowing other methods to be optimized. (); -} \ No newline at end of file +} + +-keep public class org.slf4j.** { *; } +-keep public class ch.** { *; } +-keep class javax.mail.** { *; } +-keep class javax.mail.internet.** { *; } +-dontwarn javax.mail.** \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/gateway/TimberChatLogger.kt b/data/src/main/java/mega/privacy/android/data/gateway/TimberChatLogger.kt index 6e35b8dd53..7a6757fd51 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/TimberChatLogger.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/TimberChatLogger.kt @@ -4,12 +4,14 @@ import nz.mega.sdk.MegaChatApi import nz.mega.sdk.MegaChatLoggerInterface import timber.log.Timber import javax.inject.Inject +import androidx.annotation.Keep /** * Chat file logger * * Chat log listener that prints all the chat output to file. See logback.xml for configuration */ +@Keep internal class TimberChatLogger @Inject constructor() : MegaChatLoggerInterface { @Synchronized override fun log(loglevel: Int, message: String?) { diff --git a/data/src/main/java/mega/privacy/android/data/gateway/TimberMegaLogger.kt b/data/src/main/java/mega/privacy/android/data/gateway/TimberMegaLogger.kt index d88aa30407..aa94daec86 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/TimberMegaLogger.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/TimberMegaLogger.kt @@ -1,6 +1,7 @@ package mega.privacy.android.data.gateway import android.util.Log +import androidx.annotation.Keep import nz.mega.sdk.MegaApiAndroid import nz.mega.sdk.MegaLoggerInterface import timber.log.Timber @@ -13,6 +14,7 @@ import javax.inject.Inject * * See logback.xml for configuration. */ +@Keep internal class TimberMegaLogger @Inject constructor() : MegaLoggerInterface { @Synchronized override fun log(time: String, logLevel: Int, source: String, message: String) { diff --git a/data/src/main/java/mega/privacy/android/data/logging/LineNumberDebugTree.kt b/data/src/main/java/mega/privacy/android/data/logging/LineNumberDebugTree.kt index 7848ce0f49..721504401e 100644 --- a/data/src/main/java/mega/privacy/android/data/logging/LineNumberDebugTree.kt +++ b/data/src/main/java/mega/privacy/android/data/logging/LineNumberDebugTree.kt @@ -1,6 +1,7 @@ package mega.privacy.android.data.logging import android.util.Log +import androidx.annotation.Keep import mega.privacy.android.data.gateway.TimberChatLogger import mega.privacy.android.data.gateway.TimberMegaLogger import timber.log.Timber @@ -10,6 +11,7 @@ import timber.log.Timber * * Debug log output tree for logcat */ +@Keep internal class LineNumberDebugTree : Timber.DebugTree() { private val ignoredClasses = listOf( Timber::class.java.name, From 42841f9a68b6b4d31911e400ebafc350431c73b9 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Mon, 26 Aug 2024 11:03:06 +0700 Subject: [PATCH 222/261] AND-19143: Add proguard rule for LiveEventBus (cherry picked from commit aa4e765c4199259e3c74df526f714d8829f02e62) --- app/proguard-rules.pro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 815b8a7d92..6c2e750ebd 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -129,6 +129,12 @@ (); } +##################### +# LiveEventBus remove this rule when removing LiveEventBus +# ExternalLiveData.java getFieldObservers and callMethodPutIfAbsent +##################### +-keep class androidx.arch.core.internal.SafeIterableMap { *; } + -keep public class org.slf4j.** { *; } -keep public class ch.** { *; } -keep class javax.mail.** { *; } From d580190a6dd05c28f4bb9cd43ce1ed6ab09e9bb5 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 27 Aug 2024 19:09:26 +1200 Subject: [PATCH 223/261] AND-19143: Add proguard rule for BannerViewPager (cherry picked from commit c962d211491add2e08669e1b37da7de5906784ee) --- app/proguard-rules.pro | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6c2e750ebd..f5aaa4ea5c 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -139,4 +139,16 @@ -keep public class ch.** { *; } -keep class javax.mail.** { *; } -keep class javax.mail.internet.** { *; } --dontwarn javax.mail.** \ No newline at end of file +-dontwarn javax.mail.** + +##################### +# BannerViewPager # +##################### +-keep class androidx.recyclerview.widget.** { *; } +-keep class androidx.viewpager2.widget.** { *; } + +##################### +# Matcher # +##################### +-keep class org.hamcrest.** { *; } +-dontwarn org.hamcrest.** \ No newline at end of file From 914588d90161914941d9e3bcc822520707d69ae3 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Tue, 27 Aug 2024 19:59:22 +0700 Subject: [PATCH 224/261] TRAN-522: Name collision doesn't show when uploading same file data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt domain/src/main/kotlin/mega/privacy/android/domain/repository/FileSystemRepository.kt --- .../data/repository/FileSystemRepositoryImpl.kt | 11 +++++++++++ .../domain/entity/document/DocumentEntity.kt | 4 ++-- .../domain/repository/FileSystemRepository.kt | 8 ++++++++ .../domain/usecase/file/FilePrepareUseCase.kt | 9 +++++++-- .../usecase/file/FilePrepareUseCaseTest.kt | 17 +++++++++++++---- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt index 665cbf8bdd..d82d9710cd 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/FileSystemRepositoryImpl.kt @@ -647,4 +647,15 @@ internal class FileSystemRepositoryImpl @Inject constructor( destination = destinationUri ) } + + override suspend fun getDocumentFileName(uri: UriPath): String = withContext(ioDispatcher) { + val rawUri = uri.value.toUri() + val isTreeUri = DocumentsContract.isTreeUri(rawUri) + val document = if (isTreeUri) { + DocumentFile.fromTreeUri(context, rawUri) + } else { + DocumentFile.fromSingleUri(context, rawUri) + } ?: throw FileNotFoundException("Content uri doesn't exist: $rawUri") + document.name.orEmpty() + } } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/document/DocumentEntity.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/document/DocumentEntity.kt index 2546426dd2..df526d5e61 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/document/DocumentEntity.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/document/DocumentEntity.kt @@ -27,8 +27,8 @@ data class DocumentEntity( /** * Creates DocumentEntity from file */ -fun File.toDocumentEntity() = DocumentEntity( - name = name, +fun File.toDocumentEntity(customName: String? = null) = DocumentEntity( + name = customName ?: name, size = length(), lastModified = lastModified(), uri = UriPath(absolutePath), diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/repository/FileSystemRepository.kt b/domain/src/main/kotlin/mega/privacy/android/domain/repository/FileSystemRepository.kt index 8ec92ea3e1..49a7bcbdbc 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/repository/FileSystemRepository.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/repository/FileSystemRepository.kt @@ -471,4 +471,12 @@ interface FileSystemRepository { * @param destination */ suspend fun copyUri(name: String, source: UriPath, destination: UriPath) + + /** + * Get document file name + * + * @param uri + * @return file name + */ + suspend fun getDocumentFileName(uri: UriPath): String } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCase.kt index 7ac486a409..061fe6718d 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCase.kt @@ -6,6 +6,7 @@ import mega.privacy.android.domain.entity.document.DocumentEntity import mega.privacy.android.domain.entity.document.toDocumentEntity import mega.privacy.android.domain.entity.uri.UriPath import mega.privacy.android.domain.qualifier.IoDispatcher +import mega.privacy.android.domain.repository.FileSystemRepository import mega.privacy.android.domain.usecase.transfers.GetFileForUploadUseCase import javax.inject.Inject @@ -14,17 +15,21 @@ import javax.inject.Inject */ class FilePrepareUseCase @Inject constructor( private val getFileForUploadUseCase: GetFileForUploadUseCase, + private val fileSystemRepository: FileSystemRepository, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, ) { /** - * invoke to prepare files from a list of UriPaths and returns a list of DocumentEntities. + * invoke to prepare files from a list of UriPaths and returns a list of cache files DocumentEntities. */ suspend operator fun invoke( uris: List, isChatUpload: Boolean = false, ): List = withContext(ioDispatcher) { uris.mapNotNull { - getFileForUploadUseCase(it.value, isChatUpload)?.toDocumentEntity() + getFileForUploadUseCase( + it.value, + isChatUpload + )?.toDocumentEntity(customName = fileSystemRepository.getDocumentFileName(it)) } } } \ No newline at end of file diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCaseTest.kt index cf5a998e36..d5890d6afe 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/file/FilePrepareUseCaseTest.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.document.DocumentEntity import mega.privacy.android.domain.entity.document.toDocumentEntity import mega.privacy.android.domain.entity.uri.UriPath +import mega.privacy.android.domain.repository.FileSystemRepository import mega.privacy.android.domain.usecase.transfers.GetFileForUploadUseCase import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeAll @@ -17,6 +18,7 @@ import org.mockito.Mockito.`when` import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.reset +import org.mockito.kotlin.whenever import java.io.File @ExperimentalCoroutinesApi @@ -24,6 +26,7 @@ import java.io.File class FilePrepareUseCaseTest { private val getFileForUploadUseCase: GetFileForUploadUseCase = mock() + private val fileSystemRepository: FileSystemRepository = mock() private lateinit var filePrepareUseCase: FilePrepareUseCase @@ -32,12 +35,16 @@ class FilePrepareUseCaseTest { @BeforeAll fun setUp() { - filePrepareUseCase = FilePrepareUseCase(getFileForUploadUseCase, testDispatcher) + filePrepareUseCase = FilePrepareUseCase( + getFileForUploadUseCase, + fileSystemRepository, + testDispatcher + ) } @BeforeEach fun reset() { - reset(getFileForUploadUseCase) + reset(getFileForUploadUseCase, fileSystemRepository) } @Test @@ -56,7 +63,8 @@ class FilePrepareUseCaseTest { on { absolutePath } doReturn "uri2" } val documentEntities = listOf(file1.toDocumentEntity(), file2.toDocumentEntity()) - + whenever(fileSystemRepository.getDocumentFileName(UriPath("uri1"))).thenReturn("name1") + whenever(fileSystemRepository.getDocumentFileName(UriPath("uri2"))).thenReturn("name2") `when`(getFileForUploadUseCase("uri1", false)).thenReturn(file1) `when`(getFileForUploadUseCase("uri2", false)).thenReturn(file2) @@ -77,7 +85,8 @@ class FilePrepareUseCaseTest { @Test fun `test invoke with null DocumentEntities`() = runTest(testScheduler) { val uriPaths = listOf(UriPath("uri1"), UriPath("uri2")) - + whenever(fileSystemRepository.getDocumentFileName(UriPath("uri1"))).thenReturn("name1") + whenever(fileSystemRepository.getDocumentFileName(UriPath("uri2"))).thenReturn("name2") `when`(getFileForUploadUseCase("uri1", false)).thenReturn(null) `when`(getFileForUploadUseCase("uri2", false)).thenReturn(null) From d192738ac2d9851319977486a4f80633e6ef267c Mon Sep 17 00:00:00 2001 From: Veronika Koreiba Date: Thu, 29 Aug 2024 16:51:03 +1200 Subject: [PATCH 225/261] AND-19338 Return Google Mobile Ads SDK --- app/build.gradle.kts | 1 + app/proguard-rules.pro | 36 +++++- app/src/main/AndroidManifest.xml | 7 ++ .../privacy/android/app/MegaApplication.kt | 8 ++ .../android/app/main/ManagerActivity.kt | 105 ++++++++++++------ .../presentation/manager/ManagerViewModel.kt | 10 ++ .../manager/model/ManagerState.kt | 4 + app/src/main/res/layout/activity_manager.xml | 4 +- app/src/main/res/values/dimens.xml | 2 +- gradle/catalogs/google.versions.toml | 2 + gradle/catalogs/lib.versions.toml | 2 +- 11 files changed, 140 insertions(+), 41 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 608904a72a..9226b1223e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -243,6 +243,7 @@ dependencies { // Google GMS implementation(lib.billing.client.ktx) + implementation(google.services.ads) implementation(google.services.location) implementation(google.services.maps) implementation(google.services.mlkit.document.scanner) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f5aaa4ea5c..28548e00b5 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -151,4 +151,38 @@ # Matcher # ##################### -keep class org.hamcrest.** { *; } --dontwarn org.hamcrest.** \ No newline at end of file +-dontwarn org.hamcrest.** + +##################### +# Google Ads # +##################### +-keep class com.google.android.gms.internal.ads.** { *; } +-keep public class com.google.android.gms.ads.** { + public *; +} + +-keep public class com.google.ads.** { + public *; +} + +# For mediation +-keepattributes *Annotation* + +# Other required classes for Google Play Services +# Read more at http://developer.android.com/google/play-services/setup.html +-keep class * extends java.util.ListResourceBundle { + protected Object[][] getContents(); +} + +-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { + public static final *** NULL; +} + +-keepnames @com.google.android.gms.common.annotation.KeepName class * +-keepclassmembernames class * { + @com.google.android.gms.common.annotation.KeepName *; +} + +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4191343b7f..403c6f9ddf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -725,6 +725,13 @@ + + \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt index 7f9b575e00..e1c3d47fe3 100644 --- a/app/src/main/java/mega/privacy/android/app/MegaApplication.kt +++ b/app/src/main/java/mega/privacy/android/app/MegaApplication.kt @@ -15,6 +15,7 @@ import coil.decode.GifDecoder import coil.decode.ImageDecoderDecoder import coil.decode.SvgDecoder import coil.decode.VideoFrameDecoder +import com.google.android.gms.ads.MobileAds import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase import com.jeremyliao.liveeventbus.LiveEventBus @@ -225,6 +226,13 @@ class MegaApplication : MultiDexApplication(), DefaultLifecycleObserver, setupMegaChatApi() getMiscFlagsIfNeeded() applicationScope.launch { + runCatching { + // Initialize the Google Mobile Ads SDK on a background thread. + MobileAds.initialize(this@MegaApplication) {} + Timber.i("MobileAds initialized") + }.onFailure { + Timber.e(it, "MobileAds initialization failed") + } runCatching { updateApiServerUseCase() } dbH.resetExtendedAccountDetailsTimestamp() // clear the cache files stored in the external cache folder. diff --git a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt index eb71739e9a..228d9010b9 100644 --- a/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt +++ b/app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt @@ -31,6 +31,7 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.Chronometer +import android.widget.FrameLayout import android.widget.LinearLayout import android.widget.RelativeLayout import android.widget.TextView @@ -80,6 +81,11 @@ import androidx.navigation.fragment.NavHostFragment import androidx.viewpager2.widget.ViewPager2 import androidx.work.WorkManager import com.anggrayudi.storage.file.getAbsolutePath +import com.google.android.gms.ads.AdListener +import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.ads.admanager.AdManagerAdRequest +import com.google.android.gms.ads.admanager.AdManagerAdView import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.MaterialToolbar import com.google.android.material.bottomnavigation.BottomNavigationView @@ -159,7 +165,6 @@ import mega.privacy.android.app.myAccount.MyAccountActivity import mega.privacy.android.app.presentation.advertisements.model.AdsSlotIDs.TAB_CLOUD_SLOT_ID import mega.privacy.android.app.presentation.advertisements.model.AdsSlotIDs.TAB_HOME_SLOT_ID import mega.privacy.android.app.presentation.advertisements.model.AdsSlotIDs.TAB_PHOTOS_SLOT_ID -import mega.privacy.android.app.presentation.advertisements.view.AdsBannerView import mega.privacy.android.app.presentation.backups.BackupsFragment import mega.privacy.android.app.presentation.bottomsheet.NodeOptionsBottomSheetDialogFragment import mega.privacy.android.app.presentation.bottomsheet.UploadBottomSheetDialogActionListener @@ -521,7 +526,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf private lateinit var freePlanLimitParticipantsDialogComposeView: ComposeView private lateinit var bottomNavigationView: BottomNavigationView private lateinit var navigationView: NavigationView - private lateinit var adsComposeView: ComposeView + private lateinit var adsContainerView: FrameLayout private var miniAudioPlayerController: MiniAudioPlayerController? = null private lateinit var cameraUploadViewTypes: LinearLayout @@ -635,6 +640,8 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } } + private var adView: AdManagerAdView? = null + override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, @@ -921,8 +928,8 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf private fun checkForInAppAdvertisement() { lifecycleScope.launch { runCatching { - val isAdsEnabled = getFeatureFlagValueUseCase(ABTestFeatures.ads) - if (isAdsEnabled) { + val isAdseFlagEnabled = getFeatureFlagValueUseCase(ABTestFeatures.adse) + if (isAdseFlagEnabled) { if (this@ManagerActivity.isPortrait()) { setupAdsView() } else { @@ -932,7 +939,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf adsViewModel.getDefaultStartScreen() } }.onFailure { - Timber.e("Failed to fetch feature flags or ab_ads test flag with error: ${it.message}") + Timber.e("Failed to fetch ab_adse flag with error: ${it.message}") } } } @@ -982,7 +989,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf findViewById(R.id.document_scanning_error_dialog_compose_view) freePlanLimitParticipantsDialogComposeView = findViewById(R.id.free_plan_limit_dialog_compose_view) - adsComposeView = findViewById(R.id.ads_web_compose_view) + adsContainerView = findViewById(R.id.ads_web_compose_view) fragmentLayout = findViewById(R.id.fragment_layout) bottomNavigationView = findViewById(R.id.bottom_navigation_view) @@ -2309,7 +2316,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf */ fun handleShowingAds(slotId: String) { if (this.isPortrait() && adsViewModel.canConsumeAdSlot(slotId)) { - adsViewModel.fetchNewAd(slotId) + showAdsView() } else { hideAdsView() } @@ -2327,6 +2334,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf checkForInAppUpdateInstallStatus() cookieDialogHandler.onResume() updateTransfersWidgetVisibility() + adView?.resume() } private fun checkForInAppUpdateInstallStatus() { @@ -2728,6 +2736,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf override fun onPause() { Timber.d("onPause") transfersManagement.isOnTransfersSection = false + adView?.pause() super.onPause() } @@ -2739,6 +2748,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf reconnectDialog?.cancel() dismissAlertDialogIfExists(processFileDialog) cookieDialogHandler.onDestroy() + adView?.destroy() super.onDestroy() } @@ -4047,7 +4057,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) val padding = - if (adsComposeView.isVisible) resources.getDimensionPixelSize(R.dimen.ads_web_view_and_bottom_navigation_view_height) + if (adsContainerView.isVisible) resources.getDimensionPixelSize(R.dimen.ads_web_view_and_bottom_navigation_view_height) else resources.getDimensionPixelSize(R.dimen.bottom_navigation_view_height) params.setMargins( 0, 0, 0, @@ -7181,7 +7191,7 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf ViewGroup.LayoutParams.MATCH_PARENT ) val height: Int = - if (adsComposeView.isVisible) resources.getDimensionPixelSize(R.dimen.ads_web_view_and_bottom_navigation_view_height) + if (adsContainerView.isVisible) resources.getDimensionPixelSize(R.dimen.ads_web_view_and_bottom_navigation_view_height) else resources.getDimensionPixelSize(R.dimen.bottom_navigation_view_height) if (hide && visibility == View.VISIBLE) { @@ -7814,33 +7824,51 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } private fun setupAdsView() { - adsComposeView.apply { - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnDetachedFromWindow) - setContent { - val themeMode by getThemeMode().collectAsStateWithLifecycle(initialValue = ThemeMode.System) - val isDark = themeMode.isDarkMode() - val uiState by adsViewModel.uiState.collectAsStateWithLifecycle() - OriginalTempTheme(isDark = isDark) { - AdsBannerView(uiState = uiState, - onAdsWebpageLoaded = ::onAdsWebpageLoaded, - onAdClicked = { uri -> - uri?.let { - val intent = Intent(Intent.ACTION_VIEW, it) - if (intent.resolveActivity(packageManager) != null) { - startActivity(intent) - onAdConsumed() - } else { - Timber.d("No Application found to can handle Ads intent") - adsViewModel.fetchNewAd() - } - } - }, onAdDismissed = { - onAdConsumed() - } - ) - } + val adView = AdManagerAdView(this) + // This is a adUntiId only for testing, it should be replace with real one after testing is finished + adView.adUnitId = AD_UNIT_ID + // the size will be set manually for now, the better implementation will be provided when API and SDK are ready + adView.setAdSize(AD_SIZE) + adView.adListener = object : AdListener() { + override fun onAdClicked() { + // Code to be executed when the user clicks on an ad. + Timber.d("Ad clicked") + } + + override fun onAdClosed() { + Timber.i("Ad closed") + // Code to be executed when the user is about to return + // to the app after tapping on an ad. + } + + override fun onAdFailedToLoad(adError : LoadAdError) { + // Code to be executed when an ad request fails. + Timber.w("Ad failed to load: ${adError.message}") + } + + override fun onAdImpression() { + Timber.i("Ad impression") + // Code to be executed when an impression is recorded + // for an ad. + } + + override fun onAdLoaded() { + Timber.i("Ad loaded") + // Code to be executed when an ad finishes loading. + } + + override fun onAdOpened() { + Timber.i("Ad opened") + // Code to be executed when an ad opens an overlay that + // covers the screen. } } + this.adView = adView + adsContainerView.removeAllViews() + adsContainerView.addView(adView) + + val adRequest = AdManagerAdRequest.Builder().build() + adView.loadAd(adRequest) } private fun onAdConsumed() { @@ -7851,11 +7879,14 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } private fun showAdsView() { - adsComposeView.isVisible = true + if (viewModel.state().adsEnabled) { + adsContainerView.isVisible = true + setupAdsView() + } } fun hideAdsView() { - adsComposeView.isVisible = false + adsContainerView.isVisible = false adsViewModel.cancelFetchingAds() } @@ -7876,6 +7907,8 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf } companion object { + const val AD_UNIT_ID = "ca-app-pub-2135147798858967/9835644604" + val AD_SIZE = AdSize(320, 50) const val TRANSFERS_TAB = "TRANSFERS_TAB" private const val BOTTOM_ITEM_BEFORE_OPEN_FULLSCREEN_OFFLINE = "BOTTOM_ITEM_BEFORE_OPEN_FULLSCREEN_OFFLINE" diff --git a/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt index 7a480c2283..ca80922323 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/manager/ManagerViewModel.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.launch import mega.privacy.android.app.MegaApplication import mega.privacy.android.app.R import mega.privacy.android.app.components.ChatManagement +import mega.privacy.android.app.featuretoggle.ABTestFeatures import mega.privacy.android.app.featuretoggle.ApiFeatures import mega.privacy.android.app.featuretoggle.AppFeatures import mega.privacy.android.app.main.dialog.removelink.RemovePublicLinkResultMapper @@ -532,6 +533,15 @@ class ManagerViewModel @Inject constructor( } } } + + viewModelScope.launch { + runCatching { + val isAdseFlagEnabled = getFeatureFlagValueUseCase(ABTestFeatures.adse) + _state.update { it.copy(adsEnabled = isAdseFlagEnabled) } + }.onFailure { + Timber.e(it, "Failed to get the adse feature flag") + } + } } /** diff --git a/app/src/main/java/mega/privacy/android/app/presentation/manager/model/ManagerState.kt b/app/src/main/java/mega/privacy/android/app/presentation/manager/model/ManagerState.kt index 081c750c73..c1f8378512 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/manager/model/ManagerState.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/manager/model/ManagerState.kt @@ -44,6 +44,8 @@ import mega.privacy.android.domain.entity.node.RestoreNodeResult * @property uploadEvent Event to trigger upload actions * @property handleScanDocumentResult Decides if the legacy or modern Document Scanner should be used * @property documentScanningErrorTypeUiItem The specific Error return when using the modern Document Scanner + * @property isAndroidSyncWorkManagerFeatureFlagEnabled Feature flag to use Android Sync Work Manager instead of SyncBackgroundService + * @property adsEnabled Boolean to determine if ads are enabled */ data class ManagerState( val isFirstNavigationLevel: Boolean = true, @@ -73,4 +75,6 @@ data class ManagerState( val uploadEvent: StateEventWithContent = consumed(), val handleScanDocumentResult: HandleScanDocumentResult? = null, val documentScanningErrorTypeUiItem: DocumentScanningErrorTypeUiItem? = null, + val isAndroidSyncWorkManagerFeatureFlagEnabled: Boolean = false, + val adsEnabled: Boolean = false, ) diff --git a/app/src/main/res/layout/activity_manager.xml b/app/src/main/res/layout/activity_manager.xml index 42aa1799dd..5d54dc5db1 100644 --- a/app/src/main/res/layout/activity_manager.xml +++ b/app/src/main/res/layout/activity_manager.xml @@ -154,10 +154,10 @@ app:labelVisibilityMode="unlabeled" app:menu="@menu/bottom_navigation_items" /> - diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index cb496b29c1..12f11080a6 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -107,7 +107,7 @@ 12dp 56dp - 146dp + 110dp 36dp 8dp diff --git a/gradle/catalogs/google.versions.toml b/gradle/catalogs/google.versions.toml index cf44d483cb..eb5fce590c 100644 --- a/gradle/catalogs/google.versions.toml +++ b/gradle/catalogs/google.versions.toml @@ -14,6 +14,7 @@ maps-compose = "6.1.0" play-review = "2.0.1" play-update = "2.1.0" protobuff = "3.22.3" +services-ads = "23.3.0" services-location = "21.3.0" services-maps = "18.2.0" services-mlkit-document-scanner = "16.0.0-beta1" @@ -54,6 +55,7 @@ play-review-ktx = { module = "com.google.android.play:review-ktx", version.ref = play-update = { module = "com.google.android.play:app-update", version.ref = "play-update" } play-update-ktx = { module = "com.google.android.play:app-update-ktx", version.ref = "play-update" } protobuff = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuff" } +services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "services-ads" } services-location = { module = "com.google.android.gms:play-services-location", version.ref = "services-location" } services-maps = { module = "com.google.android.gms:play-services-maps", version.ref = "services-maps" } services-mlkit-document-scanner = { module = "com.google.android.gms:play-services-mlkit-document-scanner", version.ref = "services-mlkit-document-scanner"} diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index b36ebc4249..57eda443cc 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -26,7 +26,7 @@ karma = "1.3" sqlcipher = "4.5.4" kotlin-serialisation = "1.6.3" eclipse-jgit = "6.6.0.202305301015-r" -json = "20230227" +json = "20240303" mega-core-ui = "2.10.20240531102524" kotlinx-collections-immutable = "0.3.7" From d97327daaa3da568c356bb3c3f25c373b43fee77 Mon Sep 17 00:00:00 2001 From: "Application Development (Jenkins Agent)" Date: Thu, 5 Sep 2024 05:08:23 +1200 Subject: [PATCH 226/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 019f6ce486..53b88ca959 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ shimmerlayout = 'io.supercharge:shimmerlayout:2.1.0' simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorage" } vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240903.072432" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From bbd7de5ea80f205db66945645572f017ee1235bb Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 5 Sep 2024 11:22:55 +0700 Subject: [PATCH 227/261] TRAN-537: Upload file doesn't work in android below 30 (cherry picked from commit f90bb697d2e9411417b1e072e714ec47bda521c4) --- .../ManagerUploadBottomSheetDialogActionHandler.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt b/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt index 4d92725c1d..0aace86fb2 100644 --- a/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt +++ b/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt @@ -31,7 +31,6 @@ import mega.privacy.android.app.presentation.bottomsheet.TakePictureAndUploadAct import mega.privacy.android.app.presentation.bottomsheet.UploadFilesActionListener import mega.privacy.android.app.presentation.bottomsheet.UploadFolderActionListener import mega.privacy.android.app.presentation.documentscanner.SaveScannedDocumentsActivity -import mega.privacy.android.app.presentation.extensions.uploadFilesManually import mega.privacy.android.app.presentation.extensions.uploadFolderManually import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.MegaNodeDialogUtil.IS_NEW_FOLDER_DIALOG_SHOWN @@ -189,7 +188,7 @@ internal class ManagerUploadBottomSheetDialogActionHandler @Inject constructor( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { manualUploadFilesLauncher.launch(POST_NOTIFICATIONS) } else { - managerActivity.uploadFilesManually() + openMultipleDocumentLauncher.launch(arrayOf("*/*")) } } From a2a0f97b2973d83c623f823fc7d0e91f2232a87a Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 6 Sep 2024 11:11:21 +0800 Subject: [PATCH 228/261] T17791576 AND - Cannot play videos after sliding in a chat 'shared files' --- .../imagepreview/ImagePreviewVideoLauncher.kt | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt index 0130f271a9..da3128c548 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/imagepreview/ImagePreviewVideoLauncher.kt @@ -7,15 +7,13 @@ import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.Constants.VIEWER_FROM_ZIP_BROWSER import mega.privacy.android.app.utils.FileUtil import mega.privacy.android.domain.entity.node.ImageNode -import mega.privacy.android.domain.entity.node.NodeContentUri import mega.privacy.android.domain.entity.node.chat.ChatImageFile import mega.privacy.android.domain.usecase.GetFileUrlByImageNodeUseCase import mega.privacy.android.domain.usecase.file.GetFileTypeInfoUseCase import mega.privacy.android.domain.usecase.file.GetFingerprintUseCase -import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerIsRunningUseCase -import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerStartUseCase import mega.privacy.android.domain.usecase.node.AddImageTypeUseCase import mega.privacy.android.domain.usecase.node.GetFolderLinkNodeContentUriUseCase +import mega.privacy.android.domain.usecase.node.GetNodeContentUriUseCase import mega.privacy.android.navigation.MegaNavigator import nz.mega.sdk.MegaNode import timber.log.Timber @@ -30,9 +28,8 @@ class ImagePreviewVideoLauncher @Inject constructor( private val getFingerprintUseCase: GetFingerprintUseCase, private val getFileUrlByImageNodeUseCase: GetFileUrlByImageNodeUseCase, private val addImageTypeUseCase: AddImageTypeUseCase, - private val megaApiHttpServerIsRunningUseCase: MegaApiHttpServerIsRunningUseCase, - private val megaApiHttpServerStartUseCase: MegaApiHttpServerStartUseCase, private val getFolderLinkNodeContentUriUseCase: GetFolderLinkNodeContentUriUseCase, + private val getNodeContentUriUseCase: GetNodeContentUriUseCase, private val getFileTypeInfoUseCase: GetFileTypeInfoUseCase, private val megaNavigator: MegaNavigator, ) { @@ -63,16 +60,10 @@ class ImagePreviewVideoLauncher @Inject constructor( } ?: run { val typedFileNode = addImageTypeUseCase(imageNode) if (source == ImagePreviewFetcherSource.CHAT) { - getFileUrlByImageNodeUseCase(imageNode as ChatImageFile)?.let { - val shouldStopHttpSever = if (megaApiHttpServerIsRunningUseCase() == 0) { - megaApiHttpServerStartUseCase() - true - } else false - NodeContentUri.RemoteContentUri(it, shouldStopHttpSever) - } + getNodeContentUriUseCase(imageNode as ChatImageFile) } else { getFolderLinkNodeContentUriUseCase(typedFileNode) - }?.let { contentUri -> + }.let { contentUri -> megaNavigator.openMediaPlayerActivityByFileNode( context = context, contentUri = contentUri, From 448bb74eeff321459e7bbcea2dd3ce89de6fc53a Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 6 Sep 2024 17:50:21 +0800 Subject: [PATCH 229/261] Resolve the issue where the folder link cannot be opened without login. T17791576 AND - Cannot play videos after sliding in a chat 'shared files' --- .../node/GetFolderLinkNodeContentUriUseCase.kt | 17 +++++++++++++---- .../GetFolderLinkNodeContentUriUseCaseTest.kt | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/GetFolderLinkNodeContentUriUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/GetFolderLinkNodeContentUriUseCase.kt index 53cd867f80..91e920d319 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/GetFolderLinkNodeContentUriUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/node/GetFolderLinkNodeContentUriUseCase.kt @@ -5,6 +5,8 @@ import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.usecase.GetLocalFolderLinkFromMegaApiFolderUseCase import mega.privacy.android.domain.usecase.GetLocalFolderLinkFromMegaApiUseCase import mega.privacy.android.domain.usecase.HasCredentialsUseCase +import mega.privacy.android.domain.usecase.mediaplayer.MegaApiFolderHttpServerIsRunningUseCase +import mega.privacy.android.domain.usecase.mediaplayer.MegaApiFolderHttpServerStartUseCase import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerIsRunningUseCase import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerStartUseCase import javax.inject.Inject @@ -15,6 +17,8 @@ import javax.inject.Inject class GetFolderLinkNodeContentUriUseCase @Inject constructor( private val megaApiHttpServerStartUseCase: MegaApiHttpServerStartUseCase, private val megaApiHttpServerIsRunningUseCase: MegaApiHttpServerIsRunningUseCase, + private val megaApiFolderHttpServerIsRunningUseCase: MegaApiFolderHttpServerIsRunningUseCase, + private val megaApiFolderHttpServerStartUseCase: MegaApiFolderHttpServerStartUseCase, private val getNodeContentUriUseCase: GetNodeContentUriUseCase, private val hasCredentialsUseCase: HasCredentialsUseCase, private val getLocalFolderLinkFromMegaApiUseCase: GetLocalFolderLinkFromMegaApiUseCase, @@ -28,13 +32,18 @@ class GetFolderLinkNodeContentUriUseCase @Inject constructor( * */ suspend operator fun invoke(fileNode: TypedFileNode): NodeContentUri { - val shouldStopHttpSever = if (megaApiHttpServerIsRunningUseCase() == 0) { - megaApiHttpServerStartUseCase() - true - } else false + val shouldStopHttpSever: Boolean return if (hasCredentialsUseCase()) { + shouldStopHttpSever = if (megaApiHttpServerIsRunningUseCase() == 0) { + megaApiHttpServerStartUseCase() + true + } else false getLocalFolderLinkFromMegaApiUseCase(fileNode.id.longValue) } else { + shouldStopHttpSever = if (megaApiFolderHttpServerIsRunningUseCase() == 0) { + megaApiFolderHttpServerStartUseCase() + true + } else false getLocalFolderLinkFromMegaApiFolderUseCase(fileNode.id.longValue) }?.let { url -> NodeContentUri.RemoteContentUri(url, shouldStopHttpSever) diff --git a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/GetFolderLinkNodeContentUriUseCaseTest.kt b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/GetFolderLinkNodeContentUriUseCaseTest.kt index 40f7054a64..9235027eb5 100644 --- a/domain/src/test/kotlin/mega/privacy/android/domain/usecase/GetFolderLinkNodeContentUriUseCaseTest.kt +++ b/domain/src/test/kotlin/mega/privacy/android/domain/usecase/GetFolderLinkNodeContentUriUseCaseTest.kt @@ -4,6 +4,8 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import mega.privacy.android.domain.entity.node.NodeContentUri import mega.privacy.android.domain.entity.node.TypedFileNode +import mega.privacy.android.domain.usecase.mediaplayer.MegaApiFolderHttpServerIsRunningUseCase +import mega.privacy.android.domain.usecase.mediaplayer.MegaApiFolderHttpServerStartUseCase import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerIsRunningUseCase import mega.privacy.android.domain.usecase.mediaplayer.MegaApiHttpServerStartUseCase import mega.privacy.android.domain.usecase.node.GetFolderLinkNodeContentUriUseCase @@ -24,6 +26,9 @@ class GetFolderLinkNodeContentUriUseCaseTest { private val megaApiHttpServerStartUseCase = mock() private val megaApiHttpServerIsRunningUseCase = mock() + private val megaApiFolderHttpServerIsRunningUseCase = + mock() + private val megaApiFolderHttpServerStartUseCase = mock() private val getNodeContentUriUseCase = mock() private val hasCredentialsUseCase = mock() private val getLocalFolderLinkFromMegaApiUseCase = mock() @@ -37,6 +42,8 @@ class GetFolderLinkNodeContentUriUseCaseTest { underTest = GetFolderLinkNodeContentUriUseCase( megaApiHttpServerStartUseCase = megaApiHttpServerStartUseCase, megaApiHttpServerIsRunningUseCase = megaApiHttpServerIsRunningUseCase, + megaApiFolderHttpServerStartUseCase = megaApiFolderHttpServerStartUseCase, + megaApiFolderHttpServerIsRunningUseCase = megaApiFolderHttpServerIsRunningUseCase, getNodeContentUriUseCase = getNodeContentUriUseCase, hasCredentialsUseCase = hasCredentialsUseCase, getLocalFolderLinkFromMegaApiUseCase = getLocalFolderLinkFromMegaApiUseCase, @@ -49,6 +56,8 @@ class GetFolderLinkNodeContentUriUseCaseTest { reset( megaApiHttpServerStartUseCase, megaApiHttpServerIsRunningUseCase, + megaApiFolderHttpServerStartUseCase, + megaApiFolderHttpServerIsRunningUseCase, getNodeContentUriUseCase, hasCredentialsUseCase, getLocalFolderLinkFromMegaApiUseCase, @@ -72,7 +81,7 @@ class GetFolderLinkNodeContentUriUseCaseTest { runTest { whenever(hasCredentialsUseCase()).thenReturn(false) whenever(getLocalFolderLinkFromMegaApiFolderUseCase(any())).thenReturn(expectedUrl) - whenever(megaApiHttpServerIsRunningUseCase()).thenReturn(0) + whenever(megaApiFolderHttpServerIsRunningUseCase()).thenReturn(0) assertThat(underTest(mock())).isEqualTo( NodeContentUri.RemoteContentUri(url = expectedUrl, shouldStopHttpSever = true) ) @@ -94,7 +103,7 @@ class GetFolderLinkNodeContentUriUseCaseTest { runTest { whenever(hasCredentialsUseCase()).thenReturn(false) whenever(getLocalFolderLinkFromMegaApiFolderUseCase(any())).thenReturn(expectedUrl) - whenever(megaApiHttpServerIsRunningUseCase()).thenReturn(1) + whenever(megaApiFolderHttpServerIsRunningUseCase()).thenReturn(1) assertThat(underTest(mock())).isEqualTo( NodeContentUri.RemoteContentUri(url = expectedUrl, shouldStopHttpSever = false) ) @@ -117,7 +126,7 @@ class GetFolderLinkNodeContentUriUseCaseTest { val fileNode = mock() whenever(hasCredentialsUseCase()).thenReturn(false) whenever(getLocalFolderLinkFromMegaApiFolderUseCase(any())).thenReturn(null) - whenever(megaApiHttpServerIsRunningUseCase()).thenReturn(1) + whenever(megaApiFolderHttpServerIsRunningUseCase()).thenReturn(1) underTest(fileNode) verify(getNodeContentUriUseCase).invoke(fileNode) } From 8084ee860190bedb0548b7644989eec604ebcfcf Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Fri, 6 Sep 2024 12:33:21 +0200 Subject: [PATCH 230/261] TRAN-540: Users are not requested to add app reviews. (cherry picked from commit 9dc7fe3dbc5108d6ee20f5a2074a6f199ba74e04) 9dc7fe3d TRAN-540: Users are not requested to add app reviews. --- .../starttransfer/StartTransfersComponentViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/transfers/starttransfer/StartTransfersComponentViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/transfers/starttransfer/StartTransfersComponentViewModel.kt index 407dc5f3d5..f3329623b7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/transfers/starttransfer/StartTransfersComponentViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/transfers/starttransfer/StartTransfersComponentViewModel.kt @@ -611,7 +611,7 @@ internal class StartTransfersComponentViewModel @Inject constructor( if (checkShowDownloadRating && !paused && transferTotals.totalFileTransfers > 0) { val currentDownloadSpeed = getCurrentDownloadSpeedUseCase() RatingHandlerImpl().showRatingBaseOnSpeedAndSize( - size = transferTotals.totalFileTransfers.toLong(), + size = transferTotals.totalBytes, speed = currentDownloadSpeed.toLong(), listener = object : OnCompleteListener { override fun onComplete() { @@ -764,7 +764,7 @@ internal class StartTransfersComponentViewModel @Inject constructor( if (checkShowUploadRating && !paused && transferTotals.totalFileTransfers > 0) { val currentUploadSpeed = getCurrentUploadSpeedUseCase() RatingHandlerImpl().showRatingBaseOnSpeedAndSize( - size = transferTotals.totalFileTransfers.toLong(), + size = transferTotals.totalBytes, speed = currentUploadSpeed, listener = object : OnCompleteListener { override fun onComplete() { From 454e94971a38b39c9da9d9ffaad973d8620fe2d5 Mon Sep 17 00:00:00 2001 From: Yenel Date: Fri, 6 Sep 2024 12:48:52 +0200 Subject: [PATCH 231/261] Hotfix SAT-1472 Log in button not working --- .../domain/usecase/login/BackgroundFastLoginUseCase.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/BackgroundFastLoginUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/BackgroundFastLoginUseCase.kt index 4f7ef5dcad..4f66c27c34 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/BackgroundFastLoginUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/login/BackgroundFastLoginUseCase.kt @@ -33,8 +33,10 @@ class BackgroundFastLoginUseCase @Inject constructor( suspend operator fun invoke(): String { loginMutex.lock() - val session = - getSessionUseCase() ?: throw SessionNotRetrievedException() + val session = getSessionUseCase() ?: run { + runCatching { loginMutex.unlock() } + throw SessionNotRetrievedException() + } if (!getRootNodeExistsUseCase()) { initialiseMegaChatUseCase(session) From b6a20cde9fb8e60ab0919c6faedc715aad34380b Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 6 Sep 2024 20:43:37 +0800 Subject: [PATCH 232/261] T17791572 AND- Recently Watched in Videos --- .../DefaultMediaPlayerRepository.kt | 10 +++++++++ .../repository/VideoSectionRepositoryImpl.kt | 2 +- .../DefaultMediaPlayerRepositoryTest.kt | 12 ++++++++++ .../android/domain/di/InternalLogoutModule.kt | 6 +++++ .../entity/mediaplayer/PlaybackInformation.kt | 10 ++++++--- .../repository/MediaPlayerRepository.kt | 5 +++++ .../ClearVideoPlaybackDataLogoutTask.kt | 22 +++++++++++++++++++ 7 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 domain/src/main/kotlin/mega/privacy/android/domain/usecase/logout/ClearVideoPlaybackDataLogoutTask.kt diff --git a/data/src/main/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepository.kt index 453953cd73..70ba7bb4f1 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepository.kt @@ -7,6 +7,8 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import mega.privacy.android.data.database.DatabaseHandler import mega.privacy.android.data.extensions.getRequestListener import mega.privacy.android.data.gateway.FileGateway @@ -391,6 +393,14 @@ internal class DefaultMediaPlayerRepository @Inject constructor( playbackInfoMap.remove(mediaId) } + override suspend fun clearPlaybackInformation() = withContext(ioDispatcher) { + playbackInfoMap.clear() + appPreferencesGateway.putString( + PREFERENCE_KEY_VIDEO_EXIT_TIME, + Json.encodeToString(playbackInfoMap) + ) + } + override suspend fun savePlaybackTimes() { appPreferencesGateway.putString( PREFERENCE_KEY_VIDEO_EXIT_TIME, diff --git a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt index fb7e7609c8..4b99347402 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt @@ -353,7 +353,7 @@ internal class VideoSectionRepositoryImpl @Inject constructor( }.sortedByDescending { it.watchedTimestamp } } - override suspend fun clearRecentlyWatchedVideos() { + override suspend fun clearRecentlyWatchedVideos() = withContext(ioDispatcher) { recentlyWatchedVideosData.clear() appPreferencesGateway.putString( PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, diff --git a/data/src/test/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepositoryTest.kt b/data/src/test/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepositoryTest.kt index 99cb62ff13..bc7cf7d1a5 100644 --- a/data/src/test/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepositoryTest.kt +++ b/data/src/test/java/mega/privacy/android/data/repository/DefaultMediaPlayerRepositoryTest.kt @@ -7,6 +7,8 @@ import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import mega.privacy.android.data.database.DatabaseHandler import mega.privacy.android.data.gateway.FileGateway import mega.privacy.android.data.gateway.MegaLocalRoomGateway @@ -230,6 +232,16 @@ class DefaultMediaPlayerRepositoryTest { assertThat(actual?.containsKey(expectedDeleteMediaId)).isFalse() } + @Test + fun `test that clearPlaybackInformation function is invoked as expected`() = + runTest { + underTest.clearPlaybackInformation() + verify(appPreferencesGateway).putString( + "PREFERENCE_KEY_VIDEO_EXIT_TIME", + Json.encodeToString(emptyMap()) + ) + } + @ParameterizedTest(name = "when audio repeatMode is {0}, the result of monitorAudioRepeatMode is {1}") @MethodSource("provideRepeatModeParameters") fun `test that the result of monitorAudioRepeatMode functions are correct`( diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/di/InternalLogoutModule.kt b/domain/src/main/kotlin/mega/privacy/android/domain/di/InternalLogoutModule.kt index bb783a0c07..63909a0285 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/di/InternalLogoutModule.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/di/InternalLogoutModule.kt @@ -6,6 +6,7 @@ import dagger.hilt.migration.DisableInstallInCheck import dagger.multibindings.IntoSet import mega.privacy.android.domain.usecase.logout.ClearChatDataLogoutTask import mega.privacy.android.domain.usecase.logout.ClearPasscodeDataLogoutTask +import mega.privacy.android.domain.usecase.logout.ClearVideoPlaybackDataLogoutTask import mega.privacy.android.domain.usecase.logout.LogoutTask import mega.privacy.android.domain.usecase.logout.RemoveBackupFoldersLogoutTask @@ -27,5 +28,10 @@ internal abstract class InternalLogoutModule { @IntoSet fun provideClearChatDataLogoutTask(task: ClearChatDataLogoutTask): LogoutTask = task + + @Provides + @IntoSet + fun provideClearVideoPlaybackDataLogoutTask(task: ClearVideoPlaybackDataLogoutTask): LogoutTask = + task } } \ No newline at end of file diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/entity/mediaplayer/PlaybackInformation.kt b/domain/src/main/kotlin/mega/privacy/android/domain/entity/mediaplayer/PlaybackInformation.kt index 18dd761723..c6d0047263 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/entity/mediaplayer/PlaybackInformation.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/entity/mediaplayer/PlaybackInformation.kt @@ -1,5 +1,8 @@ package mega.privacy.android.domain.entity.mediaplayer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + /** * The entity for playback information * @@ -7,8 +10,9 @@ package mega.privacy.android.domain.entity.mediaplayer * @property totalDuration the total duration of media item * @property currentPosition the current position of media item */ +@Serializable data class PlaybackInformation( - val mediaId: Long?, - val totalDuration: Long, - val currentPosition: Long, + @SerialName("mediaId") val mediaId: Long?, + @SerialName("totalDuration") val totalDuration: Long, + @SerialName("currentPosition") val currentPosition: Long, ) diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/repository/MediaPlayerRepository.kt b/domain/src/main/kotlin/mega/privacy/android/domain/repository/MediaPlayerRepository.kt index 548688531d..d1f1930946 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/repository/MediaPlayerRepository.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/repository/MediaPlayerRepository.kt @@ -256,6 +256,11 @@ interface MediaPlayerRepository { */ suspend fun deletePlaybackInformation(mediaId: Long) + /** + * Clear Playback Information + */ + suspend fun clearPlaybackInformation() + /** * Save the playback times */ diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/logout/ClearVideoPlaybackDataLogoutTask.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/logout/ClearVideoPlaybackDataLogoutTask.kt new file mode 100644 index 0000000000..3336aa2d34 --- /dev/null +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/logout/ClearVideoPlaybackDataLogoutTask.kt @@ -0,0 +1,22 @@ +package mega.privacy.android.domain.usecase.logout + +import mega.privacy.android.domain.repository.MediaPlayerRepository +import mega.privacy.android.domain.usecase.videosection.ClearRecentlyWatchedVideosUseCase +import javax.inject.Inject + +/** + * Clear video playback data logout task + */ +class ClearVideoPlaybackDataLogoutTask @Inject constructor( + private val clearRecentlyWatchedVideosUseCase: ClearRecentlyWatchedVideosUseCase, + private val mediaPlayerRepository: MediaPlayerRepository, +) : LogoutTask { + + /** + * Invoke + */ + override suspend fun invoke() { + clearRecentlyWatchedVideosUseCase() + mediaPlayerRepository.clearPlaybackInformation() + } +} \ No newline at end of file From 2ef7f5eb615ac030f3a84ee6dd4d0a05030c1361 Mon Sep 17 00:00:00 2001 From: Hai Luong Date: Thu, 5 Sep 2024 11:22:55 +0700 Subject: [PATCH 233/261] TRAN-537: Upload file doesn't work in android below 30 (cherry picked from commit f90bb697d2e9411417b1e072e714ec47bda521c4) --- .../ManagerUploadBottomSheetDialogActionHandler.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt b/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt index adaecd6fe9..6e2bc3c367 100644 --- a/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt +++ b/app/src/main/java/mega/privacy/android/app/main/managerSections/ManagerUploadBottomSheetDialogActionHandler.kt @@ -31,7 +31,6 @@ import mega.privacy.android.app.presentation.bottomsheet.TakePictureAndUploadAct import mega.privacy.android.app.presentation.bottomsheet.UploadFilesActionListener import mega.privacy.android.app.presentation.bottomsheet.UploadFolderActionListener import mega.privacy.android.app.presentation.documentscanner.SaveScannedDocumentsActivity -import mega.privacy.android.app.presentation.extensions.uploadFilesManually import mega.privacy.android.app.presentation.extensions.uploadFolderManually import mega.privacy.android.app.utils.Constants import mega.privacy.android.app.utils.MegaNodeDialogUtil.IS_NEW_FOLDER_DIALOG_SHOWN @@ -183,7 +182,7 @@ internal class ManagerUploadBottomSheetDialogActionHandler @Inject constructor( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { manualUploadFilesLauncher.launch(POST_NOTIFICATIONS) } else { - managerActivity.uploadFilesManually() + openMultipleDocumentLauncher.launch(arrayOf("*/*")) } } From 5a28b2ac15ac2a99d67324d8ab4d13865b2a6093 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Mon, 9 Sep 2024 10:45:42 +0530 Subject: [PATCH 234/261] Update version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index f94de87037..91879c9d55 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,7 +78,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "14.2" +extra["appVersion"] = "14.2.1" // Sdk and tools extra["compileSdkVersion"] = 35 From 873416952bfdaf87b0df871d5f8aaaaea47a3fb2 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Wed, 11 Sep 2024 09:29:01 +1200 Subject: [PATCH 235/261] AND-19197 - Convert reaction picker to modal card (cherry picked from commit 5825b5d0eaf03ac327eaddf43daab9a493e578b1) 01df2508 AND-19197 - Convert reaction picker to modal card 7646e74a Test fixes --- .../presentation/meeting/chat/ChatFragment.kt | 15 +-- .../compose/ChatViewNavigationGraph.kt | 1 + .../compose/EmojiPickerModalNavigation.kt | 19 +-- .../compose/MessageOptionsModalNavigation.kt | 3 + .../chat/view/sheet/EmojiBottomSheet.kt | 28 ----- .../chat/view/sheet/EmojiPickerDialog.kt | 33 +++++ .../view/sheet/MessageOptionsBottomSheet.kt | 117 +++--------------- .../sheet/MessageOptionsBottomSheetTest.kt | 2 + gradle/catalogs/androidx.versions.toml | 2 +- .../ui/controls/chat/MegaEmojiPickerView.kt | 23 ---- 10 files changed, 69 insertions(+), 174 deletions(-) delete mode 100644 app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiBottomSheet.kt create mode 100644 app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiPickerDialog.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatFragment.kt index 36cd8316fc..f4b5cc1891 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/ChatFragment.kt @@ -5,12 +5,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetValue -import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.material.rememberScaffoldState import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -21,8 +17,8 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions -import com.google.accompanist.navigation.material.BottomSheetNavigator import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi +import com.google.accompanist.navigation.material.rememberBottomSheetNavigator import dagger.hilt.android.AndroidEntryPoint import mega.privacy.android.analytics.Analytics import mega.privacy.android.app.R @@ -48,7 +44,6 @@ import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme import mega.privacy.mobile.analytics.event.ChatConversationScreenEvent import javax.inject.Inject -@OptIn(ExperimentalMaterialApi::class) @AndroidEntryPoint internal class ChatFragment : Fragment() { @@ -78,13 +73,7 @@ internal class ChatFragment : Fragment() { PasscodeContainer( passcodeCryptObjectFactory = passcodeCryptObjectFactory, content = { - val sheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - skipHalfExpanded = false - ) - val bottomSheetNavigator = remember { - BottomSheetNavigator(sheetState) - } + val bottomSheetNavigator = rememberBottomSheetNavigator() val navHostController = rememberNavController(bottomSheetNavigator) val chatId = requireActivity().intent.getLongExtra(Constants.CHAT_ID, -1) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/ChatViewNavigationGraph.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/ChatViewNavigationGraph.kt index 05489e4c3e..38369bcd33 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/ChatViewNavigationGraph.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/ChatViewNavigationGraph.kt @@ -98,6 +98,7 @@ internal fun NavGraphBuilder.chatViewNavigationGraph( messageOptionsModal( navController = navController, + navigateToEmojiPicker = navController::navigateToEmojiPickerModal, ) { navController.popBackStack( ConversationRoute, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/EmojiPickerModalNavigation.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/EmojiPickerModalNavigation.kt index a384c5c039..773859bc01 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/EmojiPickerModalNavigation.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/EmojiPickerModalNavigation.kt @@ -3,33 +3,34 @@ package mega.privacy.android.app.presentation.meeting.chat.view.navigation.compo import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.NavOptions -import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi -import com.google.accompanist.navigation.material.bottomSheet +import androidx.navigation.compose.dialog import mega.privacy.android.app.presentation.meeting.chat.model.ChatViewModel -import mega.privacy.android.app.presentation.meeting.chat.view.sheet.EmojiBottomSheet +import mega.privacy.android.app.presentation.meeting.chat.view.sheet.EmojiPickerDialog private const val messageIdArg = "messageId" -@OptIn(ExperimentalMaterialNavigationApi::class) internal fun NavGraphBuilder.emojiPickerModal( navController: NavHostController, - closeBottomSheets: () -> Unit, + closeView: () -> Unit, ) { - bottomSheet(route = "emojiModal/{$messageIdArg}") { backStackEntry -> + dialog(route = "emojiModal/{$messageIdArg}") { backStackEntry -> val viewModel = backStackEntry.sharedViewModel(navController) val messageId = backStackEntry.arguments?.getString(messageIdArg)?.toLongOrNull() ?: throw IllegalArgumentException("messageId cannot be null for emojiModal") - EmojiBottomSheet( + EmojiPickerDialog( onReactionClicked = { viewModel.onAddReaction(messageId, it) - closeBottomSheets() + closeView() }, ) } } -internal fun NavHostController.navigateToEmojiPickerModal(messageId: Long, navOptions: NavOptions? = null) { +internal fun NavHostController.navigateToEmojiPickerModal( + messageId: Long, + navOptions: NavOptions? = null, +) { navigate("emojiModal/$messageId", navOptions) } \ No newline at end of file diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/MessageOptionsModalNavigation.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/MessageOptionsModalNavigation.kt index bbfa28a09b..d674356098 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/MessageOptionsModalNavigation.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/navigation/compose/MessageOptionsModalNavigation.kt @@ -13,6 +13,7 @@ private const val messageIdArg = "messageId" @OptIn(ExperimentalMaterialNavigationApi::class) internal fun NavGraphBuilder.messageOptionsModal( navController: NavHostController, + navigateToEmojiPicker: (Long) -> Unit, closeBottomSheets: () -> Unit, ) { bottomSheet(route = "messageOptionsModal/{$messageIdArg}") { backStackEntry -> @@ -22,10 +23,12 @@ internal fun NavGraphBuilder.messageOptionsModal( ?: throw IllegalArgumentException("messageId cannot be null for messageOptionsModal") MessageOptionsBottomSheet( + messageId = messageId, onReactionClicked = { viewModel.onAddReaction(messageId, it) closeBottomSheets() }, + onMoreReactionsClicked = navigateToEmojiPicker, actions = viewModel.getApplicableBotomsheetActions { closeBottomSheets() }, ) } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiBottomSheet.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiBottomSheet.kt deleted file mode 100644 index 5a8d5a4b0a..0000000000 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiBottomSheet.kt +++ /dev/null @@ -1,28 +0,0 @@ -package mega.privacy.android.app.presentation.meeting.chat.view.sheet - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import mega.privacy.android.shared.original.core.ui.controls.chat.MegaEmojiPickerView - -@Composable -fun EmojiBottomSheet( - onReactionClicked: (String) -> Unit, -){ - val scrollState = rememberScrollState() - Column( - modifier = Modifier - .fillMaxWidth() - .verticalScroll(scrollState) - .systemBarsPadding() - ) { - MegaEmojiPickerView( - onEmojiPicked = { onReactionClicked(it.emoji) }, - modifier = Modifier - ) - } -} diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiPickerDialog.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiPickerDialog.kt new file mode 100644 index 0000000000..43fded4616 --- /dev/null +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/EmojiPickerDialog.kt @@ -0,0 +1,33 @@ +package mega.privacy.android.app.presentation.meeting.chat.view.sheet + +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import mega.privacy.android.shared.original.core.ui.controls.cards.MegaCard +import mega.privacy.android.shared.original.core.ui.controls.chat.MegaEmojiPickerView + +/** + * Emoji picker dialog + * + * @param onReactionClicked + */ +@Composable +fun EmojiPickerDialog( + onReactionClicked: (String) -> Unit, +){ + MegaCard( + modifier = Modifier + .padding(16.dp) + .fillMaxWidth() + .fillMaxHeight(0.9f), + content = { + MegaEmojiPickerView( + onEmojiPicked = { onReactionClicked(it.emoji) }, + modifier = Modifier + ) + } + ) +} diff --git a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheet.kt b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheet.kt index 593fec3baf..01fcc0884d 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheet.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheet.kt @@ -1,34 +1,14 @@ package mega.privacy.android.app.presentation.meeting.chat.view.sheet -import android.content.Context -import android.content.res.Configuration -import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.SizeTransform -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideOutHorizontally -import androidx.compose.animation.togetherWith import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp -import androidx.emoji2.emojipicker.EmojiPickerView import mega.privacy.android.app.presentation.meeting.chat.model.messages.actions.MessageBottomSheetAction -import mega.privacy.android.shared.original.core.ui.controls.chat.MegaEmojiPickerView import mega.privacy.android.shared.original.core.ui.controls.chat.messages.reaction.AddReactionsSheetItem import mega.privacy.android.shared.original.core.ui.controls.dividers.DividerType import mega.privacy.android.shared.original.core.ui.controls.dividers.MegaDivider @@ -41,107 +21,44 @@ import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme @Composable fun MessageOptionsBottomSheet( onReactionClicked: (String) -> Unit, + onMoreReactionsClicked: (Long) -> Unit, actions: List, modifier: Modifier = Modifier, + messageId: Long, ) { - val scrollState = rememberScrollState() - var preloadedPicker by remember { - mutableStateOf(null) - } - - val context = LocalContext.current - val isPortrait = - LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT - - LaunchedEffect(isPortrait) { - preloadedPicker = preloadEmojiPicker( - context = context, - isPortrait = isPortrait, - onEmojiSelected = onReactionClicked - ) - } - - var moreEmoji by remember { - mutableStateOf(false) - } - - val showEmoji by remember { derivedStateOf { preloadedPicker != null && moreEmoji } } - - BackHandler(moreEmoji) { - moreEmoji = false - } - - Column( modifier = modifier .fillMaxWidth() .testTag(TEST_TAG_MESSAGE_OPTIONS_PANEL) - .verticalScroll(scrollState) ) { - AnimatedContent( - targetState = showEmoji, - transitionSpec = { - if (targetState) { - // Forward animation: slide in from right and out to left - slideInHorizontally(initialOffsetX = { fullWidth -> fullWidth }) togetherWith - slideOutHorizontally(targetOffsetX = { fullWidth -> -fullWidth }) using - SizeTransform(clip = false) - } else { - // Reverse animation: slide in from left and out to right - slideInHorizontally(initialOffsetX = { fullWidth -> -fullWidth }) togetherWith - slideOutHorizontally(targetOffsetX = { fullWidth -> fullWidth }) using - SizeTransform(clip = false) - } - }, label = "Animate emoji picker" - ) { targetState -> - if (targetState) { - val picker = preloadedPicker - if (picker != null) { - MegaEmojiPickerView( - preloadedPicker = picker, - modifier = Modifier - ) - } - } else { - Column { - AddReactionsSheetItem( - onReactionClicked = { - onReactionClicked(it) - }, - onMoreReactionsClicked = { moreEmoji = true }, - modifier = Modifier.padding(8.dp), - ) + AddReactionsSheetItem( + onReactionClicked = { + onReactionClicked(it) + }, + onMoreReactionsClicked = { onMoreReactionsClicked(messageId) }, + modifier = Modifier.padding(8.dp), + ) - var group = if (actions.isNotEmpty()) actions.first().group else null - actions.forEach { - if (group != it.group) { - MegaDivider(dividerType = DividerType.BigStartPadding) - group = it.group - } - it.view() - } - } + var group = if (actions.isNotEmpty()) actions.first().group else null + actions.forEach { + if (group != it.group) { + MegaDivider(dividerType = DividerType.BigStartPadding) + group = it.group } + it.view() } } } -private fun preloadEmojiPicker( - context: Context, - isPortrait: Boolean, - onEmojiSelected: (String) -> Unit, -) = EmojiPickerView(context).apply { - emojiGridColumns = if (isPortrait) 9 else 18 - setOnEmojiPickedListener { selection -> onEmojiSelected(selection.emoji) } -} - @CombinedThemePreviews @Composable private fun MessageOptionsBottomSheetPreview() { OriginalTempTheme(isDark = isSystemInDarkTheme()) { MessageOptionsBottomSheet( onReactionClicked = {}, + onMoreReactionsClicked = {}, actions = listOf(), + messageId = -1L, ) } } diff --git a/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheetTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheetTest.kt index 1391b0eec0..47f677ed0b 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheetTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/meeting/chat/view/sheet/MessageOptionsBottomSheetTest.kt @@ -35,7 +35,9 @@ class MessageOptionsBottomSheetTest { composeRule.setContent { MessageOptionsBottomSheet( onReactionClicked = {}, + onMoreReactionsClicked = {}, actions = emptyList(), + messageId = -1L, ) } } diff --git a/gradle/catalogs/androidx.versions.toml b/gradle/catalogs/androidx.versions.toml index a453e3a1a1..48be9cb82a 100644 --- a/gradle/catalogs/androidx.versions.toml +++ b/gradle/catalogs/androidx.versions.toml @@ -13,7 +13,7 @@ compose-compiler = "1.5.15" compose-viewmodel = "2.8.4" datastore = "1.1.1" documentfile = "1.0.1" -emoji = "1.4.0" +emoji = "1.5.0" exifinterface = "1.3.7" fragment = "1.8.0" hilt-android = "1.2.0" diff --git a/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/chat/MegaEmojiPickerView.kt b/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/chat/MegaEmojiPickerView.kt index 5639e0bce0..40304c1d2a 100644 --- a/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/chat/MegaEmojiPickerView.kt +++ b/shared/original-core-ui/src/main/java/mega/privacy/android/shared/original/core/ui/controls/chat/MegaEmojiPickerView.kt @@ -43,29 +43,6 @@ fun MegaEmojiPickerView( ) } -/** - * Emoji picker view. - */ -@Composable -fun MegaEmojiPickerView( - showEmojiPicker: Boolean = true, - preloadedPicker: EmojiPickerView, - modifier: Modifier, -) = Column { - AndroidView( - modifier = modifier - .fillMaxWidth() - .background(MegaOriginalTheme.colors.background.pageBackground) - .testTag(TEST_TAG_EMOJI_PICKER_VIEW), - factory = { - preloadedPicker - }, - update = { view: EmojiPickerView -> - view.isVisible = showEmojiPicker - }, - ) -} - /** * Tag used to identify the emoji picker view. */ From a87bb0e3789986ded8fef2a0260844644026fd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Thu, 12 Sep 2024 00:41:16 +1200 Subject: [PATCH 236/261] T17791760 App in foreground - received a chat message --- .gitleaksignore | 2 ++ .../java/mega/privacy/android/app/fcm/PushMessageWorker.kt | 3 ++- .../app/globalmanagement/MegaChatNotificationHandler.kt | 2 +- .../mega/privacy/android/app/fcm/PushMessageWorkerTest.kt | 5 ++--- .../mega/privacy/android/data/facade/MegaChatApiFacade.kt | 7 ++----- .../privacy/android/data/gateway/api/MegaChatApiGateway.kt | 3 +-- .../android/data/repository/DefaultPushesRepository.kt | 4 ++-- .../privacy/android/domain/repository/PushesRepository.kt | 4 +--- .../domain/usecase/notifications/PushReceivedUseCase.kt | 5 +---- 9 files changed, 14 insertions(+), 21 deletions(-) diff --git a/.gitleaksignore b/.gitleaksignore index 8ecc09682d..2c46c8de74 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -222,6 +222,8 @@ app/agconnect-services.json:generic-api-key:6 app/src/main/java/mega/privacy/android/app/MegaApplication.java:generic-api-key:69 app/src/main/java/mega/privacy/android/app/DatabaseHandler.java:hashicorp-tf-password:41 app/google-services.json:gcp-api-key:24 +feature/sync/src/main/java/mega/privacy/android/feature/sync/domain/usecase/sync/worker/StartSyncWorkerUseCase.kt:etsy-access-token:14 +feature/sync/src/test/java/mega/privacy/android/feature/sync/domain/usecase/worker/StartSyncWorkerUseCaseTest.kt:etsy-access-token:20 src/nz/mega/android/utils/Util.java:generic-api-key:103 src/nz/mega/android/FortumoPayment.java:generic-api-key:28 src/nz/mega/android/MegaApplication.java:generic-api-key:39 diff --git a/app/src/main/java/mega/privacy/android/app/fcm/PushMessageWorker.kt b/app/src/main/java/mega/privacy/android/app/fcm/PushMessageWorker.kt index eb2dfcc259..b610d0f9eb 100644 --- a/app/src/main/java/mega/privacy/android/app/fcm/PushMessageWorker.kt +++ b/app/src/main/java/mega/privacy/android/app/fcm/PushMessageWorker.kt @@ -131,8 +131,9 @@ class PushMessageWorker @AssistedInject constructor( } runCatching { - pushReceivedUseCase(shouldBeep, chatId) + pushReceivedUseCase(shouldBeep) }.onSuccess { + Timber.d("Push received success chatID: $chatId msgId:$msgId") if (!isChatNotifiableUseCase(chatId) || !areNotificationsEnabled()) return@with diff --git a/app/src/main/java/mega/privacy/android/app/globalmanagement/MegaChatNotificationHandler.kt b/app/src/main/java/mega/privacy/android/app/globalmanagement/MegaChatNotificationHandler.kt index 0f8ae952a3..ea39dd1d14 100644 --- a/app/src/main/java/mega/privacy/android/app/globalmanagement/MegaChatNotificationHandler.kt +++ b/app/src/main/java/mega/privacy/android/app/globalmanagement/MegaChatNotificationHandler.kt @@ -104,7 +104,7 @@ class MegaChatNotificationHandler @Inject constructor( applicationScope.launch { runCatching { - pushReceivedUseCase(shouldBeep, chatId) + pushReceivedUseCase(shouldBeep) }.onSuccess { if (!isChatNotifiableUseCase(chatId) || !areNotificationsEnabled()) return@launch diff --git a/app/src/test/java/mega/privacy/android/app/fcm/PushMessageWorkerTest.kt b/app/src/test/java/mega/privacy/android/app/fcm/PushMessageWorkerTest.kt index 86115e3715..83cea7c3b0 100644 --- a/app/src/test/java/mega/privacy/android/app/fcm/PushMessageWorkerTest.kt +++ b/app/src/test/java/mega/privacy/android/app/fcm/PushMessageWorkerTest.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest -import mega.privacy.android.app.fcm.PushMessageWorker import mega.privacy.android.app.notifications.ChatMessageNotificationManager import mega.privacy.android.app.notifications.PromoPushNotificationManager import mega.privacy.android.app.notifications.ScheduledMeetingPushMessageNotificationManager @@ -141,7 +140,7 @@ class PushMessageWorkerTest { @Test fun `test that retryPendingConnections is invoked if fast login success`() = runTest { whenever(backgroundFastLoginUseCase()).thenReturn("good_session") - whenever(pushReceivedUseCase.invoke(any(), any())).thenReturn(Unit) + whenever(pushReceivedUseCase.invoke(any())).thenReturn(Unit) underTest.doWork() verify(retryPendingConnectionsUseCase).invoke(false) @@ -186,7 +185,7 @@ class PushMessageWorkerTest { runTest { val push = PushMessage.ChatPushMessage(true, 1L, 2L) whenever(pushMessageMapper(any())).thenReturn(push) - whenever(pushReceivedUseCase(push.shouldBeep, push.chatId)).thenReturn(Unit) + whenever(pushReceivedUseCase(push.shouldBeep)).thenReturn(Unit) whenever(isChatNotifiableUseCase(push.chatId)).thenReturn(false) val result = underTest.doWork() diff --git a/data/src/main/java/mega/privacy/android/data/facade/MegaChatApiFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/MegaChatApiFacade.kt index e3c74e128c..13e1701da1 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/MegaChatApiFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/MegaChatApiFacade.kt @@ -71,11 +71,8 @@ internal class MegaChatApiFacade @Inject constructor( override fun removeChatRequestListener(listener: MegaChatRequestListenerInterface) = chatApi.removeChatRequestListener(listener) - override fun pushReceived( - beep: Boolean, - chatId: Long, - listener: MegaChatRequestListenerInterface?, - ) = chatApi.pushReceived(beep, chatId, listener) + override fun pushReceived(beep: Boolean, listener: MegaChatRequestListenerInterface?) = + chatApi.pushReceived(beep, listener) override fun retryPendingConnections( disconnect: Boolean, diff --git a/data/src/main/java/mega/privacy/android/data/gateway/api/MegaChatApiGateway.kt b/data/src/main/java/mega/privacy/android/data/gateway/api/MegaChatApiGateway.kt index e5155f8497..c13b693664 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/api/MegaChatApiGateway.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/api/MegaChatApiGateway.kt @@ -86,10 +86,9 @@ interface MegaChatApiGateway { * Notifies a push has been received. * * @param beep True if should beep, false otherwise. - * @param chatId Chat identifier. * @param listener Listener. */ - fun pushReceived(beep: Boolean, chatId: Long, listener: MegaChatRequestListenerInterface?) + fun pushReceived(beep: Boolean, listener: MegaChatRequestListenerInterface?) /** * Refreshes DNS servers and retries pending connections. diff --git a/data/src/main/java/mega/privacy/android/data/repository/DefaultPushesRepository.kt b/data/src/main/java/mega/privacy/android/data/repository/DefaultPushesRepository.kt index cc6c56dfc7..ab2974b994 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/DefaultPushesRepository.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/DefaultPushesRepository.kt @@ -73,7 +73,7 @@ internal class DefaultPushesRepository @Inject constructor( .apply() } - override suspend fun pushReceived(beep: Boolean, chatId: Long) = + override suspend fun pushReceived(beep: Boolean) = withContext(ioDispatcher) { suspendCancellableCoroutine { continuation -> val listener = OptionalMegaChatRequestListenerInterface( @@ -86,7 +86,7 @@ internal class DefaultPushesRepository @Inject constructor( } } ) - megaChatApi.pushReceived(beep, chatId, listener) + megaChatApi.pushReceived(beep, listener) continuation.invokeOnCancellation { megaChatApi.removeRequestListener(listener) } } diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/repository/PushesRepository.kt b/domain/src/main/kotlin/mega/privacy/android/domain/repository/PushesRepository.kt index f89244a5a7..c16ce3d042 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/repository/PushesRepository.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/repository/PushesRepository.kt @@ -1,7 +1,6 @@ package mega.privacy.android.domain.repository import kotlinx.coroutines.flow.Flow -import mega.privacy.android.domain.entity.ChatRequest /** * Pushes repository. @@ -35,10 +34,9 @@ interface PushesRepository { * Notifies a push has been received. * * @param beep True if should beep, false otherwise. - * @param chatId Chat identifier. * @return Result of the request. Required for creating the notification. */ - suspend fun pushReceived(beep: Boolean, chatId: Long) + suspend fun pushReceived(beep: Boolean) /** * Clear push token diff --git a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/notifications/PushReceivedUseCase.kt b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/notifications/PushReceivedUseCase.kt index e8c72940a5..b611c9e9b4 100644 --- a/domain/src/main/kotlin/mega/privacy/android/domain/usecase/notifications/PushReceivedUseCase.kt +++ b/domain/src/main/kotlin/mega/privacy/android/domain/usecase/notifications/PushReceivedUseCase.kt @@ -1,6 +1,5 @@ package mega.privacy.android.domain.usecase.notifications -import mega.privacy.android.domain.entity.ChatRequest import mega.privacy.android.domain.repository.PushesRepository import javax.inject.Inject @@ -15,9 +14,7 @@ class PushReceivedUseCase @Inject constructor( * Invoke * * @param beep True if should beep, false otherwise. - * @param chatId Chat identifier. * @return Result of the request. Required for creating the notification. */ - suspend operator fun invoke(beep: Boolean, chatId: Long) = - pushesRepository.pushReceived(beep, chatId) + suspend operator fun invoke(beep: Boolean) = pushesRepository.pushReceived(beep) } \ No newline at end of file From f4b186c6be01d382351ec2bd1cd33d017d725cf4 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Wed, 11 Sep 2024 15:56:56 +0200 Subject: [PATCH 237/261] Update strings (cherry picked from commit 78a438ee634ae58767b141aab5a7b81a657bade9) --- app/src/main/res/values-es/strings.xml | 10 +++++----- app/src/main/res/values-pt/strings.xml | 4 ++-- .../src/main/res/values-de/strings_shared.xml | 6 +++--- .../src/main/res/values-es/strings_shared.xml | 6 +++--- .../src/main/res/values-nl/strings_shared.xml | 2 +- .../src/main/res/values-th/strings_shared.xml | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 81f9ffe197..f134387846 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -183,7 +183,7 @@ Las contraseñas no coinciden - This email address has already signed up for an account with MEGA + Esta dirección de correo electrónico ya está asociada a una cuenta en MEGA Conectando con el servidor: creando cuenta @@ -1400,7 +1400,7 @@ Cómo funciona - Invite your friends to sign up for a free MEGA account and to install a MEGA Mobile App. You will receive free storage as a bonus for every signup and app installation. + Invita a tus amigos a registrar una cuenta gratuita de MEGA e instalar nuestra aplicación móvil. Por cada registro e instalación de la aplicación, recibirás un bono adicional de almacenamiento. Bono de almacenamiento gratuito aplicable solo a usuarios nuevos que instalen la aplicación móvil o de escritorio de MEGA. @@ -2463,7 +2463,7 @@ Tus fotos en la nube - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + La función Subidas de la cámara es esencial para cualquier dispositivo móvil y nosotros la tenemos. Registra tu cuenta ahora. Introduce tu contraseña @@ -2557,7 +2557,7 @@ Iniciar sesión en MEGA - Sign up for a MEGA account + Registra una cuenta de MEGA Recientes @@ -3761,7 +3761,7 @@ Tu cuenta de MEGA ha sido suspendida debido a repetidas notificaciones de presuntas infracciones de derechos de autor. Como consecuencia, no podrás acceder a tu cuenta ni a tus datos.\nRevisa el correo electrónico que enviamos a tu dirección de correo para obtener más información sobre cómo presentar una contranotificación. - Your account was terminated due to a breach of MEGA’s Terms of Service.\nYou will not be able to regain access to your stored data or be authorised to sign up for a new MEGA account. + Hemos cerrado tu cuenta debido a un incumplimiento de los Términos de servicio de MEGA.\nNo podrás recuperar el acceso a tus datos ni estás autorizado a registrar una nueva cuenta de MEGA. Reuniones diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 20d6488df0..738735ca00 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -397,7 +397,7 @@ Item movido - Item movido para a lixeira + Item movido para a Lixeira Erro. Não foi movido @@ -3369,7 +3369,7 @@ Você está a ponto de excluir a sua pasta de backup. Ao fazer isso, serão removidos todos os backups que você configurou. Você tem certeza de que quer fazer isso? - Mover “%1s” à Lixeira + Mover “%1s” para a Lixeira Somente leitura diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 43c059ba8f..489b41d3a3 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -665,11 +665,11 @@ Schließen - Protect your calls + Schützen Sie Ihre Kommunikation - Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] + Ihre Meetings, Familiengespräche und privaten Unterhaltungen sind durch unsere Zero-Knowledge-Verschlüsselung geschützt. [A]Mehr erfahren[/A] - Message must be at least 10 characters + Die Nachricht muss mindestens 10 Zeichen lang sein Bitte Einzelheiten angeben diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 606a76f2f0..f0addeeec9 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -349,7 +349,7 @@ Añade contactos, crea tu propia red, colabora y haz llamadas y videollamadas sin salir de MEGA. - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + La función Subidas de la cámara es esencial para cualquier dispositivo móvil y nosotros la tenemos. Registra tu cuenta ahora. Reunión con cifrado de conocimiento cero. @@ -608,7 +608,7 @@ Describe el problema con al menos 10 caracteres - Keep conversations private + Mantén tus conversaciones privadas All your messages, group chats, and calls are protected by our zero-knowledge encryption. [A]Learn more[/A] @@ -616,7 +616,7 @@ Invite friends with confidence - With top-notch security and verification codes, reach out without fear of scams, data mining, or information theft + Con seguridad de primer nivel y códigos de verificación, comunícate sin temor a estafas, minería de datos o robo de información Invitar diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index e725d4cb0d..9c2914694c 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -669,7 +669,7 @@ Uw vergaderingen, familiegesprekken en privégesprekken worden beschermd door onze zero-knowledge codering. [A]Meer informatie[/A] - Message must be at least 10 characters + Het bericht moet minstens 10 tekens lang zijn Voer details in diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 0c185be426..21fa5c382a 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -153,7 +153,7 @@ ระยะเวลา - \’ระยะเวลาทั้งหมด + ระยะเวลาทั้งหมด น้อยกว่า 10 วินาที From 7bc2d8e27f0b5d8ccbd55cae3f94956db9c37fd5 Mon Sep 17 00:00:00 2001 From: Ilya Konnov Date: Thu, 12 Sep 2024 14:59:13 +0800 Subject: [PATCH 238/261] SAT-1564 Launch work manager only when feature toggle is on --- .../sync/domain/usecase/sync/worker/StartSyncWorkerTask.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/sync/src/main/java/mega/privacy/android/feature/sync/domain/usecase/sync/worker/StartSyncWorkerTask.kt b/feature/sync/src/main/java/mega/privacy/android/feature/sync/domain/usecase/sync/worker/StartSyncWorkerTask.kt index 94bca64a9e..d5e4174722 100644 --- a/feature/sync/src/main/java/mega/privacy/android/feature/sync/domain/usecase/sync/worker/StartSyncWorkerTask.kt +++ b/feature/sync/src/main/java/mega/privacy/android/feature/sync/domain/usecase/sync/worker/StartSyncWorkerTask.kt @@ -1,6 +1,8 @@ package mega.privacy.android.feature.sync.domain.usecase.sync.worker import mega.privacy.android.domain.usecase.appstart.AppStopTask +import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase +import mega.privacy.android.shared.sync.featuretoggles.SyncFeatures import javax.inject.Inject /** @@ -8,9 +10,12 @@ import javax.inject.Inject */ class StartSyncWorkerTask @Inject constructor( private val startSyncWorkerUseCase: StartSyncWorkerUseCase, + private val getFeatureFlagValueUseCase: GetFeatureFlagValueUseCase, ) : AppStopTask { override suspend fun invoke() { - startSyncWorkerUseCase() + if (getFeatureFlagValueUseCase(SyncFeatures.AndroidSyncWorkManager)) { + startSyncWorkerUseCase() + } } } \ No newline at end of file From fddb7c6e319418b8efefbea6e6b38425326a830b Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Fri, 13 Sep 2024 16:18:40 +0800 Subject: [PATCH 239/261] T17791576 AND - Cannot play videos after sliding in a chat 'shared files' --- .../app/mediaplayer/LegacyVideoPlayerViewModel.kt | 5 ++++- .../mediaplayer/service/AudioPlayerServiceViewModel.kt | 9 +++++---- .../mediaplayer/LegacyVideoPlayerViewModelTest.kt | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/LegacyVideoPlayerViewModel.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/LegacyVideoPlayerViewModel.kt index 40c4e458b8..08850a2682 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/LegacyVideoPlayerViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/LegacyVideoPlayerViewModel.kt @@ -25,6 +25,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import io.reactivex.rxjava3.disposables.CompositeDisposable import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -114,6 +115,7 @@ import mega.privacy.android.domain.entity.transfer.TransferEvent import mega.privacy.android.domain.exception.BlockedMegaException import mega.privacy.android.domain.exception.MegaException import mega.privacy.android.domain.exception.QuotaExceededMegaException +import mega.privacy.android.domain.qualifier.ApplicationScope import mega.privacy.android.domain.qualifier.IoDispatcher import mega.privacy.android.domain.usecase.GetBackupsNodeUseCase import mega.privacy.android.domain.usecase.GetLocalFilePathUseCase @@ -181,6 +183,7 @@ class LegacyVideoPlayerViewModel @Inject constructor( @ApplicationContext private val context: Context, @VideoPlayer private val mediaPlayerGateway: MediaPlayerGateway, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, + @ApplicationScope private val applicationScope: CoroutineScope, private val monitorTransferEventsUseCase: MonitorTransferEventsUseCase, private val playlistItemMapper: PlaylistItemMapper, private val trackPlaybackPositionUseCase: TrackPlaybackPositionUseCase, @@ -1717,7 +1720,7 @@ class LegacyVideoPlayerViewModel @Inject constructor( * Clear the state and flying task of this class, should be called in onDestroy. */ private fun clear() { - viewModelScope.launch { + applicationScope.launch { compositeDisposable.dispose() if (needStopStreamingServer) { diff --git a/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerServiceViewModel.kt b/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerServiceViewModel.kt index 894a72a1ec..067d1e41a4 100644 --- a/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerServiceViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/mediaplayer/service/AudioPlayerServiceViewModel.kt @@ -24,12 +24,12 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import mega.privacy.android.app.R -import mega.privacy.android.app.mediaplayer.gateway.AudioPlayerServiceViewModelGateway -import mega.privacy.android.app.mediaplayer.mapper.PlaylistItemMapper -import mega.privacy.android.app.mediaplayer.model.MediaPlaySources import mega.privacy.android.app.mediaplayer.MediaPlayerActivity.Companion.TYPE_NEXT import mega.privacy.android.app.mediaplayer.MediaPlayerActivity.Companion.TYPE_PLAYING import mega.privacy.android.app.mediaplayer.MediaPlayerActivity.Companion.TYPE_PREVIOUS +import mega.privacy.android.app.mediaplayer.gateway.AudioPlayerServiceViewModelGateway +import mega.privacy.android.app.mediaplayer.mapper.PlaylistItemMapper +import mega.privacy.android.app.mediaplayer.model.MediaPlaySources import mega.privacy.android.app.mediaplayer.playlist.PlaylistItem import mega.privacy.android.app.mediaplayer.playlist.finalizeItem import mega.privacy.android.app.mediaplayer.playlist.updateNodeName @@ -145,6 +145,7 @@ class AudioPlayerServiceViewModel @Inject constructor( private val monitorTransferEventsUseCase: MonitorTransferEventsUseCase, @ApplicationScope private val sharingScope: CoroutineScope, @IoDispatcher private val ioDispatcher: CoroutineDispatcher, + @ApplicationScope private val applicationScope: CoroutineScope, private val playlistItemMapper: PlaylistItemMapper, private val megaApiFolderHttpServerIsRunningUseCase: MegaApiFolderHttpServerIsRunningUseCase, private val megaApiFolderHttpServerStartUseCase: MegaApiFolderHttpServerStartUseCase, @@ -1330,7 +1331,7 @@ class AudioPlayerServiceViewModel @Inject constructor( } override fun clear() { - sharingScope.launch { + applicationScope.launch { compositeDisposable.dispose() if (needStopStreamingServer) { diff --git a/app/src/test/java/mega/privacy/android/app/presentation/mediaplayer/LegacyVideoPlayerViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/mediaplayer/LegacyVideoPlayerViewModelTest.kt index 533e68f79c..e9f139ebad 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/mediaplayer/LegacyVideoPlayerViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/mediaplayer/LegacyVideoPlayerViewModelTest.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.media3.common.MediaItem import app.cash.turbine.test import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf @@ -149,7 +150,8 @@ internal class LegacyVideoPlayerViewModelTest { getThumbnailUseCase = getThumbnailUseCase, getOfflineNodeInformationByIdUseCase = getOfflineNodeInformationByIdUseCase, saveVideoRecentlyWatchedUseCase = saveVideoRecentlyWatchedUseCase, - getFileUriUseCase = getFileUriUseCase + getFileUriUseCase = getFileUriUseCase, + applicationScope = CoroutineScope(UnconfinedTestDispatcher()), ) savedStateHandle[underTest.subtitleDialogShowKey] = false savedStateHandle[underTest.subtitleShowKey] = false From 0362334c5680aefa843ad23185451bc03f059584 Mon Sep 17 00:00:00 2001 From: Yenel Date: Fri, 13 Sep 2024 15:25:42 +0200 Subject: [PATCH 240/261] TRAN-551 Uploading by sharing from another app results in wrong modified date --- .../mega/privacy/android/app/ShareInfo.java | 16 +++++++++++- .../privacy/android/data/facade/FileFacade.kt | 25 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/ShareInfo.java b/app/src/main/java/mega/privacy/android/app/ShareInfo.java index 32e6b34a66..ddebc4963e 100644 --- a/app/src/main/java/mega/privacy/android/app/ShareInfo.java +++ b/app/src/main/java/mega/privacy/android/app/ShareInfo.java @@ -489,11 +489,25 @@ private void processContent(Uri uri, Context context) { } } } - int lastModifiedIndex = cursor.getColumnIndex("last_modified"); + int lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED); if (lastModifiedIndex != -1) { this.lastModified = cursor.getLong(lastModifiedIndex); } + if (lastModified == 0) { + lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED); + if (lastModifiedIndex != -1) { + this.lastModified = cursor.getLong(lastModifiedIndex); + } + } + + if (lastModified == 0) { + lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_TAKEN); + if (lastModifiedIndex != -1) { + this.lastModified = cursor.getLong(lastModifiedIndex); + } + } + if (size == -1 || inputStream == null) { Timber.d("Keep going"); int dataIndex = cursor.getColumnIndex("_data"); diff --git a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt index 3bd6d7bc5b..1fae39b62b 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt @@ -15,7 +15,9 @@ import android.os.StatFs import android.provider.DocumentsContract import android.provider.MediaStore import android.provider.MediaStore.MediaColumns.DATA +import android.provider.MediaStore.MediaColumns.DATE_ADDED import android.provider.MediaStore.MediaColumns.DATE_MODIFIED +import android.provider.MediaStore.MediaColumns.DATE_TAKEN import android.provider.MediaStore.MediaColumns.DISPLAY_NAME import android.provider.MediaStore.MediaColumns.SIZE import android.provider.MediaStore.VOLUME_EXTERNAL @@ -442,15 +444,34 @@ internal class FileFacade @Inject constructor( } } - private suspend fun copyFile(sourceFile: DocumentFile, targetFile: File) { + private fun copyFile(sourceFile: DocumentFile, targetFile: File) { context.contentResolver.openInputStream(sourceFile.uri)?.use { inputStream -> targetFile.outputStream().use { output -> inputStream.copyTo(output) } - targetFile.setLastModified(sourceFile.lastModified()) + (sourceFile.lastModified().takeIf { it > 0 } + ?: getLastModifiedFromContentResolver(sourceFile.uri)).let { lastModified -> + lastModified.takeIf { it > 0 }?.let { + targetFile.setLastModified(lastModified) + } + } } } + private fun getLastModifiedFromContentResolver(uri: Uri) = + context.contentResolver.acquireContentProviderClient(uri) + ?.use { client -> + client.query(uri, null, null, null, null) + ?.use { cursor -> + cursor.moveToFirst() + val index = cursor.getColumnIndex(DATE_MODIFIED).takeIf { it != -1 } + ?: cursor.getColumnIndex(DATE_ADDED).takeIf { it != -1 } + ?: cursor.getColumnIndex(DATE_TAKEN).takeIf { it != -1 } + ?: 0 + index.takeIf { it != 0 }?.let { cursor.getLong(it) } + } ?: 0 + } ?: 0 + override fun downscaleImage(file: File, destination: File, maxPixels: Long) { val orientation = AndroidGfxProcessor.getExifOrientation(file.absolutePath) val fileRect = AndroidGfxProcessor.getImageDimensions(file.absolutePath, orientation) From 6242742c368517d7ca9bac8c90b195ce7f24fdb5 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Mon, 16 Sep 2024 10:22:51 +0200 Subject: [PATCH 241/261] Update strings --- app/src/main/res/values-ar/strings.xml | 12 ++-- app/src/main/res/values-de/strings.xml | 12 ++-- app/src/main/res/values-es/strings.xml | 10 +-- app/src/main/res/values-fr/strings.xml | 12 ++-- app/src/main/res/values-in/strings.xml | 8 +-- app/src/main/res/values-it/strings.xml | 12 ++-- app/src/main/res/values-ja/strings.xml | 12 ++-- app/src/main/res/values-ko/strings.xml | 12 ++-- app/src/main/res/values-nl/strings.xml | 12 ++-- app/src/main/res/values-pl/strings.xml | 12 ++-- app/src/main/res/values-pt/strings.xml | 12 ++-- app/src/main/res/values-ro/strings.xml | 10 +-- app/src/main/res/values-ru/strings.xml | 12 ++-- app/src/main/res/values-th/strings.xml | 12 ++-- app/src/main/res/values-vi/strings.xml | 24 +++---- app/src/main/res/values-zh-rCN/strings.xml | 22 +++--- app/src/main/res/values-zh-rTW/strings.xml | 10 +-- .../res/values-vi/strings_sync_feature.xml | 4 +- .../src/main/res/values-ar/strings_shared.xml | 16 +++++ .../src/main/res/values-de/strings_shared.xml | 16 +++++ .../src/main/res/values-es/strings_shared.xml | 16 +++++ .../src/main/res/values-fr/strings_shared.xml | 16 +++++ .../src/main/res/values-in/strings_shared.xml | 68 ++++++++++++------- .../src/main/res/values-it/strings_shared.xml | 16 +++++ .../src/main/res/values-ja/strings_shared.xml | 18 ++++- .../src/main/res/values-ko/strings_shared.xml | 16 +++++ .../src/main/res/values-nl/strings_shared.xml | 16 +++++ .../src/main/res/values-pl/strings_shared.xml | 16 +++++ .../src/main/res/values-pt/strings_shared.xml | 16 +++++ .../src/main/res/values-ro/strings_shared.xml | 16 +++++ .../src/main/res/values-ru/strings_shared.xml | 16 +++++ .../src/main/res/values-th/strings_shared.xml | 16 +++++ .../src/main/res/values-vi/strings_shared.xml | 48 ++++++++----- .../main/res/values-zh-rCN/strings_shared.xml | 26 +++++-- .../main/res/values-zh-rTW/strings_shared.xml | 16 +++++ .../src/main/res/values/strings_shared.xml | 16 +++++ 36 files changed, 446 insertions(+), 158 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 79a0335b38..2e4e54e9f2 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -143,7 +143,7 @@ جديد في ميغا MEGA؟ - إنشاء حساب + قم بإنشاء حساب ميغا MEGA أدخل بريدك الإلكتروني @@ -169,7 +169,7 @@ قم بتسجيل الدخول للمشاركة مع ميغا MEGA - رابط التأكيد خاصتك لم يعد صالحاً. قد يكون حسابك مفعلاً مسبقاً أو قد تكون قد ألغيت تسجيل حسابك. + رابط التأكيد الخاص بك لم يعد صالحًا. ربما تم تفعيل حسابك بالفعل أو ربما قمت بإلغاء اشتراكك. الاسم الأول @@ -1476,7 +1476,7 @@ تثبيت تطبيق ميغا MEGA mobile - مكافآت التسجيل + مكافأة الاشتراك قم بتثبيت تطبيق ميغا للحاسوب المكتبي MEGA Desktop @@ -1506,7 +1506,7 @@ لقد تلقيت %1$s من مساحة تخزين لتثبيتك تطبيق ميغا للهاتف المحمول MEGA mobile. - لقد تلقيت %1$s من مساحة تخزين كمكافأة تسجيل مجانية. + You have received %1$s storage space as your free signup bonus. مجلد مشارك @@ -2074,7 +2074,7 @@ انقر للانضمام الى المكالمة - دعوة جهات الاتصال + ادعو مشاركة مع @@ -2115,7 +2115,7 @@ تفعيل أو تعطيل النسخ المعدلة للملفات لكامل حسابك.\nتعطيل ميزة النسخ المعدلة للملفات لا تمنع جهات الاتصال الخاصة بك من إنشاء نسخ جديدة في الملفات المشاركة. - انقر و ادخل الاسم أو عنوان البريد الالكتروني + Search contacts or type email address هل تريد إضافة %s الى جهات الاتصال خاصتك؟ diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index bbd020ec8b..c88fd6707e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -135,7 +135,7 @@ Neu bei MEGA? - Account erstellen + MEGA-Account erstellen Ihre E-Mail-Adresse @@ -161,7 +161,7 @@ Einloggen, um Freigaben in MEGA zu erstellen - Der Bestätigungslink ist nicht mehr gültig. Entweder haben Sie Ihren Account bereits aktiviert, oder die Registrierung wurde abgebrochen. + Ihr Bestätigungslink ist nicht mehr gültig. Möglicherweise ist Ihr Account bereits aktiviert oder Sie haben Ihre Registrierung abgebrochen. Vorname(n) @@ -1356,7 +1356,7 @@ MEGA-Mobil-App installieren - Anmeldebonus + Registrierungsbonus MEGA-Desktop-App installieren @@ -1386,7 +1386,7 @@ Sie haben %1$s Extraspeicherplatz für die Installation der MEGA-Mobil-App erhalten. - Sie haben %1$s Speicherplatz als Bonus für Ihre Anmeldung erhalten. + Sie haben %1$s Speicherplatz als kostenlosen Registrierungsbonus erhalten. Ordner freigeben @@ -1902,7 +1902,7 @@ Konferenz beitreten - Kontaktanfragen verschicken + Einladen Freigeben an @@ -1939,7 +1939,7 @@ Dateiversionierung für den gesamten Account ein- und ausschalten.\nDas Ausschalten der Dateiversionierung hindert Ihre Kontakte nicht daran, in Ordnerfreigaben neue Versionen zu erstellen. - Antippen und Namen oder E-Mail-Adresse eingeben + Kontakte durchsuchen oder E-Mail-Adresse eingeben %s zu Ihren Kontakten hinzufügen? diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index f134387846..bd52e3b8cc 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -137,7 +137,7 @@ ¿Nuevo en MEGA? - Crear cuenta + Crea una cuenta de MEGA Introduce tu email @@ -1386,7 +1386,7 @@ Instala la app móvil de MEGA - Bono por registro de cuenta + Signup bonus Instala una aplicación de escritorio de MEGA @@ -1416,7 +1416,7 @@ Has obtenido %1$s de espacio de almacenamiento por instalar la aplicación de MEGA para móvil. - Has obtenido %1$s de espacio de almacenamiento por haberte registrado. + You have received %1$s storage space as your free signup bonus. Compartir carpeta @@ -1945,7 +1945,7 @@ Toca para unirte a la llamada - Invitar contactos + Invitar Compartir con @@ -1983,7 +1983,7 @@ Activa o desactiva el control de versiones de archivos para toda tu cuenta.\nDesactivar el control de versiones no impedirá que tus contactos creen nuevas versiones en carpetas compartidas. - Toca, introduce el nombre o el correo electrónico + Search contacts or type email address ¿Añadir a %s a tus contactos? diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a965594fa3..f0ea102afc 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -137,7 +137,7 @@ Première fois sur MEGA ? - Créer un compte + Créer un compte MEGA Saisissez votre adresse courriel @@ -163,7 +163,7 @@ Connectez-vous pour partager avec MEGA - Votre lien de confirmation n’est plus valide. Votre compte est peut-être déjà activé ou vous avez peut-être annulé votre inscription. + Votre lien de confirmation n\’est plus valide. Votre compte est peut-être déjà activé ou vous avez peut-être annulé votre inscription. Prénom @@ -1386,7 +1386,7 @@ Installer une Appli MEGA Mobile - Prime d’inscription + Prime d\’inscription Installer une Appli MEGA pour ordinateur @@ -1416,7 +1416,7 @@ Vous avez reçu %1$s d’espace de stockage pour avoir installé l’Appli MEGA Mobile. - Vous avez reçu %1$s d’espace de stockage comme prime gratuite d’inscription. + Vous avez reçu %1$s d’espace de stockage supplémentaire comme prime d’inscription. Partager un dossier @@ -1945,7 +1945,7 @@ Touchez pour vous joindre à l’appel - Inviter des contacts + Inviter Partager avec @@ -1983,7 +1983,7 @@ Activez ou désactivez le versionnage des fichiers pour votre compte entier.\nDésactiver le versionnage des fichiers n’empêche pas vos contacts de créer de nouvelles versions dans les dossiers partagés. - Touchez, saisissez un nom ou une adresse courriel + Recherchez vos contacts ou saisissez une adresse courriel Ajouter %s à vos contacts ? diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 297a6da6dc..e85520c605 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -133,7 +133,7 @@ Baru di MEGA? - Buat akun + Buat akun MEGA Masukkan email anda @@ -1356,7 +1356,7 @@ Anda telah menerima %1$s ruang penyimpanan untuk menginstal Aplikasi Seluler MEGA. - Anda telah menerima ruang penyimpanan %1$s sebagai bonus pendaftaran gratis anda. + Anda telah menerima %1$s ruang penyimpanan sebagai bonus pendaftaran gratis anda. Bagikan folder @@ -1859,7 +1859,7 @@ Ketuk untuk bergabung dengan panggilan - Undang kontak + Undang Berbagi dengan @@ -1895,7 +1895,7 @@ Aktifkan atau nonaktifkan versi file untuk seluruh akun anda.\nAnda masih dapat menerima versi file dari folder bersama jika kontak anda telah mengaktifkan ini. - Ketuk, masukkan nama atau alamat email + Cari kontak atau ketik alamat email Tambahkan %s ke kontak anda? diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8d36fe7939..09c1a7834c 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -137,7 +137,7 @@ Nuovo su MEGA? - Crea account + Crea un account MEGA Inserisci la tua email @@ -163,7 +163,7 @@ Accedi per condividere con MEGA - Il tuo link di conferma non è più valido. Il tuo account potrebbe essere stato già attivato o potresti aver annullato la tua registrazione. + Your confirmation link is no longer valid. Your account may already be activated or you may have cancelled your signup. Nome @@ -1386,7 +1386,7 @@ Installa la nostra app - Bonus di registrazione + Signup bonus Installa un’app per desktop di MEGA @@ -1416,7 +1416,7 @@ Hai ricevuto %1$s di spazio di archiviazione per aver installato l\’app per mobile di MEGA. - Hai ricevuto %1$s di spazio di archiviazione gratuito come bonus per la tua registrazione. + You have received %1$s storage space as your free signup bonus. Condividi cartella @@ -1945,7 +1945,7 @@ Tocca per unirti alla chiamata - Invita contatti + Invita Condividi con @@ -1983,7 +1983,7 @@ Attiva o disattiva le versioni dei file per il tuo account.\nDisabilitare le versioni dei file non esclude che i tuoi contatti creino nuove versioni nelle cartelle condivise. - Tocca, inserisci nome o indirizzo email + Search contacts or type email address Aggiungere %s ai tuoi contatti? diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index a097579c1c..bc4f502fb1 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -133,7 +133,7 @@ MEGAは初めてですか? - アカウントを作成する + サインアップ メールアドレスを入力 @@ -159,7 +159,7 @@ MEGAと共有するにはログインしてください - あなたの確認リンクはもう有効ではありません。あなたのアカウントは既に有効になっているか、登録をキャンセルしたかもしれません。 + 確認リンクは無効になりました。あなたのアカウントはすでに有効になっているか、サインアップをキャンセルしている可能性があります。 名前 @@ -1326,7 +1326,7 @@ 当社のモバイルアプリをインストール - ご登録ボーナス + サインアップボーナス MEGAデスクトップアプリをインストール @@ -1356,7 +1356,7 @@ あなたはMEGAモバイルアプリのインストールに対して、%1$sのストレージスペースを受け取りました。 - あなたは無料登録ボーナスとして%1$sのストレージスペースを受け取りました。 + 無料サインアップボーナスとして%1$sのストレージスペースを受け取りました。 フォルダを共有 @@ -1859,7 +1859,7 @@ 通話に参加するにはタップします - 連絡先を招待 + 招待 共有先 @@ -1895,7 +1895,7 @@ あなたの全アカウントを対象にファイルのバージョン管理を有効または無効にします。\nファイルのバージョン管理を無効にしても、あなたの連絡先が共有フォルダで新しいバージョンを作成するのを妨げません。 - タップして名前またはメールアドレスを入力 + 連絡先を検索するか、メールアドレスを入力してください 連絡先に%sさんを追加しますか? diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index e5668975b5..6d29b3ab53 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -133,7 +133,7 @@ MEGA가 처음이신가요? - 계정 생성 + MEGA 계정 생성 이메일을 입력하세요 @@ -159,7 +159,7 @@ MEGA로 공유하려면 로그인하세요 - 확인 링크가 더 이상 유효하지 않습니다. 계정이 이미 활성화되었거나 가입을 취소했을 수 있습니다. + Your confirmation link is no longer valid. Your account may already be activated or you may have cancelled your signup. 이름 @@ -1326,7 +1326,7 @@ MEGA 모바일 앱 설치 - 가입 보너스 + Signup bonus MEGA 데스크톱 앱 설치 @@ -1356,7 +1356,7 @@ MEGA 모바일 앱을 설치하여 저장소 공간 %1$s를 받았습니다. - 당신은 무료 가입 보너스로 %1$s의 저장 공간을 받았습니다. + You have received %1$s storage space as your free signup bonus. 폴더 공유 @@ -1859,7 +1859,7 @@ 통화에 참여하려면 탭하세요 - 연락처 초대 + 초대 다른 사람과 공유 @@ -1895,7 +1895,7 @@ 계정 전체에 대한 파일 버전 관리를 활성화하거나 비활성화 합니다.\n파일 버전 관리를 해제하는 것이 연락처가 공유된 폴더에 새로운 버전을 만드는 것을 막을 수 없습니다. - 탭하고, 이름 또는 이메일 주소를 입력하세요 + Search contacts or type email address %s을/를 연락처에 추가할까요? diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 59e7d3bea9..a2a52e0920 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -135,7 +135,7 @@ Nieuw bij MEGA? - Account Creëren + MEGA-account aanmaken Vul uw email in @@ -161,7 +161,7 @@ Log in om te delen met MEGA - Uw bevestigingslink is niet langer geldig. Uw account kan al geactiveerd zijn of u kunt uw registratie geannuleerd hebben. + Uw bevestigingslink is niet langer geldig. Uw account is mogelijk al geactiveerd of u heeft uw aanmelding geannuleerd. Voornaam @@ -1356,7 +1356,7 @@ Installeer een mobiele app - Registratie bonus + Inschrijfbonus Installeer een MEGA Desktop Applicatie @@ -1386,7 +1386,7 @@ U heeft %1$s opslagruimte gekregen voor het installeren van de MEGA Mobile Applicatie. - U heeft %1$s opslag ruimte ontvangen als uw gratis registratie bonus. + U heeft %1$s opslagruimte als gratis aanmeldingsbonus ontvangen. Map delen @@ -1902,7 +1902,7 @@ Tik om aan te sluiten bij de oproep - Contacten uitnodigen + Uitnodigen Delen met @@ -1939,7 +1939,7 @@ Versionering inschakelen of uitschakelen voor uw gehele account. \nVersionering uischakelen zorgt er niet voor dat uw contacten nieuwe versies kunnen creëren in gedeelde mappen. - Tik op, voer naam of e-mailadres in + Zoek contacten of typ een e-mailadres Wilt u %s tot uw contacten toevoegen? diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d5d7e464d7..b2d862a0ce 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -139,7 +139,7 @@ Pierwszy raz na MEGA? - Utwórz konto + Utwórz konto MEGA Wprowadź swój adres e-mail @@ -165,7 +165,7 @@ Zaloguj się, aby udostępnić MEGA - Twój link potwierdzający nie jest już ważny. Twoje konto może już być aktywne lub możesz anulować rejestrację. + Your confirmation link is no longer valid. Your account may already be activated or you may have cancelled your signup. Imię @@ -1416,7 +1416,7 @@ Zainstaluj aplikację mobilną - Zarejestruj bonus + Signup bonus Zainstaluj aplikację MEGA Desktop @@ -1446,7 +1446,7 @@ Otrzymałeś %1$s przestrzeni dyskowej za instalację MEGA Mobile App. - Otrzymałeś %1$s powierzchni na pliki jako bonus za rejestrację. + You have received %1$s storage space as your free signup bonus. Udostępnij katalog @@ -1988,7 +1988,7 @@ Kliknij, aby dołączyć do połączenia - Zaproś kontakty + Zaproszenie Udostępnij za pomocą @@ -2027,7 +2027,7 @@ Włącz lub wyłącz kontrolę wersji dla całego konta. \n Wyłączenie kontroli wersji nie uniemożliwia twojemu kontaktowi tworzenia nowych wersji w folderach współdzielonych. - Wybierz, wprowadź nazwę lub adres e-mail + Search contacts or type email address Dodać %s do swoich kontaktów? diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 738735ca00..90b36dde99 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -137,7 +137,7 @@ Novo no MEGA? - Criar conta + Criar uma conta no MEGA Digite o seu email @@ -163,7 +163,7 @@ Faça login para compartilhar com o MEGA - O seu link de confirmação já não é válido. A sua conta pode já estar ativa, ou você pode ter cancelado o seu registro. + O seu link de confirmação já não é válido. A sua conta pode já estar ativa, ou você pode ter cancelado o seu cadastro. Nome @@ -1386,7 +1386,7 @@ Instalar o nosso aplicativo para celular - Bônus de registro + Bônus de cadastro Instalar o app para desktop @@ -1416,7 +1416,7 @@ Você recebeu %1$s de espaço de armazenamento por instalar o aplicativo do MEGA para dispositivos móveis. - Você recebeu %1$s de espaço de armazenamento como bônus gratuito pelo seu registro. + Você recebeu %1$s de espaço de armazenamento como bônus por cadastrar uma conta. Compartilhar pasta @@ -1945,7 +1945,7 @@ Pressione para entrar na chamada - Adicione contatos + Convidar Compartilhar com @@ -1983,7 +1983,7 @@ Ativar ou desativar o controle das versões de arquivos na sua conta. \nDesativar o controle das versões de arquivos não impede que os seus contatos criem novas versões em pastas compartilhadas. - Digite o nome ou email + Pesquise entre os contatos ou digite um email Você quer adicionar %s aos seus contatos? diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index e9887a5c42..5b279dfab2 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -137,7 +137,7 @@ Ești utilizator nou pe MEGA? - Creează un cont + Creați un cont MEGA Introduceți adresa dvs. de e-mail @@ -1386,7 +1386,7 @@ Instalează o aplicație mobilă MEGA - Bonus de înregistrare + Bonus de înscriere Instalează Aplicația Desktop MEGA @@ -1416,7 +1416,7 @@ Ai primit %1$s spațiu de stocare pentru instalarea Aplicației Mobile MEGA. - Ai primit %1$s spațiu de stocare ca bonus de înregistrare gratuită. + Ați primit %1$s spațiu de stocare ca bonus de înscriere gratuit. Partajează folderul @@ -1945,7 +1945,7 @@ Atinge pentru a te alătura apelului - Invită contacte + Invitați Partajează cu @@ -1983,7 +1983,7 @@ Activează sau dezactivează versionarea fișierelor pentru întregul cont.\nDezactivarea versionării fișierelor nu împiedică contactele tale să creeze noi versiuni în folderele partajate. - Atingeți, introduceți numele sau adresa de e-mail + Căutați contacte sau tastați adresa de e-mail Adaugi pe %s la contacte? diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6f72f0c0e4..aaf015ae47 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -139,7 +139,7 @@ Впервые в MEGA? - Зарегистрироваться + Зарегистрироваться в MEGA Введите адрес электронной почты @@ -165,7 +165,7 @@ Для использования MEGA войдите в систему - Ссылка подтверждения более не действительна. Ваш аккаунт может быть уже активирован или вы могли отменить регистрацию. + Cсылка для подтверждения больше не действительна. Возможно, ваш аккаунт уже активирован или вы отменили регистрацию. Имя @@ -1416,7 +1416,7 @@ Установить мобильное приложение - Бонусы за регистрацию + Бонус за регистрацию Установить MEGA на ПК @@ -1446,7 +1446,7 @@ Вы получили %1$s места на диске за установку мобильного приложения MEGA. - При регистрации вы получаете %1$s места на диске в качестве бонуса. + За регистрацию вы получаете %1$s на диске в качестве бонуса. Поделиться папкой @@ -1988,7 +1988,7 @@ Коснитесь, чтобы присоединиться - Пригласить контакты + Пригласить Поделиться с @@ -2027,7 +2027,7 @@ Включите или отключите управление версиями файлов для всего аккаунта.\nОтключение версий файлов не запретит вашим контактам создавать новые версии в общих папках. - Коснитесь, введите имя или электронную почту + Ищите контакты или введите адрес электронной почты Добавить пользователя %s в контакты? diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index ea5ade5edd..5f5e9bef58 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -133,7 +133,7 @@ เป็นผู้ใช้ MEGA ใหม่ - สร้างบัญชี + สร้างบัญชี MEGA กรอกที่อยู่อีเมลของคุณ @@ -159,7 +159,7 @@ ลงชื่อเข้าใช้เพื่อแชร์กับ MEGA - ลิงก์ยืนยันของคุณใช้ไม่ได้อีกต่อไป บัญชีของคุณอาจถูกเปิดใช้งานหรือคุณอาจยกเลิกการลงทะเบียนแล้ว + Your confirmation link is no longer valid. Your account may already be activated or you may have cancelled your signup. ชื่อ @@ -1326,7 +1326,7 @@ ติดตั้งแอป MEGA บนมือถือ - โบนัสการลงทะเบียน + Signup bonus ติดตั้งแอปเดสก์ท็อป MEGA @@ -1356,7 +1356,7 @@ คุณได้รับพื้นที่จัดเก็บ %1$s จากการติดตั้งแอป MEGA บนมือถือ - คุณได้รับพื้นที่เก็บข้อมูลขนาด %1$s เป็นโบนัสการลงทะเบียนฟรีของคุณ + You have received %1$s storage space as your free signup bonus. แชร์โฟลเดอร์ @@ -1859,7 +1859,7 @@ แตะเพื่อเข้าร่วมการโทร - เชิญผู้ติดต่อ + เชิญ แชร์กับ @@ -1895,7 +1895,7 @@ เปิดหรือปิดใช้งานการกำหนดเวอร์ชันไฟล์สำหรับทั้งบัญชีของคุณ\nการปิดใช้งานการกำหนดเวอร์ชันไฟล์ ไม่ได้มีการป้องกันผู้ติดต่อของคุณเพื่อสร้างเวอร์ชันใหม่ในโฟลเดอร์ที่แชร์ - แตะ เพื่อกรอกชื่อหรืออีเมล + Search contacts or type email address เพิ่ม %s ในรายชื่อติดต่อของคุณหรือไม่ diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index ad0b17fb3b..82d9967584 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -133,7 +133,7 @@ Mới đến MEGA? - Tạo tài khoản + Tạo tài khoản MEGA Nhập địa chỉ email @@ -159,7 +159,7 @@ Đăng nhập để chia sẻ với MEGA - Liên kết xác nhận không còn hiệu lực. Tài khoản của có thể đã được kích hoạt rồi hoặc việc đăng ký đã bị hủy. + Đường liên kết xác nhận không còn hiệu lực. Tài khoản của bạn có thể đã được kích hoạt rồi hoặc việc đăng ký đã bị hủy. Tên @@ -179,7 +179,7 @@ Hai mật khẩu này không trùng khớp - This email address has already signed up for an account with MEGA + Địa chỉ email này đã có đăng ký tài khoản với MEGA rồi Đang kết nối đến máy chủ: Đang tạo tài khoản @@ -1326,7 +1326,7 @@ Cài đặt App MEGA cho Di Động - Thưởng tài khoản mới + Thưởng đăng ký Cài App MEGA cho Máy Tính @@ -1340,7 +1340,7 @@ Cách hoạt động - Invite your friends to sign up for a free MEGA account and to install a MEGA Mobile App. You will receive free storage as a bonus for every signup and app installation. + Mời bạn bè của bạn tạo một tài khoản MEGA miễn phí và cài đặt App MEGA cho Di Động. Bạn sẽ nhận được thêm không gian miễn phí thưởng cho mỗi lần bạn bè đăng ký và cài đặt ứng dụng. Phần thưởng không gian lưu trữ miễn phí chỉ có áp dụng cho những lời mời mới và khi App MEGA cho Di Động hoặc App MEGA cho Máy Tính được cài đặt. @@ -1356,7 +1356,7 @@ Bạn đã nhận được %1$s không gian lưu trữ từ việc cài ứng dụng MEGA cho Di Động. - Bạn đã nhận được %1$s không gian lưu trữ từ việc đăng ký tài khoản. + Bạn đã nhận được %1$s không gian lưu trữ thưởng cho việc đăng ký của bạn. Chia sẻ thư mục @@ -1859,7 +1859,7 @@ Chạm vào để tham gia cuộc gọi - Mời thêm tên liên lạc + Mời Chia sẻ với @@ -1895,7 +1895,7 @@ Kích hoạt hoặc tắt tính năng ghi nhật ký phiên bản tệp tin cho toàn bộ tài khoản.\nTắt đi tính năng ghi nhật ký phiên bản sẽ không ngăn cản các tên liên lạc trong tài khoản của bạn tạo ra phiên bản mới của thư mục chia sẻ chung. - Chạm để nhập tên hay địa chỉ email + Tìm kiếm danh bạ hoặc nhập địa chỉ email Thêm %s vào sổ liên lạc? @@ -2339,7 +2339,7 @@ Hình Ảnh được gửi lên mây - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + Đăng tải camêra là tính năng thiết yếu cho mọi thiết bị di động, và MEGA có cung cấp cho mọi người dùng. Tạo tài khoản ngay. Nhập mật khẩu @@ -2429,7 +2429,7 @@ Đăng nhập vào MEGA - Sign up for a MEGA account + Đăng ký tài khoản MEGA Gần Đây @@ -3569,7 +3569,7 @@ Tài khoản MEGA của quý vị đã bị đình chỉ do đã nhiều lần bị cáo buộc vi phạm bản quyền. Điều này có nghĩa là quý vị không được phép truy cập tài khoản của mình hoặc bất cứ dữ liệu bên trong.\nKiểm tra hộp thư email của quý vị để biết thêm thông tin và về cách gửi đơn phản đối. - Your account was terminated due to a breach of MEGA’s Terms of Service.\nYou will not be able to regain access to your stored data or be authorised to sign up for a new MEGA account. + Tài khoản của bạn đã bị chấm dứt do vi phạm Điều Khoản Dịch Vụ của MEGA. \nBạn sẽ không thể lấy lại quyền truy cập vào dữ liệu đã được lưu trữ của mình hoặc được phép đăng ký tài khoản MEGA mới. Họp @@ -4675,7 +4675,7 @@ Đã loại bỏ %1$d thành viên - Ứng dụng đã được cập nhật + Ứng dụng đã được cập nhật Khởi chạy lại ứng dụng diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index dff31abdc3..31692bad61 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -133,7 +133,7 @@ 还没有MEGA帐户? - 创建帐户 + 注册 请输入您的电子邮件地址 @@ -143,7 +143,7 @@ 无网络连接 - You’ve been logged out of this device from another location + 您已从其它位置登出此设备 正在生成加密密钥 @@ -159,7 +159,7 @@ 登入以使用MEGA共享 - 您的确认链接已失效。您的帐户可能已被激活或您可能已取消注册。 + 您的确认链接已失效。您的帐户可能已被激活,或者您可能已经取消注册。 @@ -179,7 +179,7 @@ 密码不匹配 - This email address has already signed up for an account with MEGA + 此电子邮件地址已注册MEGA帐户 正在连接到服务器:正在创建帐户 @@ -1340,7 +1340,7 @@ 如何运作 - Invite your friends to sign up for a free MEGA account and to install a MEGA Mobile App. You will receive free storage as a bonus for every signup and app installation. + 邀请您的朋友注册一个免费MEGA帐户并安装MEGA移动应用程序。每次完成注册并安装应用程序后,您都将获得免费存储空间作为奖励。 免费存储空间奖励仅适用于已安装MEGA手机应用程序或MEGA桌面应用程序的新邀请用户。 @@ -1356,7 +1356,7 @@ 您已通过安装MEGA手机应用程序获得了%1$s的存储空间。 - 您已收到%1$s的存储空间作为免费注册奖励。 + 您已收到%1$s存储空间作为您的免费注册奖励。 共享文件夹 @@ -1859,7 +1859,7 @@ 点击加入通话 - 邀请联系人 + 邀请 分享 @@ -1895,7 +1895,7 @@ 为整个帐户启用或禁用文件历史版本。\n禁用文件历史版本功能不会阻止您的联系人在共享文件夹中创建新版本。 - 点按,输入姓名或电子邮件地址 + 搜索联系人或键入电子邮件地址 将%s添加为您的联系人? @@ -2339,7 +2339,7 @@ 您在云盘的照片 - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + 相机上传是任何移动设备的必备功能,我们已经为您提供这项服务。立即注册一个帐户。 请输入您的密码 @@ -2429,7 +2429,7 @@ 登录MEGA - Sign up for a MEGA account + 注册一个MEGA帐户 近期 @@ -3569,7 +3569,7 @@ 由于多次被指控侵犯版权,您的MEGA帐户已被停用。这意味着您无法访问您的帐户或其中的数据。\n检查您的电子邮件收件箱,了解有关如何提交抗辩通知的更多信息。 - Your account was terminated due to a breach of MEGA’s Terms of Service.\nYou will not be able to regain access to your stored data or be authorised to sign up for a new MEGA account. + 您的帐户因违反MEGA的服务条款而被终止。\n您将无法重新获得对存储数据的访问权限,也无法获得注册新MEGA帐户的授权。 会议 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 485c59c239..c3cc98e620 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -133,7 +133,7 @@ 還沒有MEGA帳戶? - 建立帳戶 + 建立MEGA帳戶 請輸入您的電子信箱地址 @@ -159,7 +159,7 @@ 登入以使用MEGA進行共享 - 您的確認連結已無效。您的帳戶可能已啟用,或您可能已取消註冊 + 您的確認連結已失效。您的帳戶可能已啟用,或您可能已取消註冊。 名字 @@ -1356,7 +1356,7 @@ 您已經由安裝MEGA手機應用程式而獲得%1$s儲存空間獎勵。 - 您已經收到%1$s的儲存空間,這是免費的註冊獎勵喔。 + 您已收到%1$s儲存空間作為免費註冊的獎勵。 共享資料夾 @@ -1859,7 +1859,7 @@ 點擊即可加入通話 - 邀請聯絡人 + 邀請 與…共享 @@ -1895,7 +1895,7 @@ 啟用或停用您整個帳戶的檔案版本控制功能。\n停用檔案版本控制並不會讓您的聯絡人無法在共享資料夾建立新版本的檔案。 - 點選,輸入姓名或電子郵件地址 + 搜尋聯絡人或輸入電子郵件地址 將%s新增為您的聯絡人? diff --git a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml index 62f203cbed..4b8db89a16 100644 --- a/feature/sync/src/main/res/values-vi/strings_sync_feature.xml +++ b/feature/sync/src/main/res/values-vi/strings_sync_feature.xml @@ -73,9 +73,9 @@ Đã đồng bộ - Thư mục thiết bị + Thư mục thiết bị - Thư mục trên MEGA + Thư mục trên MEGA Th.tin vấn đề diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 48e5592fc5..d5039df1cb 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -722,4 +722,20 @@ أدخل التفاصيل احصل على مساحة تخزين سحابية مجانية + + ما الجديد + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + اعرف أكثر + + إلغاء + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 489b41d3a3..0e41f62997 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -674,4 +674,20 @@ Bitte Einzelheiten angeben Kostenlosen Cloudspeicher erhalten + + Das ist neu + + Einfache, automatische Synchronisierung + + Synchronisieren Sie Ordner auf Ihrem Gerät mit MEGA, um überall Zugriff auf die neuesten Versionen Ihrer Dateien zu haben + + Ordner synchronisieren + + Upgraden, um Synchronisierung zu verwenden + + Mehr erfahren + + Abbrechen + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index f0addeeec9..be88e862dc 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -683,4 +683,20 @@ Introducir motivo Obtén almacenamiento en la nube gratis + + Novedades + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Más información + + Cancelar + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 085c0a0a58..11acd12c58 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -686,4 +686,20 @@ Saisissez des détails Obtenir du stockage nuagique gratuit + + Nouveautés + + Synchronisation simple et automatique + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Synchroniser les dossiers + + Effectuer une mise à niveau pour utiliser la synchronisation + + En apprendre davantage + + Annuler + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 9b34a0b110..6183d57235 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -153,17 +153,17 @@ Durasi - All durations + Semua durasi - Less than 10 seconds + Kurang dari 10 detik - Between 10 and 60 seconds + Antara 10 dan 60 detik - Between 1 and 4 minutes + Antara 1 dan 4 menit - Between 4 and 20 minutes + Antara 4 dan 20 menit - More than 20 minutes + Lebih dari 20 menit Masukkan nama daftar putar @@ -171,7 +171,7 @@ A playlist with this name already exists. Enter a different name. - Delete playlist? + Hapus playlist? Hapus @@ -179,7 +179,7 @@ Hapus daftar putar - Remove from playlist? + Hapus dari playlist? Hapus @@ -390,9 +390,9 @@ Hanya Pro - Tags + Tag - Use tags to help you find and organise your data. Try tagging by year, location, project, or subject. + Gunakan tag untuk membantu anda menemukan dan mengatur data anda. Coba tag berdasarkan tahun, lokasi, proyek, atau subjek. Tag @@ -406,7 +406,7 @@ Tags must be %1$d characters or less - Tags + Tag Tidak ada deskripsi @@ -466,11 +466,11 @@ Maksimal 32 karakter - Hidden item + Item tersembunyi - This item is set to hidden. Once you share the item, anyone with the link will be able to see it. It will still be hidden in your Cloud drive. + Item ini diatur ke tersembunyi. Setelah anda membagikan item, siapa pun yang memiliki tautan akan dapat melihatnya. Itu masih akan disembunyikan di drive Cloud anda. - One or more of these items is set to hidden. Once you share the hidden items, anyone with the link will be able to see them. The items will still be hidden in your Cloud drive. + Satu atau lebih item ini diatur ke tersembunyi. Setelah anda membagikan item tersembunyi, siapa pun yang memiliki tautan akan dapat melihatnya. Item masih akan disembunyikan di drive Cloud anda. Batalkan Langganan @@ -508,7 +508,7 @@ 2. Masuk ke akun MEGA anda. - 3. Click the main menu. + 3. Klik menu utama. 4. Click [A]Settings.[/A] @@ -585,15 +585,15 @@ Found %1$s and %2$d files. - No tags + Tidak ada tag Membatalkan transfer… Enquiries must be at least 10 characters - Describe the issue with at least 10 characters + Jelaskan masalah dengan setidaknya 10 karakter - Keep conversations private + Jaga percakapan tetap pribadi All your messages, group chats, and calls are protected by our zero-knowledge encryption. [A]Learn more[/A] @@ -601,17 +601,17 @@ Invite friends with confidence - With top-notch security and verification codes, reach out without fear of scams, data mining, or information theft + Dengan kode keamanan dan verifikasi terbaik, hubungi tanpa takut penipuan, penambangan data, atau pencurian informasi Undang - There are hidden items in this folder. Sharing the folder will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Ada item tersembunyi di folder ini. Berbagi folder berarti bahwa item tersembunyi terlihat oleh orang-orang yang anda bagikan. Item masih akan disembunyikan di drive Cloud anda. - There are hidden items in one or more of these folders. Sharing the folders will mean that the hidden items are visible to those you share with. The items will still be hidden in your Cloud drive. + Ada item tersembunyi di satu atau lebih folder ini. Berbagi folder berarti bahwa item tersembunyi terlihat oleh orang-orang yang anda bagikan. Item masih akan disembunyikan di drive Cloud anda. - We’re sorry to see you leave! Can you tell us why you’re cancelling your subscription? + Kami menyesal melihat anda pergi! Bisakah anda memberi tahu kami mengapa anda membatalkan langganan anda? - Your subscription will be cancelled immediately and you will be moved to a free MEGA account when your current plan expires. Note: Cancelling your subscription won’t delete your account. + Langganan anda akan segera dibatalkan dan anda akan dipindahkan ke akun MEGA gratis ketika paket anda saat ini berakhir. Catatan: Membatalkan langganan tidak akan menghapus akun anda. Pilih alasan untuk membatalkan langganan anda @@ -635,13 +635,13 @@ Lainnya (harap berikan detailnya) - I allow MEGA to contact me to talk about this topic further + Saya mengizinkan MEGA untuk menghubungi saya untuk membicarakan topik ini lebih lanjut Batalkan Langganan Jangan batalkan - Recently watched + Baru-baru ini ditonton Tidak Ada Aktivitas Terbaru @@ -659,7 +659,7 @@ Tutup - Protect your calls + Lindungi panggilan anda Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] @@ -668,4 +668,20 @@ Masukkan detail Dapatkan penyimpanan cloud gratis + + Apa yang baru + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Pelajari selengkapnya + + Batal + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index e5702f02b4..b7e3a28aaf 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -683,4 +683,20 @@ Inserisci dettagli Ottieni spazio di archiviazione cloud gratuito + + Cosa c\’è di nuovo + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Scopri di più + + Annulla + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index e839e606ce..88c96b1570 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -517,7 +517,7 @@ モバイルデバイスの場合 - 1. ウェブブラウザで[A]]www.mega.nz[/A]にアクセスする。 + 1. ウェブブラウザで[A]www.mega.nz[/A]にアクセスする。 2. MEGAアカウントにログインする。 @@ -662,4 +662,20 @@ 詳細を入力してください 無料クラウドストレージを入手 + + 新機能 + + 簡単に自動同期 + + デバイス上のフォルダをMEGAと同期すると、どこからでもお持ちのファイルの最新バージョンにアクセスできます + + フォルダを同期 + + アップグレードして同期を使用する + + もっと詳しく知る + + キャンセル + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 2aa9517321..35c8df6e3f 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -663,4 +663,20 @@ 자세한 정보를 입력하세요 무료 클라우드 저장소를 얻으세요 + + 새로운 점 + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + 더 알아보기 + + 취소 + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 9c2914694c..1dbc21bad5 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -674,4 +674,20 @@ Voer details in Ontvang gratis cloudopslag + + Wat is er nieuw + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Leer meer + + Annuleren + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index d13995d85b..df4fb1b8eb 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -698,4 +698,20 @@ Wprowadź szczegóły Uzyskaj bezpłatną pamięć w chmurze + + Co nowego + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Dowiedz się więcej + + Anuluj + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 8a73472945..b2f7a420d6 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -686,4 +686,20 @@ Digite as informações Obtenha armazenamento em nuvem gratuito + + Novidades + + Sincronização fácil e automática + + Sincronize com o MEGA uma pasta no seu dispositivo, e acesse a versão mais recente dos seus arquivos independentemente de onde você estiver + + Sincronizar pastas + + Fazer o upgrade para sincronizar + + Mais informações + + Cancelar + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 49674f773d..cc7985f5d6 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -686,4 +686,20 @@ Introduceți detalii Obțineți spațiu de stocare în cloud gratuit + + Ce este nou + + Sincronizare ușoară și automată + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sincronizați folderele + + Faceți upgrade pentru a folosi sincronizarea + + Aflați mai multe + + Anulați + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index b26b0aa14a..0ea5a3947f 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -698,4 +698,20 @@ Укажите подробности Бесплатное облачное хранилище + + Что нового + + Простая автоматическая синхронизация + + Синхронизируйте папку на своём устройстве с MEGA, чтобы иметь доступ к актуальным версиям файлов в любом месте + + Синхронизировать папки + + Улучшить аккаунт для синхронизации + + Узнать больше + + Отмена + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 21fa5c382a..bf09d36a61 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -662,4 +662,20 @@ กรอกรายละเอียด รับที่เก็บข้อมูลบนคลาวด์ฟรี + + มีอะไรใหม่ ๆ บ้าง + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + เรียนรู้เพิ่มเติม + + ยกเลิก + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 0953eb5090..3195beb989 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -198,7 +198,7 @@ - Đã loại bỏ %1$d mục khỏi “%2$s” + Đã loại bỏ %1$d mục khỏi “%2$s” @@ -333,7 +333,7 @@ Thêm tên liên lạc, tạo kết nối, cộng tác với nhau, trao đổi qua gọi thoại và video mà không cần phải rời khỏi MEGA. - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + Đăng tải camêra là tính năng thiết yếu cho mọi thiết bị di động, và MEGA có cung cấp cho mọi người dùng. Tạo tài khoản ngay. Gọi họp video an toàn với mã hóa vô kiến thức. @@ -421,13 +421,13 @@ Tính năng - Free + Miễn phí Lưu trữ - %1giây + %1s - Truyền Tải + Truyền tải Bị giới hạn @@ -469,7 +469,7 @@ Một hay nhiều mục này được đặt ẩn đi. Khi bạn chia sẻ các mục này, bất kỳ ai có đường liên kết sẽ có thể xem thấy hết nhưng các mục vẫn sẽ được ẩn đi trong Ổ Mây của bạn. - Hủy Gói Đăng Ký Dịch Vụ + Hủy gói đăng ký Kích hoạt lại gói đăng ký @@ -587,15 +587,15 @@ Mô tả vấn đề với ít nhất 10 ký tự - Keep conversations private + Giữ các cuộc trò chuyện được riêng tư - All your messages, group chats, and calls are protected by our zero-knowledge encryption. [A]Learn more[/A] + Tất cả tin nhắn, trò chuyện nhóm và cuộc gọi của bạn đều được bảo vệ bằng mã hóa vô kiến thức của chúng tôi. [A]Tìm hiểu thêm[/A] Mời bạn bè - Invite friends with confidence + Tự tin mời bạn bè - With top-notch security and verification codes, reach out without fear of scams, data mining, or information theft + Sử dụng mã xác minh và cấp bảo mật hàng đầu, tiếp cận mà không sợ lừa đảo, bị khai thác dữ liệu hoặc trộm cắp thông tin Mời @@ -631,7 +631,7 @@ Tôi cho phép MEGA liên hệ với tôi để bàn thêm về chủ đề này - Hủy Gói Đăng Ký Dịch Vụ + Hủy gói đăng ký Đừng hủy @@ -647,19 +647,35 @@ Quét không được hoàn tất - Your phone doesn’t meet the minimum memory requirements to complete the scan + Điện thoại của bạn không đáp ứng đủ yêu cầu bộ nhớ tối thiểu để hoàn tất quá trình quét - We’re having trouble scanning this document. Please try again. + Chúng tôi gặp sự cố khi quét tài liệu này. Vui lòng thử lại. Đóng - Protect your calls + Bảo vệ cuộc gọi của bạn - Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] + Các cuộc họp, cuộc gọi gia đình và cuộc trò chuyện riêng tư của bạn được bảo vệ bằng mã hóa vô kiến thức của chúng tôi. [A]Tìm hiểu thêm[/A] - Message must be at least 10 characters + Tin nhắn phải có ít nhất 10 ký tự Nhập chi tiết Nhận lấy không gian lưu trữ đám mây miễn phí + + Có gì mới + + Đồng bộ hóa tự động và dễ dàng + + Đồng bộ hóa thư mục trên thiết bị của bạn với MEGA để truy cập phiên bản mới nhất của tệp tin ở bất cứ nơi đâu + + Đồng bộ thư mục + + Nâng cấp để dùng đồng bộ hóa + + Tìm hiểu thêm + + Hủy + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index bbe1452d9b..6038415177 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -333,7 +333,7 @@ 添加联系人、创建关系网、协同合作以及进行语音和视频通话,一切尽在MEGA - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + 相机上传是任何移动设备的必备功能,我们已经为您提供这项服务。立即注册一个帐户。 零知识加密视频会议。 @@ -425,7 +425,7 @@ 存储空间 - %1秒 + %1s 传输 @@ -653,13 +653,29 @@ 关闭 - Protect your calls + 保护您的通话 - Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] + 您的会议、家庭通话和私密对话都受我们零知识加密的保护。[A]了解更多[/A] - Message must be at least 10 characters + 消息必须至少包含10个字符 输入详细信息 获取免费云端存储 + + 新增内容 + + 轻松,自动的同步 + + 将您设备上的文件夹与MEGA同步,随时随地访问您文件的最新版本 + + 同步文件夹 + + 升级以使用同步 + + 了解更多 + + 取消 + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 2b101a88af..39698eb636 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -662,4 +662,20 @@ 輸入詳細訊息 獲得免費雲端儲存 + + 有什麼新功能 + + 輕鬆,自動的同步 + + 將您裝置上的資料夾與MEGA同步,以便在任何地方存取您檔案的最新版本 + + 同步資料夾 + + 升級以使用同步 + + 瞭解更多 + + 取消 + + Sync option updated \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 8b1e954f5f..4bfaa9019b 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -674,4 +674,20 @@ Enter details Get free cloud storage + + What’s new + + Easy, automated sync + + Sync a folder on your device with MEGA to access the latest version of your files anywhere + + Sync folders + + Upgrade to use sync + + Learn more + + Cancel + + Sync option updated \ No newline at end of file From fb44f8a955f7c150c28ab562f7623131c1aae0ff Mon Sep 17 00:00:00 2001 From: Sida Qian Date: Fri, 13 Sep 2024 15:35:59 +1200 Subject: [PATCH 242/261] SAO-1905 Hide tags if rubbish bin or incoming shares node --- .../privacy/android/app/presentation/data/NodeUIItem.kt | 2 ++ .../app/presentation/search/SearchActivityViewModel.kt | 9 ++++++++- .../android/app/presentation/view/NodeListView.kt | 2 +- .../search/model/SearchActivityViewModelTest.kt | 8 ++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt b/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt index b672c7d8ec..82a10510a7 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt @@ -10,6 +10,7 @@ import mega.privacy.android.domain.entity.node.shares.ShareFolderNode * @param isSelected Node is selected * @param isInvisible Node is invisible * @param fileDuration Duration of file + * @param isRubbishBin Is node in rubbish bin * @property uniqueKey Unique key of the node, to be used in Compose list * @constructor Create empty Node UI Item */ @@ -18,6 +19,7 @@ data class NodeUIItem( var isSelected: Boolean, val isInvisible: Boolean = false, val fileDuration: String? = null, + val isRubbishBin: Boolean = false, ) : Node by node { val uniqueKey = "${node.id.longValue}".plus( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index 08d22a71d2..b82571a986 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -44,6 +44,7 @@ import mega.privacy.android.domain.usecase.GetCloudSortOrder import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.canceltoken.CancelCancelTokenUseCase import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase +import mega.privacy.android.domain.usecase.node.IsNodeInRubbishBinUseCase import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import mega.privacy.android.domain.usecase.search.SearchUseCase @@ -64,6 +65,7 @@ import kotlin.coroutines.cancellation.CancellationException * @property typeFilterToSearchMapper [TypeFilterToSearchMapper] * @property emptySearchViewMapper [EmptySearchViewMapper] * @property cancelCancelTokenUseCase [CancelCancelTokenUseCase] + * @property isNodeInRubbishBinUseCase [IsNodeInRubbishBinUseCase] * @property setViewType [SetViewType] * @property monitorViewType [MonitorViewType] * @property getCloudSortOrder [GetCloudSortOrder] @@ -81,6 +83,7 @@ class SearchActivityViewModel @Inject constructor( private val dateFilterOptionStringResMapper: DateFilterOptionStringResMapper, private val emptySearchViewMapper: EmptySearchViewMapper, private val cancelCancelTokenUseCase: CancelCancelTokenUseCase, + private val isNodeInRubbishBinUseCase: IsNodeInRubbishBinUseCase, private val setViewType: SetViewType, private val monitorViewType: MonitorViewType, private val getCloudSortOrder: GetCloudSortOrder, @@ -221,7 +224,11 @@ class SearchActivityViewModel @Inject constructor( } } else { val nodeUIItems = searchResults.distinctBy { it.id.longValue }.map { typedNode -> - NodeUIItem(node = typedNode, isSelected = false) + NodeUIItem( + node = typedNode, + isSelected = false, + isRubbishBin = isNodeInRubbishBinUseCase(typedNode.id) + ) } _state.update { state -> val cloudSortOrder = getCloudSortOrder() diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt index 25b80d54ff..79fd6892a5 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt @@ -121,7 +121,7 @@ fun NodeListView( showPublicLinkCreationTime = showPublicLinkCreationTime ), description = nodeUiItem.node.description, - tags = nodeUiItem.node.tags, + tags = nodeUiItem.node.tags.takeIf { !nodeUiItem.isRubbishBin && !nodeUiItem.node.isIncomingShare }, icon = nodeUiItem.node.getNodeItemThumbnail(fileTypeIconMapper = fileTypeIconMapper), thumbnailData = ThumbnailRequest(nodeUiItem.id, isPublicNode), isSelected = nodeUiItem.isSelected, diff --git a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt index 9e41a1fd86..20e7c0d1a6 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt @@ -40,6 +40,7 @@ import mega.privacy.android.domain.usecase.GetCloudSortOrder import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.canceltoken.CancelCancelTokenUseCase import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase +import mega.privacy.android.domain.usecase.node.IsNodeInRubbishBinUseCase import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import mega.privacy.android.domain.usecase.search.SearchUseCase @@ -65,6 +66,7 @@ class SearchActivityViewModelTest { private val monitorNodeUpdatesFakeFlow = MutableSharedFlow() private val monitorNodeUpdatesUseCase: MonitorNodeUpdatesUseCase = mock() private val cancelCancelTokenUseCase: CancelCancelTokenUseCase = mock() + private val isNodeInRubbishBinUseCase: IsNodeInRubbishBinUseCase = mock() private val searchFilterMapper: SearchFilterMapper = mock() private val nodeSourceTypeToSearchTargetMapper: NodeSourceTypeToSearchTargetMapper = mock() private val typeFilterToSearchMapper: TypeFilterToSearchMapper = mock() @@ -104,6 +106,7 @@ class SearchActivityViewModelTest { stateHandle = stateHandle, getCloudSortOrder = getCloudSortOrder, cancelCancelTokenUseCase = cancelCancelTokenUseCase, + isNodeInRubbishBinUseCase = isNodeInRubbishBinUseCase, searchFilterMapper = searchFilterMapper, nodeSourceTypeToSearchTargetMapper = nodeSourceTypeToSearchTargetMapper, typeFilterToSearchMapper = typeFilterToSearchMapper, @@ -146,6 +149,7 @@ class SearchActivityViewModelTest { stateHandle, getCloudSortOrder, cancelCancelTokenUseCase, + isNodeInRubbishBinUseCase, searchFilterMapper, nodeSourceTypeToSearchTargetMapper, typeFilterToSearchMapper, @@ -333,6 +337,7 @@ class SearchActivityViewModelTest { val nodeSourceType = NodeSourceType.CLOUD_DRIVE whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) + whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) nodeList.add(typedFileNode) nodeList.add(typedFolderNode) @@ -385,6 +390,7 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) + whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), @@ -441,6 +447,7 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) + whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), @@ -493,6 +500,7 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) + whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), From 5f6fdaff7160860043ca63fbea67a7ddaefe51ca Mon Sep 17 00:00:00 2001 From: Sougandh mp Date: Mon, 16 Sep 2024 18:58:24 +1200 Subject: [PATCH 243/261] SAO-1905: (T17741416) Fix tags visible in share screen bug --- .../privacy/android/app/presentation/data/NodeUIItem.kt | 2 -- .../app/presentation/search/SearchActivityViewModel.kt | 8 +++----- .../privacy/android/app/presentation/view/NodeListView.kt | 2 +- .../search/model/SearchActivityViewModelTest.kt | 8 -------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt b/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt index 82a10510a7..b672c7d8ec 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/data/NodeUIItem.kt @@ -10,7 +10,6 @@ import mega.privacy.android.domain.entity.node.shares.ShareFolderNode * @param isSelected Node is selected * @param isInvisible Node is invisible * @param fileDuration Duration of file - * @param isRubbishBin Is node in rubbish bin * @property uniqueKey Unique key of the node, to be used in Compose list * @constructor Create empty Node UI Item */ @@ -19,7 +18,6 @@ data class NodeUIItem( var isSelected: Boolean, val isInvisible: Boolean = false, val fileDuration: String? = null, - val isRubbishBin: Boolean = false, ) : Node by node { val uniqueKey = "${node.id.longValue}".plus( diff --git a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt index b82571a986..8f96440f31 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/search/SearchActivityViewModel.kt @@ -31,6 +31,7 @@ import mega.privacy.android.app.presentation.search.model.TypeFilterWithName import mega.privacy.android.app.presentation.search.navigation.DATE_ADDED import mega.privacy.android.app.presentation.search.navigation.DATE_MODIFIED import mega.privacy.android.app.presentation.search.navigation.TYPE +import mega.privacy.android.domain.entity.SortOrder import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.NodeSourceType import mega.privacy.android.domain.entity.node.NodeSourceType.OTHER @@ -44,7 +45,6 @@ import mega.privacy.android.domain.usecase.GetCloudSortOrder import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.canceltoken.CancelCancelTokenUseCase import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase -import mega.privacy.android.domain.usecase.node.IsNodeInRubbishBinUseCase import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import mega.privacy.android.domain.usecase.search.SearchUseCase @@ -65,7 +65,6 @@ import kotlin.coroutines.cancellation.CancellationException * @property typeFilterToSearchMapper [TypeFilterToSearchMapper] * @property emptySearchViewMapper [EmptySearchViewMapper] * @property cancelCancelTokenUseCase [CancelCancelTokenUseCase] - * @property isNodeInRubbishBinUseCase [IsNodeInRubbishBinUseCase] * @property setViewType [SetViewType] * @property monitorViewType [MonitorViewType] * @property getCloudSortOrder [GetCloudSortOrder] @@ -83,7 +82,6 @@ class SearchActivityViewModel @Inject constructor( private val dateFilterOptionStringResMapper: DateFilterOptionStringResMapper, private val emptySearchViewMapper: EmptySearchViewMapper, private val cancelCancelTokenUseCase: CancelCancelTokenUseCase, - private val isNodeInRubbishBinUseCase: IsNodeInRubbishBinUseCase, private val setViewType: SetViewType, private val monitorViewType: MonitorViewType, private val getCloudSortOrder: GetCloudSortOrder, @@ -227,11 +225,11 @@ class SearchActivityViewModel @Inject constructor( NodeUIItem( node = typedNode, isSelected = false, - isRubbishBin = isNodeInRubbishBinUseCase(typedNode.id) ) } + val cloudSortOrder = + runCatching { getCloudSortOrder() }.getOrDefault(SortOrder.ORDER_NONE) _state.update { state -> - val cloudSortOrder = getCloudSortOrder() state.copy( searchItemList = nodeUIItems, isSearching = false, diff --git a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt index 79fd6892a5..cd654d5c72 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/view/NodeListView.kt @@ -121,7 +121,7 @@ fun NodeListView( showPublicLinkCreationTime = showPublicLinkCreationTime ), description = nodeUiItem.node.description, - tags = nodeUiItem.node.tags.takeIf { !nodeUiItem.isRubbishBin && !nodeUiItem.node.isIncomingShare }, + tags = nodeUiItem.node.tags.takeIf { nodeSourceType != NodeSourceType.RUBBISH_BIN && nodeSourceType != NodeSourceType.INCOMING_SHARES }, icon = nodeUiItem.node.getNodeItemThumbnail(fileTypeIconMapper = fileTypeIconMapper), thumbnailData = ThumbnailRequest(nodeUiItem.id, isPublicNode), isSelected = nodeUiItem.isSelected, diff --git a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt index 20e7c0d1a6..9e41a1fd86 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/search/model/SearchActivityViewModelTest.kt @@ -40,7 +40,6 @@ import mega.privacy.android.domain.usecase.GetCloudSortOrder import mega.privacy.android.domain.usecase.account.MonitorAccountDetailUseCase import mega.privacy.android.domain.usecase.canceltoken.CancelCancelTokenUseCase import mega.privacy.android.domain.usecase.featureflag.GetFeatureFlagValueUseCase -import mega.privacy.android.domain.usecase.node.IsNodeInRubbishBinUseCase import mega.privacy.android.domain.usecase.node.MonitorNodeUpdatesUseCase import mega.privacy.android.domain.usecase.offline.MonitorOfflineNodeUpdatesUseCase import mega.privacy.android.domain.usecase.search.SearchUseCase @@ -66,7 +65,6 @@ class SearchActivityViewModelTest { private val monitorNodeUpdatesFakeFlow = MutableSharedFlow() private val monitorNodeUpdatesUseCase: MonitorNodeUpdatesUseCase = mock() private val cancelCancelTokenUseCase: CancelCancelTokenUseCase = mock() - private val isNodeInRubbishBinUseCase: IsNodeInRubbishBinUseCase = mock() private val searchFilterMapper: SearchFilterMapper = mock() private val nodeSourceTypeToSearchTargetMapper: NodeSourceTypeToSearchTargetMapper = mock() private val typeFilterToSearchMapper: TypeFilterToSearchMapper = mock() @@ -106,7 +104,6 @@ class SearchActivityViewModelTest { stateHandle = stateHandle, getCloudSortOrder = getCloudSortOrder, cancelCancelTokenUseCase = cancelCancelTokenUseCase, - isNodeInRubbishBinUseCase = isNodeInRubbishBinUseCase, searchFilterMapper = searchFilterMapper, nodeSourceTypeToSearchTargetMapper = nodeSourceTypeToSearchTargetMapper, typeFilterToSearchMapper = typeFilterToSearchMapper, @@ -149,7 +146,6 @@ class SearchActivityViewModelTest { stateHandle, getCloudSortOrder, cancelCancelTokenUseCase, - isNodeInRubbishBinUseCase, searchFilterMapper, nodeSourceTypeToSearchTargetMapper, typeFilterToSearchMapper, @@ -337,7 +333,6 @@ class SearchActivityViewModelTest { val nodeSourceType = NodeSourceType.CLOUD_DRIVE whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) - whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) nodeList.add(typedFileNode) nodeList.add(typedFolderNode) @@ -390,7 +385,6 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) - whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), @@ -447,7 +441,6 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) - whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), @@ -500,7 +493,6 @@ class SearchActivityViewModelTest { whenever(getCloudSortOrder()).thenReturn(SortOrder.ORDER_NONE) whenever(monitorViewType()).thenReturn(flowOf(ViewType.LIST)) - whenever(isNodeInRubbishBinUseCase(NodeId(any()))).thenReturn(false) whenever( searchUseCase( parentHandle = NodeId(parentHandle), From 49d882e77e7cb2404d941b2d601ce71907a9f7f0 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Tue, 17 Sep 2024 19:27:30 +1200 Subject: [PATCH 244/261] AND-19486 Remove report issue from login screen (cherry picked from commit aa717fea3eb1642413c4cc3e7ca5f81c9f52a72a) aa717fea AND-19486 Remove report issue from login screen Co-authored-by: Daniel Oosthuizen --- .../android/app/presentation/login/LoginFragment.kt | 13 ++++++++++--- .../app/presentation/login/view/LoginView.kt | 12 +----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt index 9cd034a9bc..45e9448e66 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/LoginFragment.kt @@ -154,7 +154,7 @@ class LoginFragment : Fragment() { onLostAuthenticatorDevice = ::onLostAuthenticationDevice, onBackPressed = { onBackPressed(uiState) }, onFirstTime2FAConsumed = viewModel::onFirstTime2FAConsumed, - onReportIssue = ::openReportIssueFragment, + onReportIssue = ::openLoginIssueHelpdeskPage, ) } @@ -165,8 +165,11 @@ class LoginFragment : Fragment() { } } - private fun openReportIssueFragment() { - (requireActivity() as LoginActivity).showFragment(LoginFragmentType.ReportIssue) + private fun openLoginIssueHelpdeskPage() { + Intent(Intent.ACTION_VIEW).apply { + data = Uri.parse(Companion.LOGIN_HELP_URL) + startActivity(this) + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -924,4 +927,8 @@ class LoginFragment : Fragment() { addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } } + + companion object { + private const val LOGIN_HELP_URL = "https://help.mega.io/accounts/login-issues" + } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/login/view/LoginView.kt b/app/src/main/java/mega/privacy/android/app/presentation/login/view/LoginView.kt index affda77f6a..863db4b3cf 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/login/view/LoginView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/login/view/LoginView.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.rememberScrollState @@ -67,7 +66,6 @@ import androidx.compose.ui.semantics.testTagsAsResourceId import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider @@ -340,6 +338,7 @@ private fun RequireLogin( if (state.enabledFlags.contains(AppFeatures.LoginReportIssueButton)) { Row( modifier = Modifier + .fillMaxWidth() .clickable { onReportIssue() } @@ -350,15 +349,6 @@ private fun RequireLogin( text = stringResource(id = R.string.general_login_label_trouble_logging_in), style = MaterialTheme.typography.subtitle2.copy(color = MaterialTheme.colors.textColorPrimary) ) - Spacer(modifier = Modifier.width(4.dp)) - Text( - modifier = Modifier.testTag(REPORT_ISSUE_TAG), - text = stringResource(id = R.string.general_login_button_report_your_issue), - style = MaterialTheme.typography.subtitle2.copy( - color = MaterialTheme.colors.textColorPrimary, - textDecoration = TextDecoration.Underline - ) - ) } } Row(modifier = Modifier.padding(end = 22.dp)) { From 6c1ac8f185ced4833008121c40bb7ab3147aad68 Mon Sep 17 00:00:00 2001 From: Yenel Date: Tue, 17 Sep 2024 09:17:43 +0200 Subject: [PATCH 245/261] T18088630 Uploading by sharing from another app results in wrong modified date --- .../java/mega/privacy/android/app/ShareInfo.java | 4 ++-- .../privacy/android/data/facade/FileFacade.kt | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/ShareInfo.java b/app/src/main/java/mega/privacy/android/app/ShareInfo.java index ddebc4963e..8e1fd0fda8 100644 --- a/app/src/main/java/mega/privacy/android/app/ShareInfo.java +++ b/app/src/main/java/mega/privacy/android/app/ShareInfo.java @@ -491,13 +491,13 @@ private void processContent(Uri uri, Context context) { } int lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED); if (lastModifiedIndex != -1) { - this.lastModified = cursor.getLong(lastModifiedIndex); + this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } if (lastModified == 0) { lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED); if (lastModifiedIndex != -1) { - this.lastModified = cursor.getLong(lastModifiedIndex); + this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } } diff --git a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt index 1fae39b62b..5a70595cd7 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt @@ -463,12 +463,18 @@ internal class FileFacade @Inject constructor( ?.use { client -> client.query(uri, null, null, null, null) ?.use { cursor -> + var lastModified = 0L + cursor.moveToFirst() - val index = cursor.getColumnIndex(DATE_MODIFIED).takeIf { it != -1 } - ?: cursor.getColumnIndex(DATE_ADDED).takeIf { it != -1 } - ?: cursor.getColumnIndex(DATE_TAKEN).takeIf { it != -1 } - ?: 0 - index.takeIf { it != 0 }?.let { cursor.getLong(it) } + cursor.getColumnIndex(DATE_MODIFIED).takeIf { it != -1 }?.let { index -> + lastModified = cursor.getLong(index) * 1000 + } ?: cursor.getColumnIndex(DATE_ADDED).takeIf { it != -1 }?.let { index -> + lastModified = cursor.getLong(index) * 1000 + } ?: cursor.getColumnIndex(DATE_TAKEN).takeIf { it != -1 }?.let { index -> + lastModified = cursor.getLong(index) + } + + lastModified } ?: 0 } ?: 0 From dcc48f65128a3c648cbc9777e46ab06d5b870e32 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Tue, 17 Sep 2024 11:41:22 +0200 Subject: [PATCH 246/261] Update strings --- app/src/main/res/values-ar/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 10 +++++----- app/src/main/res/values-in/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-th/strings.xml | 2 +- app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- .../src/main/res/values-ar/strings_shared.xml | 8 +++++++- .../src/main/res/values-de/strings_shared.xml | 8 +++++++- .../src/main/res/values-es/strings_shared.xml | 10 ++++++++-- .../src/main/res/values-fr/strings_shared.xml | 10 ++++++++-- .../src/main/res/values-in/strings_shared.xml | 8 +++++++- .../src/main/res/values-it/strings_shared.xml | 8 +++++++- .../src/main/res/values-ja/strings_shared.xml | 8 +++++++- .../src/main/res/values-ko/strings_shared.xml | 8 +++++++- .../src/main/res/values-nl/strings_shared.xml | 16 +++++++++++----- .../src/main/res/values-pl/strings_shared.xml | 8 +++++++- .../src/main/res/values-pt/strings_shared.xml | 8 +++++++- .../src/main/res/values-ro/strings_shared.xml | 10 ++++++++-- .../src/main/res/values-ru/strings_shared.xml | 8 +++++++- .../src/main/res/values-th/strings_shared.xml | 8 +++++++- .../src/main/res/values-vi/strings_shared.xml | 8 +++++++- .../main/res/values-zh-rCN/strings_shared.xml | 8 +++++++- .../main/res/values-zh-rTW/strings_shared.xml | 8 +++++++- .../src/main/res/values/strings_shared.xml | 10 ++++++++-- 32 files changed, 152 insertions(+), 44 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2e4e54e9f2..143bb7804a 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1993,7 +1993,7 @@ إغلاق - تطبيق المصادقة المزدوجة Two-Factor + Two-factor authenticator app هل ترغب في فتح متجر غوغل Google Play حتى تتمكن من تثبيت تطبيق المصادقة؟ diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c88fd6707e..2f5fa0800e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1825,7 +1825,7 @@ Schließen - App für Zwei-Faktor-Authentifizierung + Two-factor authenticator app Möchten Sie Google Play zur Installation einer Authenticator App öffnen? diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index bd52e3b8cc..5af01066d7 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -137,7 +137,7 @@ ¿Nuevo en MEGA? - Crea una cuenta de MEGA + Registra una cuenta de MEGA Introduce tu email @@ -1386,7 +1386,7 @@ Instala la app móvil de MEGA - Signup bonus + Bono de registro Instala una aplicación de escritorio de MEGA @@ -1416,7 +1416,7 @@ Has obtenido %1$s de espacio de almacenamiento por instalar la aplicación de MEGA para móvil. - You have received %1$s storage space as your free signup bonus. + Has recibido %1$s de espacio de almacenamiento como bono de registro gratuito. Compartir carpeta @@ -1867,7 +1867,7 @@ Cerrar - App de autenticación de dos factores + Two-factor authenticator app ¿Quieres abrir Google Play para instalar una aplicación de autenticación? @@ -1983,7 +1983,7 @@ Activa o desactiva el control de versiones de archivos para toda tu cuenta.\nDesactivar el control de versiones no impedirá que tus contactos creen nuevas versiones en carpetas compartidas. - Search contacts or type email address + Seleccionar contactos o añadir direcciones de correo ¿Añadir a %s a tus contactos? diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index e85520c605..328383c35e 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -1783,7 +1783,7 @@ Tutup - Aplikasi otentikasi dua faktor + Two-factor authenticator app Apakah anda ingin membuka Google Play agar dapat memasang aplikasi otentikasi? diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 09c1a7834c..a4db3a7ab1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -1867,7 +1867,7 @@ Chiudi - App autenticazione a due fattori + Two-factor authenticator app Vuoi aprire il Google Play Store in modo da installare un\’app di autenticazione? diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 6d29b3ab53..3397411988 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1783,7 +1783,7 @@ 닫기 - 2단계 인증 앱 + Two-factor authenticator app 인증기 앱을 설치할 수 있도록 Google Play를 여시겠습니까? diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index a2a52e0920..403ef53ef8 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1825,7 +1825,7 @@ Sluiten - Twee-staps authenticatie applicatie + Two-factor authenticator app Wilt u Google Play openen zodat u een authenticatie applicatie kunt installeren? diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b2d862a0ce..ee9b86c7ec 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -1909,7 +1909,7 @@ Zamknij - Aplikacja do uwierzytelniania dwuskładnikowego + Two-factor authenticator app Czy chcesz otworzyć Google Play, aby zainstalować aplikację uwierzytelniającego? diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 90b36dde99..4db1fcb45c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -1867,7 +1867,7 @@ Fechar - Aplicativo para autenticação de dois fatores + Two-factor authenticator app Você quer acessar a Google Play Store para instalar um aplicativo de autenticação? diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 5f5e9bef58..4146a89247 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -1783,7 +1783,7 @@ ปิด - แอปรับรองความถูกต้องด้วยสองปัจจัย + Two-factor authenticator app คุณต้องการเปิด Google Play เพื่อติดตั้งแอปตัวรับรองความถูกต้องหรือไม่ diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 82d9967584..7e538a4b95 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1783,7 +1783,7 @@ Đóng - App Xác thực 2 yếu tố + Two-factor authenticator app Bạn có muốn tới CH Google Play để tải về một app lập xác thực hay không? diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 31692bad61..92ad34a2da 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1783,7 +1783,7 @@ 关闭 - 双重验证应用程序 + Two-factor authenticator app 您想打开Google Play来安装验证应用程序吗? diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index c3cc98e620..ea64b57fda 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1783,7 +1783,7 @@ 關閉 - 雙重驗證應用程式 + Two-factor authenticator app 您想開啟Google Play來安裝身份驗證程式嗎? diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4633b68d05..16f901c95d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1825,7 +1825,7 @@ Close - Two-factor authentication app + Two-factor authenticator app Would you like to open Google Play so you can install an authenticator app? diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index d5039df1cb..9736106601 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -737,5 +737,11 @@ إلغاء - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + السماح بالوصول \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 0e41f62997..5b23e255cd 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -689,5 +689,11 @@ Abbrechen - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Zugriff erlauben \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index be88e862dc..8b0b2d6bbc 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -674,7 +674,7 @@ Cerrar - Protect your calls + Protege tus llamadas Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] @@ -698,5 +698,11 @@ Cancelar - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Permitir acceso \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 11acd12c58..60f0ea9489 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -691,7 +691,7 @@ Synchronisation simple et automatique - Sync a folder on your device with MEGA to access the latest version of your files anywhere + Synchronisez un dossier sur votre appareil avec MEGA pour accéder à la version la plus récente de vos fichiers où que vous soyez Synchroniser les dossiers @@ -701,5 +701,11 @@ Annuler - Sync option updated + Options de synchronisation mises à jour + + Activez l\’accès pour inviter des amis + + Pour inviter des amis, vous devez autoriser MEGA à accéder à votre liste de contacts + + Autoriser l’accès \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 6183d57235..62b98a0687 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -683,5 +683,11 @@ Batal - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Izinkan Akses \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index b7e3a28aaf..ca558ba9cc 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -698,5 +698,11 @@ Annulla - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Permetti l\’accesso \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 88c96b1570..91d6b3f30e 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -677,5 +677,11 @@ キャンセル - Sync option updated + 同期オプションが更新されました + + 友人を招待するためのアクセスを有効化 + + 友人を招待するには、MEGAがあなたの連絡先リストにアクセスできるようにする必要があります + + アクセスを許可 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index 35c8df6e3f..f3c07a4a10 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -678,5 +678,11 @@ 취소 - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + 접근 허용 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index 1dbc21bad5..c965c00a62 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -677,17 +677,23 @@ Wat is er nieuw - Easy, automated sync + Eenvoudig, geautomatiseerd synchroniseren - Sync a folder on your device with MEGA to access the latest version of your files anywhere + Synchroniseer een map op uw apparaat met MEGA om overal toegang te krijgen tot de nieuwste versie van uw bestanden - Sync folders + Mappen synchroniseren - Upgrade to use sync + Upgrade om synchronisatie te gebruiken Leer meer Annuleren - Sync option updated + Sync options updated + + Toegang inschakelen om vrienden uit te nodigen + + Om vrienden uit te nodigen, moet u MEGA toegang geven tot uw contactenlijst + + Toegang Toestaan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index df4fb1b8eb..ee1fdb1239 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -713,5 +713,11 @@ Anuluj - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Udostępnik \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index b2f7a420d6..4a9c7ce887 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -701,5 +701,11 @@ Cancelar - Sync option updated + Sync options updated + + Permitir o acesso para convidar amigos + + Para convidar amigos, você precisa permitir que o MEGA acesse a sua lista de contatos + + Permitir acesso \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index cc7985f5d6..96f320bfbf 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -691,7 +691,7 @@ Sincronizare ușoară și automată - Sync a folder on your device with MEGA to access the latest version of your files anywhere + Sincronizați un folder de pe dispozitiv cu MEGA pentru a accesa cea mai recentă versiune a fișierelor dvs. oriunde Sincronizați folderele @@ -701,5 +701,11 @@ Anulați - Sync option updated + Opțiuni de sincronizare actualizate + + Activați accesul pentru a invita prieteni + + Pentru a invita prieteni, trebuie să permiteți MEGA să acceseze lista dvs. de contacte + + Activează accesul \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index 0ea5a3947f..bc198f86bd 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -713,5 +713,11 @@ Отмена - Sync option updated + Параметры синхронизации обновлены + + Откройте доступ, чтобы пригласить друзей + + Чтобы приглашать друзей, нужно разрешить MEGA доступ к вашему списку контактов + + Открыть доступ \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index bf09d36a61..764f8b6061 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -677,5 +677,11 @@ ยกเลิก - Sync option updated + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + อนุญาตให้เข้าถึง \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 3195beb989..443b5a92df 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -677,5 +677,11 @@ Hủy - Sync option updated + Sync options updated + + Bật quyền truy cập để mời bạn bè + + Để mời bạn bè, bạn phải cho phép MEGA truy cập sổ danh bạ của bạn. + + Cho phép quyền truy cập \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 6038415177..9ee2e6e1d5 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -677,5 +677,11 @@ 取消 - Sync option updated + Sync options updated + + 启用访问以邀请好友的权限 + + 为了邀请好友,您必须允许MEGA访问您的联系人列表 + + 允许访问 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 39698eb636..c51bb41e65 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -677,5 +677,11 @@ 取消 - Sync option updated + Sync options updated + + 啟用邀請朋友的存取權限 + + 為了邀請朋友,您必須允許MEGA存取您的聯絡人列表 + + 允許存取 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 4bfaa9019b..db2be21ad5 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -689,5 +689,11 @@ Cancel - Sync option updated - \ No newline at end of file + Sync options updated + + Enable access to invite friends + + In order to invite friends, you must allow MEGA to access your contact list + + Allow access + From 258af81ef9c6aa2fbfd0bd5630c7a97706869aad Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Wed, 18 Sep 2024 20:50:41 +1200 Subject: [PATCH 247/261] AND-19314 Add Mutex to Reset Logging Configuration (cherry picked from commit 3134d519433f98a412696e3d9996f514472dfc6f) baeb540a VPN-19314 Add Mutex to Reset Logging Configuration b22280ad change to = Co-authored-by: Kevin Gozali --- .../data/gateway/LogbackLogConfigurationGateway.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/data/src/main/java/mega/privacy/android/data/gateway/LogbackLogConfigurationGateway.kt b/data/src/main/java/mega/privacy/android/data/gateway/LogbackLogConfigurationGateway.kt index 8dae7e9b02..3e7ed415c2 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/LogbackLogConfigurationGateway.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/LogbackLogConfigurationGateway.kt @@ -12,6 +12,9 @@ import java.io.File import java.io.IOException import java.io.InputStream import javax.inject.Inject +import javax.inject.Singleton +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock /** @@ -19,12 +22,14 @@ import javax.inject.Inject * * @property context */ +@Singleton class LogbackLogConfigurationGateway @Inject constructor( @ApplicationContext private val context: Context, - @LogFileDirectory private val logFileDirectory: Lazy + @LogFileDirectory private val logFileDirectory: Lazy, ) : LogConfigurationGateway { + private val mutex = Mutex() - override suspend fun resetLoggingConfiguration() { + override suspend fun resetLoggingConfiguration() = mutex.withLock { val loggingContext = LoggerFactory.getILoggerFactory() as LoggerContext val loggers = loggingContext.copyOfListenerList loggingContext.reset() From a709672f9f787838593fbeaf13d3e2d6c61604a5 Mon Sep 17 00:00:00 2001 From: "Application Development (Jenkins Agent)" Date: Thu, 19 Sep 2024 05:06:29 +1200 Subject: [PATCH 248/261] Update analytics dependency --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index dbbf57fecd..88b2ccbe0e 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -69,7 +69,7 @@ shimmerlayout = 'io.supercharge:shimmerlayout:2.1.0' simplestorage = { module = "com.anggrayudi:storage", version.ref = "simplestorage" } vdurmont-emoji = 'com.vdurmont:emoji-java:4.0.0' compose-state-events = { module = "com.github.leonard-palm:compose-state-events", version.ref = "compose-state-events" } -mega-analytics = "mega.privacy.mobile:analytics-events-android:+" +mega-analytics = "mega.privacy.mobile:analytics-events-android:20240918.114742" kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } balloon = "com.github.skydoves:balloon-compose:1.6.4" xray = { module = "mega.privacy.android.xray:xray", version.ref = "xray" } From 87bb4493532dd8610c1bc9ac4006922cc8a6e6db Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Date: Mon, 23 Sep 2024 10:01:43 +0200 Subject: [PATCH 249/261] bump version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4024be64d6..cfd0b1f8be 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -78,7 +78,7 @@ tasks.register("clean", Delete::class) { // Define versions in a single place // App -extra["appVersion"] = "14.3" +extra["appVersion"] = "14.3.1" // Sdk and tools extra["compileSdkVersion"] = 35 From d8afe2c38b9e7712aa56f310c99cbd72254cfdea Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 23 Sep 2024 16:43:44 +0800 Subject: [PATCH 250/261] CC-8161 AND -Non-fatal Exception: java.lang.OutOfMemoryError --- .../videosection/VideoSectionFragment.kt | 10 +- .../videosection/VideoSectionViewModel.kt | 13 +- .../videosection/VideoSectionViewModelTest.kt | 56 +- .../90.json | 744 ++++++++++++++++++ .../dao/VideoRecentlyWatchedDaoTest.kt | 197 +++++ .../android/data/database/MegaDatabase.kt | 7 +- .../data/database/MegaDatabaseConstant.kt | 7 +- .../database/dao/VideoRecentlyWatchedDao.kt | 27 + .../entity/VideoRecentlyWatchedEntity.kt | 14 + .../android/data/di/RoomDatabaseModule.kt | 6 + .../data/facade/MegaLocalRoomFacade.kt | 30 + .../data/gateway/MegaLocalRoomGateway.kt | 34 + .../VideoRecentlyWatchedEntityMapper.kt | 11 + .../repository/VideoSectionRepositoryImpl.kt | 76 +- .../data/facade/MegaLocalRoomFacadeTest.kt | 89 +++ .../VideoRecentlyWatchedEntityMapperTest.kt | 47 ++ .../VideoSectionRepositoryImplTest.kt | 153 ++-- 17 files changed, 1325 insertions(+), 196 deletions(-) create mode 100644 data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json create mode 100644 data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt create mode 100644 data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt create mode 100644 data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt create mode 100644 data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt create mode 100644 data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt index a9ef76917b..dd27529c99 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt @@ -22,6 +22,8 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -41,6 +43,7 @@ import mega.privacy.android.app.presentation.videosection.model.VideoSectionMenu import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity import mega.privacy.android.app.presentation.videosection.view.VideoSectionFeatureScreen +import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute import mega.privacy.android.app.presentation.videosection.view.videoSectionRoute import mega.privacy.android.app.utils.Constants.ORDER_CLOUD import mega.privacy.android.app.utils.Constants.ORDER_VIDEO_PLAYLIST @@ -227,6 +230,7 @@ class VideoSectionFragment : Fragment() { /** * onViewCreated */ + @OptIn(FlowPreview::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { (activity as? ManagerActivity)?.let { managerActivity -> managerActivity.supportActionBar?.hide() @@ -236,11 +240,15 @@ class VideoSectionFragment : Fragment() { } viewLifecycleOwner.collectFlow( - videoSectionViewModel.state.map { it.isPendingRefresh }.distinctUntilChanged() + videoSectionViewModel.state.map { it.isPendingRefresh }.debounce(500L) + .distinctUntilChanged() ) { isPendingRefresh -> if (isPendingRefresh) { with(videoSectionViewModel) { refreshNodes() + if (state.value.currentDestinationRoute == videoRecentlyWatchedRoute) { + loadRecentlyWatchedVideos() + } markHandledPendingRefresh() } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt index d5b932c795..a8f65b67ea 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge @@ -37,7 +38,8 @@ import mega.privacy.android.app.presentation.videosection.model.VideoSectionStat import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoSectionTabState import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity -import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute +import mega.privacy.android.domain.entity.VideoFileTypeInfo +import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.entity.node.TypedNode @@ -182,16 +184,17 @@ class VideoSectionViewModel @Inject constructor( private fun refreshNodesIfAnyUpdates() { viewModelScope.launch { merge( - monitorNodeUpdatesUseCase(), + monitorNodeUpdatesUseCase().filter { + it.changes.keys.any { node -> + node is FileNode && node.type is VideoFileTypeInfo + } + }, monitorOfflineNodeUpdatesUseCase() ).conflate() .catch { Timber.e(it) }.collect { setPendingRefreshNodes() - if (_state.value.currentDestinationRoute == videoRecentlyWatchedRoute) { - loadRecentlyWatchedVideos() - } } } } diff --git a/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt index fcb76116be..cdb51af9a3 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt @@ -20,12 +20,13 @@ import mega.privacy.android.app.presentation.videosection.model.LocationFilterOp import mega.privacy.android.app.presentation.videosection.model.VideoPlaylistUIEntity import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity -import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension import mega.privacy.android.domain.entity.Offline import mega.privacy.android.domain.entity.SortOrder +import mega.privacy.android.domain.entity.VideoFileTypeInfo import mega.privacy.android.domain.entity.account.AccountDetail import mega.privacy.android.domain.entity.node.ExportedData +import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.NodeContentUri import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.NodeUpdate @@ -256,10 +257,13 @@ class VideoSectionViewModelTest { @Test fun `test that isPendingRefresh is correctly updated when monitorNodeUpdatesUseCase is triggered`() = runTest { + val testFileNode = mock { + on { type }.thenReturn(VideoFileTypeInfo("video", "mp4", 10.seconds)) + } testScheduler.advanceUntilIdle() underTest.state.drop(1).test { - fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(emptyMap())) + fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(mapOf(testFileNode to emptyList()))) assertThat(awaitItem().isPendingRefresh).isTrue() underTest.markHandledPendingRefresh() @@ -1512,54 +1516,6 @@ class VideoSectionViewModelTest { } } - @Test - fun `test that state is correctly updated when monitorOfflineNodeUpdatesUseCase is triggered`() = - runTest { - val testHandle = 1L - val testTimestamp = 1000L - val testWatchDate = "12 April 2024" - val testVideoNodes = listOf(initTypedVideoNode(testHandle, testTimestamp)) - val testVideoEntity = initVideoUIEntity(testHandle, testWatchDate) - val expectedRecentlyWatchedItems = mapOf((testWatchDate to listOf(testVideoEntity))) - whenever(videoUIEntityMapper(anyOrNull())).thenReturn(testVideoEntity) - whenever(getVideoRecentlyWatchedUseCase()).thenReturn(testVideoNodes) - - testScheduler.advanceUntilIdle() - underTest.setCurrentDestinationRoute(videoRecentlyWatchedRoute) - - underTest.state.drop(2).test { - fakeMonitorOfflineNodeUpdatesFlow.emit(emptyList()) - assertThat(awaitItem().groupedVideoRecentlyWatchedItems).isEqualTo( - expectedRecentlyWatchedItems - ) - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun `test that state is correctly updated when monitorNodeUpdatesUseCase is triggered`() = - runTest { - val testHandle = 1L - val testTimestamp = 1000L - val testWatchDate = "12 April 2024" - val testVideoNodes = listOf(initTypedVideoNode(testHandle, testTimestamp)) - val testVideoEntity = initVideoUIEntity(testHandle, testWatchDate) - val expectedRecentlyWatchedItems = mapOf((testWatchDate to listOf(testVideoEntity))) - whenever(videoUIEntityMapper(anyOrNull())).thenReturn(testVideoEntity) - whenever(getVideoRecentlyWatchedUseCase()).thenReturn(testVideoNodes) - - testScheduler.advanceUntilIdle() - underTest.setCurrentDestinationRoute(videoRecentlyWatchedRoute) - - underTest.state.drop(2).test { - fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(emptyMap())) - assertThat(awaitItem().groupedVideoRecentlyWatchedItems).isEqualTo( - expectedRecentlyWatchedItems - ) - cancelAndIgnoreRemainingEvents() - } - } - companion object { @JvmField @RegisterExtension diff --git a/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json b/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json new file mode 100644 index 0000000000..5dddbe4f42 --- /dev/null +++ b/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json @@ -0,0 +1,744 @@ +{ + "formatVersion": 1, + "database": { + "version": 90, + "identityHash": "a057a802e7cd89ee44458a027f7cf700", + "entities": [ + { + "tableName": "contacts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `handle` TEXT, `mail` TEXT, `name` TEXT, `lastname` TEXT, `nickname` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "handle", + "columnName": "handle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mail", + "columnName": "mail", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstName", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastName", + "columnName": "lastname", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nickName", + "columnName": "nickname", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "completedtransfers_2", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `transferfilename` TEXT NOT NULL, `transfertype` INTEGER NOT NULL, `transferstate` INTEGER NOT NULL, `transfersize` TEXT NOT NULL, `transferhandle` INTEGER NOT NULL, `transferpath` TEXT NOT NULL, `transferoffline` INTEGER, `transfertimestamp` INTEGER NOT NULL, `transfererror` TEXT, `transferoriginalpath` TEXT NOT NULL, `transferparenthandle` INTEGER NOT NULL, `transferappdata` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "fileName", + "columnName": "transferfilename", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "transfertype", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "transferstate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "size", + "columnName": "transfersize", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "handle", + "columnName": "transferhandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "path", + "columnName": "transferpath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isOffline", + "columnName": "transferoffline", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "transfertimestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "transfererror", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalPath", + "columnName": "transferoriginalpath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentHandle", + "columnName": "transferparenthandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "appData", + "columnName": "transferappdata", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "completedtransfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `transferfilename` TEXT, `transfertype` TEXT, `transferstate` TEXT, `transfersize` TEXT, `transferhandle` TEXT, `transferpath` TEXT, `transferoffline` TEXT, `transfertimestamp` TEXT, `transfererror` TEXT, `transferoriginalpath` TEXT, `transferparenthandle` TEXT, `transferappdata` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "fileName", + "columnName": "transferfilename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "transfertype", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "transferstate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "transfersize", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "handle", + "columnName": "transferhandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "path", + "columnName": "transferpath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isOffline", + "columnName": "transferoffline", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "transfertimestamp", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "transfererror", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalPath", + "columnName": "transferoriginalpath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "parentHandle", + "columnName": "transferparenthandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "appData", + "columnName": "transferappdata", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "active_transfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` INTEGER NOT NULL, `transfer_type` TEXT NOT NULL, `total_bytes` INTEGER NOT NULL, `is_finished` INTEGER NOT NULL, `is_folder_transfer` INTEGER NOT NULL DEFAULT 0, `is_paused` INTEGER NOT NULL DEFAULT 0, `is_already_downloaded` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`tag`))", + "fields": [ + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "transferType", + "columnName": "transfer_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalBytes", + "columnName": "total_bytes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFinished", + "columnName": "is_finished", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFolderTransfer", + "columnName": "is_folder_transfer", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "isPaused", + "columnName": "is_paused", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "isAlreadyTransferred", + "columnName": "is_already_downloaded", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tag" + ] + }, + "indices": [ + { + "name": "index_active_transfers_transfer_type", + "unique": false, + "columnNames": [ + "transfer_type" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_active_transfers_transfer_type` ON `${TABLE_NAME}` (`transfer_type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "sdtransfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `sdtransfertag` INTEGER, `sdtransfername` TEXT, `sdtransfersize` TEXT, `sdtransferhandle` TEXT, `sdtransferappdata` TEXT, `sdtransferpath` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tag", + "columnName": "sdtransfertag", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedName", + "columnName": "sdtransfername", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedSize", + "columnName": "sdtransfersize", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedHandle", + "columnName": "sdtransferhandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedAppData", + "columnName": "sdtransferappdata", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedPath", + "columnName": "sdtransferpath", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "backups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `backup_id` TEXT NOT NULL, `backup_type` INTEGER NOT NULL, `target_node` TEXT NOT NULL, `local_folder` TEXT NOT NULL, `backup_name` TEXT NOT NULL, `state` INTEGER NOT NULL, `sub_state` INTEGER NOT NULL, `extra_data` TEXT NOT NULL, `start_timestamp` TEXT NOT NULL, `last_sync_timestamp` TEXT NOT NULL, `target_folder_path` TEXT NOT NULL, `exclude_subFolders` TEXT NOT NULL, `delete_empty_subFolders` TEXT NOT NULL, `outdated` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedBackupId", + "columnName": "backup_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backupType", + "columnName": "backup_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "encryptedTargetNode", + "columnName": "target_node", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedLocalFolder", + "columnName": "local_folder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedBackupName", + "columnName": "backup_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subState", + "columnName": "sub_state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "encryptedExtraData", + "columnName": "extra_data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedStartTimestamp", + "columnName": "start_timestamp", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedLastFinishTimestamp", + "columnName": "last_sync_timestamp", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedTargetFolderPath", + "columnName": "target_folder_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedShouldExcludeSubFolders", + "columnName": "exclude_subFolders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedShouldDeleteEmptySubFolders", + "columnName": "delete_empty_subFolders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedIsOutdated", + "columnName": "outdated", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "offline", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `handle` TEXT, `path` TEXT, `name` TEXT, `parentId` INTEGER, `type` TEXT, `incoming` INTEGER, `incomingHandle` TEXT, `lastModifiedTime` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedHandle", + "columnName": "handle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedPath", + "columnName": "path", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedName", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedType", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "incoming", + "columnName": "incoming", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedIncomingHandle", + "columnName": "incomingHandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastModifiedTime", + "columnName": "lastModifiedTime", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "syncsolvedissues", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`entityId` INTEGER PRIMARY KEY AUTOINCREMENT, `syncId` INTEGER NOT NULL DEFAULT -1, `nodeIds` TEXT NOT NULL, `localPaths` TEXT NOT NULL, `resolutionExplanation` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "syncId", + "columnName": "syncId", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "-1" + }, + { + "fieldPath": "nodeIds", + "columnName": "nodeIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localPaths", + "columnName": "localPaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resolutionExplanation", + "columnName": "resolutionExplanation", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "entityId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "userpausedsyncs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sync_id` INTEGER NOT NULL, PRIMARY KEY(`sync_id`))", + "fields": [ + { + "fieldPath": "syncId", + "columnName": "sync_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "sync_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "camerauploadsrecords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`media_id` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `folder_type` TEXT NOT NULL, `file_name` TEXT NOT NULL, `file_path` TEXT NOT NULL, `file_type` TEXT NOT NULL, `upload_status` TEXT NOT NULL, `original_fingerprint` TEXT NOT NULL, `generated_fingerprint` TEXT, `temp_file_path` TEXT NOT NULL, PRIMARY KEY(`media_id`, `timestamp`, `folder_type`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "media_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderType", + "columnName": "folder_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fileName", + "columnName": "file_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "filePath", + "columnName": "file_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fileType", + "columnName": "file_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uploadStatus", + "columnName": "upload_status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originalFingerprint", + "columnName": "original_fingerprint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "generatedFingerprint", + "columnName": "generated_fingerprint", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tempFilePath", + "columnName": "temp_file_path", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "media_id", + "timestamp", + "folder_type" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "chatroompreference", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chatId` INTEGER NOT NULL, `draft_message` TEXT NOT NULL, `editing_message_id` INTEGER, PRIMARY KEY(`chatId`))", + "fields": [ + { + "fieldPath": "chatId", + "columnName": "chatId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "draftMessage", + "columnName": "draft_message", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "editingMessageId", + "columnName": "editing_message_id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chatId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recentlywatchedvideo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`videoHandle` INTEGER NOT NULL, `watched_timestamp` INTEGER NOT NULL, PRIMARY KEY(`videoHandle`))", + "fields": [ + { + "fieldPath": "videoHandle", + "columnName": "videoHandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "watchedTimestamp", + "columnName": "watched_timestamp", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "videoHandle" + ] + }, + "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, 'a057a802e7cd89ee44458a027f7cf700')" + ] + } +} \ No newline at end of file diff --git a/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt b/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt new file mode 100644 index 0000000000..1d53e639f5 --- /dev/null +++ b/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt @@ -0,0 +1,197 @@ +package mega.privacy.android.data.database.dao + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import mega.privacy.android.data.database.MegaDatabase +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.io.IOException + +@RunWith(AndroidJUnit4::class) +class VideoRecentlyWatchedDaoTest { + private lateinit var videoRecentlyWatchedDao: VideoRecentlyWatchedDao + private lateinit var db: MegaDatabase + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder( + context, MegaDatabase::class.java + ).build() + videoRecentlyWatchedDao = db.videoRecentlyWatchedDao() + } + + @After + @Throws(IOException::class) + fun closeDb() { + db.close() + } + + @Test + fun `test_that_getAllRecentlyWatchedVideos_returns_as_expected`() = runTest { + val entities = (1..100L).map { + val entity = VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(entity) + entity + } + + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + .forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(entities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(entities[index].watchedTimestamp) + } + } + + @Test + fun `test_that_table_empty_when_call_clearRecentlyWatchedVideos`() = runTest { + (1..100L).map { + val entity = VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(entity) + } + + videoRecentlyWatchedDao.clearRecentlyWatchedVideos() + assertThat(videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first()).isEmpty() + } + + @Test + fun `test_that_corresponding_item_is_deleted_after_call_removeRecentlyWatchedVideo`() = + runTest { + val testEntities = (1..10L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + val removedHandle = 5L + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + } + + videoRecentlyWatchedDao.removeRecentlyWatchedVideo(removedHandle) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size - 1) + assertThat(entities.find { it.videoHandle == removedHandle }).isNull() + } + + @Test + fun `test_that_corresponding_item_is_added_after_call_insertOrUpdateRecentlyWatchedVideo`() = + runTest { + val expectedVideoHandle = 123456L + val expectedTimestamp = 1000000L + val newEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, expectedTimestamp) + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(newEntity) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) + } + } + + @Test + fun `test_that_corresponding_item_is_updated_after_call_insertOrUpdateRecentlyWatchedVideo_if_item_exists`() = + runTest { + val expectedVideoHandle = 123456L + val expectedTimestamp = 1000000L + val newTimestamp = 200000L + val testEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, expectedTimestamp) + val newEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, newTimestamp) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(testEntity) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) + } + } + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(newEntity) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(newTimestamp) + } + } + } + + @Test + fun `test_that_corresponding_items_are_added_after_call_insertOrUpdateRecentlyWatchedVideos`() = + runTest { + val testEntities = (1..100L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + entities.forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(testEntities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(testEntities[index].watchedTimestamp) + } + } + + @Test + fun `test_that_corresponding_items_are_updated_after_call_insertOrUpdateRecentlyWatchedVideos_if_items_exists`() = + runTest { + val testEntities = (1..100L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + val newEntities = (10L downTo 1).mapIndexed { index, it -> + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = index.toLong() + ) + } + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + entities.forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(testEntities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(testEntities[index].watchedTimestamp) + } + } + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(newEntities) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + newEntities.map { entity -> + assertThat( + entities.first { + it.videoHandle == entity.videoHandle + }.watchedTimestamp + ).isEqualTo( + entity.watchedTimestamp + ) + } + } +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt index ad2bf09ea0..7d0fc4d005 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt @@ -18,6 +18,7 @@ import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao import mega.privacy.android.data.database.dao.SyncSolvedIssuesDao import mega.privacy.android.data.database.dao.UserPausedSyncsDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.database.entity.ActiveTransferEntity import mega.privacy.android.data.database.entity.BackupEntity import mega.privacy.android.data.database.entity.CameraUploadsRecordEntity @@ -29,6 +30,7 @@ import mega.privacy.android.data.database.entity.OfflineEntity import mega.privacy.android.data.database.entity.SdTransferEntity import mega.privacy.android.data.database.entity.SyncSolvedIssueEntity import mega.privacy.android.data.database.entity.UserPausedSyncEntity +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity import mega.privacy.android.data.database.spec.AutoMigrationSpec73to74 import mega.privacy.android.data.database.spec.AutoMigrationSpec81to82 import timber.log.Timber @@ -46,6 +48,7 @@ import timber.log.Timber UserPausedSyncEntity::class, CameraUploadsRecordEntity::class, ChatPendingChangesEntity::class, + VideoRecentlyWatchedEntity::class, ], version = MegaDatabaseConstant.DATABASE_VERSION, exportSchema = true, @@ -62,7 +65,7 @@ import timber.log.Timber AutoMigration(84, 85), AutoMigration(86, 87), AutoMigration(87, 88), - AutoMigration(88, 89), + AutoMigration(89, 90), ], ) internal abstract class MegaDatabase : RoomDatabase() { @@ -86,6 +89,8 @@ internal abstract class MegaDatabase : RoomDatabase() { abstract fun chatPendingChangesDao(): ChatPendingChangesDao + abstract fun videoRecentlyWatchedDao(): VideoRecentlyWatchedDao + companion object { /** diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt index f843c935f2..ace30a66da 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt @@ -8,7 +8,7 @@ object MegaDatabaseConstant { /** * Database Version */ - const val DATABASE_VERSION = 89 + const val DATABASE_VERSION = 90 /** * Database Name @@ -74,4 +74,9 @@ object MegaDatabaseConstant { * Passphrase File Name */ const val PASSPHRASE_FILE_NAME = "passphrase.bin" + + /** + * Table recently watched video + */ + const val TABLE_RECENTLY_WATCHED_VIDEO = "recentlywatchedvideo" } diff --git a/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt b/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt new file mode 100644 index 0000000000..8449a0719e --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt @@ -0,0 +1,27 @@ +package mega.privacy.android.data.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import kotlinx.coroutines.flow.Flow +import mega.privacy.android.data.database.MegaDatabaseConstant +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity + +@Dao +internal interface VideoRecentlyWatchedDao { + @Query("SELECT * FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO}") + fun getAllRecentlyWatchedVideos(): Flow> + + @Query("DELETE FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO}") + suspend fun clearRecentlyWatchedVideos() + + @Query("DELETE FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO} WHERE videoHandle = :handle") + suspend fun removeRecentlyWatchedVideo(handle: Long) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdateRecentlyWatchedVideo(entity: VideoRecentlyWatchedEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdateRecentlyWatchedVideos(entities: List) +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt b/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt new file mode 100644 index 0000000000..2bf25f48aa --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt @@ -0,0 +1,14 @@ +package mega.privacy.android.data.database.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import mega.privacy.android.data.database.MegaDatabaseConstant + +@Entity(tableName = MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO) +internal data class VideoRecentlyWatchedEntity( + @PrimaryKey + val videoHandle: Long = 0L, + @ColumnInfo(name = "watched_timestamp") + val watchedTimestamp: Long = 0L, +) diff --git a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt index ac2d71201b..caaabca39d 100644 --- a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt @@ -28,6 +28,7 @@ import mega.privacy.android.data.database.dao.SdTransferDao import mega.privacy.android.data.database.dao.SyncSolvedIssuesDao import mega.privacy.android.data.database.dao.TypedMessageDao import mega.privacy.android.data.database.dao.UserPausedSyncsDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import net.sqlcipher.database.SupportFactory import timber.log.Timber import java.io.File @@ -205,4 +206,9 @@ internal object RoomDatabaseModule { internal fun provideTypedMessageRequestDao(chatDatabase: ChatDatabase): TypedMessageDao = chatDatabase.typedMessageDao() + @Provides + @Singleton + internal fun provideVideoRecentlyWatchedDao(database: MegaDatabase): VideoRecentlyWatchedDao = + database.videoRecentlyWatchedDao() + } diff --git a/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt index 879c3bdabd..fac551ba0c 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt @@ -13,6 +13,7 @@ import mega.privacy.android.data.database.dao.CompletedTransferDao import mega.privacy.android.data.database.dao.ContactDao import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.gateway.MegaLocalRoomGateway import mega.privacy.android.data.mapper.backup.BackupEntityMapper import mega.privacy.android.data.mapper.backup.BackupInfoTypeIntMapper @@ -31,6 +32,9 @@ import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferLega import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferModelMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferEntityMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferModelMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedEntityMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedItemMapper +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.Contact import mega.privacy.android.domain.entity.Offline @@ -74,6 +78,9 @@ internal class MegaLocalRoomFacade @Inject constructor( private val chatPendingChangesDao: ChatPendingChangesDao, private val chatRoomPendingChangesEntityMapper: ChatRoomPendingChangesEntityMapper, private val chatRoomPendingChangesModelMapper: ChatRoomPendingChangesModelMapper, + private val videoRecentlyWatchedDao: VideoRecentlyWatchedDao, + private val videoRecentlyWatchedEntityMapper: VideoRecentlyWatchedEntityMapper, + private val videoRecentlyWatchedItemMapper: VideoRecentlyWatchedItemMapper, ) : MegaLocalRoomGateway { override suspend fun insertContact(contact: Contact) { contactDao.insertOrUpdateContact(contactEntityMapper(contact)) @@ -449,6 +456,29 @@ internal class MegaLocalRoomFacade @Inject constructor( ) } + override suspend fun getAllRecentlyWatchedVideos() = + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().map { entities -> + entities.map { entity -> + videoRecentlyWatchedItemMapper(entity.videoHandle, entity.watchedTimestamp) + } + } + + override suspend fun removeRecentlyWatchedVideo(handle: Long) = + videoRecentlyWatchedDao.removeRecentlyWatchedVideo(handle) + + override suspend fun clearRecentlyWatchedVideos() = + videoRecentlyWatchedDao.clearRecentlyWatchedVideos() + + override suspend fun saveRecentlyWatchedVideo(item: VideoRecentlyWatchedItem) { + val entity = videoRecentlyWatchedEntityMapper(item) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(entity) + } + + override suspend fun saveRecentlyWatchedVideos(items: List) { + val entities = items.map { videoRecentlyWatchedEntityMapper(it) } + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(entities) + } + override fun monitorChatPendingChanges(chatId: Long): Flow = chatPendingChangesDao.getChatPendingChanges(chatId) .map { entity -> entity?.let { chatRoomPendingChangesModelMapper(it) } } diff --git a/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt b/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt index 1aed34c56b..a3d78ea397 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt @@ -1,6 +1,7 @@ package mega.privacy.android.data.gateway import kotlinx.coroutines.flow.Flow +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.Contact import mega.privacy.android.domain.entity.Offline @@ -460,4 +461,37 @@ interface MegaLocalRoomGateway { * @param chatPendingChanges [ChatPendingChanges] */ suspend fun setChatPendingChanges(chatPendingChanges: ChatPendingChanges) + + /** + * Get all recently watched videos + * + * @return flow of [VideoRecentlyWatchedItem] list + */ + suspend fun getAllRecentlyWatchedVideos(): Flow> + + /** + * Remove recently watched video + * + * @param handle removed video handle + */ + suspend fun removeRecentlyWatchedVideo(handle: Long) + + /** + * Clear recently watched videos + */ + suspend fun clearRecentlyWatchedVideos() + + /** + * Save recently watched video + * + * @param item saved [VideoRecentlyWatchedItem] + */ + suspend fun saveRecentlyWatchedVideo(item: VideoRecentlyWatchedItem) + + /** + * Save recently watched videos + * + * @param items [VideoRecentlyWatchedItem] list + */ + suspend fun saveRecentlyWatchedVideos(items: List) } diff --git a/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt b/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt new file mode 100644 index 0000000000..1ab400eac7 --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt @@ -0,0 +1,11 @@ +package mega.privacy.android.data.mapper.videosection + +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import mega.privacy.android.data.model.VideoRecentlyWatchedItem +import javax.inject.Inject + +internal class VideoRecentlyWatchedEntityMapper @Inject constructor() { + + operator fun invoke(item: VideoRecentlyWatchedItem) = + VideoRecentlyWatchedEntity(item.videoHandle, item.watchedTimestamp) +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt index 4b99347402..085c58d74b 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt @@ -67,7 +67,6 @@ internal class VideoSectionRepositoryImpl @Inject constructor( ) : VideoSectionRepository { private val videoPlaylistsMap: MutableMap = mutableMapOf() private val videoSetsMap: MutableMap> = mutableMapOf() - private val recentlyWatchedVideosData = mutableListOf() override suspend fun getAllVideos(order: SortOrder): List = withContext(ioDispatcher) { @@ -305,44 +304,39 @@ internal class VideoSectionRepositoryImpl @Inject constructor( override suspend fun getVideoPlaylistSets(): List = getAllUserSets() - override suspend fun saveVideoRecentlyWatched(handle: Long, timestamp: Long) { - initVideoRecentlyWatchedData() - recentlyWatchedVideosData.indexOfFirst { it.videoHandle == handle }.let { index -> - if (index == -1) { - recentlyWatchedVideosData.add(videoRecentlyWatchedItemMapper(handle, timestamp)) - } else { - recentlyWatchedVideosData[index] = - recentlyWatchedVideosData[index].copy(watchedTimestamp = timestamp) - } - - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) + override suspend fun saveVideoRecentlyWatched(handle: Long, timestamp: Long) = + withContext(ioDispatcher) { + migrateOldDataToDatabase() + megaLocalRoomGateway.saveRecentlyWatchedVideo( + videoRecentlyWatchedItemMapper( + handle, + timestamp + ) ) } - } - private suspend fun initVideoRecentlyWatchedData() { - if (recentlyWatchedVideosData.isEmpty()) { - getRecentlyWatchedData()?.let { - recentlyWatchedVideosData.addAll(it) + private suspend fun migrateOldDataToDatabase() = withContext(ioDispatcher) { + val items: List? = + appPreferencesGateway.monitorString( + PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, + null + ).firstOrNull()?.let { jsonString -> + Json.decodeFromString(jsonString) } - } - } + if (items.isNullOrEmpty()) return@withContext - private suspend fun getRecentlyWatchedData(): List? = - appPreferencesGateway.monitorString( + megaLocalRoomGateway.saveRecentlyWatchedVideos(items) + + appPreferencesGateway.putString( PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - null - ).firstOrNull()?.let { jsonString -> - Json.decodeFromString(jsonString) - } + Json.encodeToString(emptyList()) + ) + } override suspend fun getRecentlyWatchedVideoNodes(): List = withContext(ioDispatcher) { - initVideoRecentlyWatchedData() val offlineItems = getAllOfflineNodeHandle() - recentlyWatchedVideosData.mapNotNull { item -> + getRecentlyWatchedData()?.mapNotNull { item -> megaApiGateway.getMegaNodeByHandle(item.videoHandle)?.let { megaNode -> typedVideoNodeMapper( fileNode = megaNode.convertToFileNode(offlineItems[megaNode.handle.toString()]), @@ -350,28 +344,24 @@ internal class VideoSectionRepositoryImpl @Inject constructor( watchedTimestamp = item.watchedTimestamp ) } - }.sortedByDescending { it.watchedTimestamp } + }?.sortedByDescending { it.watchedTimestamp } ?: emptyList() } - override suspend fun clearRecentlyWatchedVideos() = withContext(ioDispatcher) { - recentlyWatchedVideosData.clear() - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) - ) + private suspend fun getRecentlyWatchedData(): List? { + migrateOldDataToDatabase() + return megaLocalRoomGateway.getAllRecentlyWatchedVideos().firstOrNull() } - override suspend fun removeRecentlyWatchedItem(handle: Long) { - initVideoRecentlyWatchedData() - recentlyWatchedVideosData.removeAll { it.videoHandle == handle } - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) - ) + override suspend fun clearRecentlyWatchedVideos() = withContext(ioDispatcher) { + megaLocalRoomGateway.clearRecentlyWatchedVideos() } + override suspend fun removeRecentlyWatchedItem(handle: Long) = + megaLocalRoomGateway.removeRecentlyWatchedVideo(handle) + companion object { private const val PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS = "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS" } } + diff --git a/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt b/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt index 165476dbd6..03775fb4e0 100644 --- a/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt +++ b/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt @@ -15,6 +15,7 @@ import mega.privacy.android.data.database.dao.CompletedTransferDao import mega.privacy.android.data.database.dao.ContactDao import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.database.entity.ActiveTransferEntity import mega.privacy.android.data.database.entity.BackupEntity import mega.privacy.android.data.database.entity.CameraUploadsRecordEntity @@ -22,6 +23,7 @@ import mega.privacy.android.data.database.entity.ChatPendingChangesEntity import mega.privacy.android.data.database.entity.CompletedTransferEntity import mega.privacy.android.data.database.entity.CompletedTransferEntityLegacy import mega.privacy.android.data.database.entity.SdTransferEntity +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity import mega.privacy.android.data.facade.MegaLocalRoomFacade.Companion.MAX_INSERT_LIST_SIZE import mega.privacy.android.data.mapper.backup.BackupEntityMapper import mega.privacy.android.data.mapper.backup.BackupInfoTypeIntMapper @@ -40,6 +42,9 @@ import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferLega import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferModelMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferEntityMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferModelMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedEntityMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedItemMapper +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.SdTransfer import mega.privacy.android.domain.entity.backup.Backup @@ -96,6 +101,9 @@ internal class MegaLocalRoomFacadeTest { private val chatRoomPendingChangesEntityMapper: ChatRoomPendingChangesEntityMapper = mock() private val chatRoomPendingChangesModelMapper: ChatRoomPendingChangesModelMapper = mock() private val completedTransferLegacyModelMapper = mock() + private val videoRecentlyWatchedDao: VideoRecentlyWatchedDao = mock() + private val videoRecentlyWatchedEntityMapper: VideoRecentlyWatchedEntityMapper = mock() + private val videoRecentlyWatchedItemMapper: VideoRecentlyWatchedItemMapper = mock() @BeforeAll fun setUp() { @@ -127,6 +135,9 @@ internal class MegaLocalRoomFacadeTest { chatPendingChangesDao = chatPendingChangesDao, chatRoomPendingChangesEntityMapper = chatRoomPendingChangesEntityMapper, chatRoomPendingChangesModelMapper = chatRoomPendingChangesModelMapper, + videoRecentlyWatchedDao = videoRecentlyWatchedDao, + videoRecentlyWatchedItemMapper = videoRecentlyWatchedItemMapper, + videoRecentlyWatchedEntityMapper = videoRecentlyWatchedEntityMapper ) } @@ -152,6 +163,9 @@ internal class MegaLocalRoomFacadeTest { chatRoomPendingChangesEntityMapper, chatRoomPendingChangesModelMapper, completedTransferLegacyModelMapper, + videoRecentlyWatchedDao, + videoRecentlyWatchedItemMapper, + videoRecentlyWatchedEntityMapper ) } @@ -702,4 +716,79 @@ internal class MegaLocalRoomFacadeTest { verify(completedTransferDao, never()).deleteAllLegacyCompletedTransfers() } + + @Test + fun `test that removeRecentlyWatchedVideo invokes as expected`() = + runTest { + val testVideoHandle = 123456L + underTest.removeRecentlyWatchedVideo(testVideoHandle) + verify(videoRecentlyWatchedDao).removeRecentlyWatchedVideo(testVideoHandle) + } + + @Test + fun `test that clearRecentlyWatchedVideos invokes as expected`() = + runTest { + underTest.clearRecentlyWatchedVideos() + verify(videoRecentlyWatchedDao).clearRecentlyWatchedVideos() + } + + @Test + fun `test that saveRecentlyWatchedVideo insert the mapped entity`() = runTest { + val testItem = mock() + val testEntity = mock() + whenever(videoRecentlyWatchedEntityMapper(testItem)).thenReturn(testEntity) + + underTest.saveRecentlyWatchedVideo(testItem) + verify(videoRecentlyWatchedDao).insertOrUpdateRecentlyWatchedVideo(testEntity) + } + + @Test + fun `test that saveRecentlyWatchedVideos insert the mapped entities`() = runTest { + val testItems = (1..100).map { + mock() + } + val testEntities = (1..100).map { + mock() + } + testItems.forEachIndexed { index, item -> + whenever(videoRecentlyWatchedEntityMapper(item)).thenReturn(testEntities[index]) + } + + underTest.saveRecentlyWatchedVideos(testItems) + verify(videoRecentlyWatchedDao).insertOrUpdateRecentlyWatchedVideos(testEntities) + } + + @Test + fun `test that getAllRecentlyWatchedVideos returns as expected`() = + runTest { + val testItems = (1..100L).map { value -> + mock { + on { videoHandle }.thenReturn(value) + on { watchedTimestamp }.thenReturn(value) + } + } + val testEntities = (1..100L).map { value -> + mock { + on { videoHandle }.thenReturn(value) + on { watchedTimestamp }.thenReturn(value) + } + } + whenever(videoRecentlyWatchedDao.getAllRecentlyWatchedVideos()).thenReturn( + flowOf( + testEntities + ) + ) + testItems.forEachIndexed { index, item -> + whenever( + videoRecentlyWatchedItemMapper( + testEntities[index].videoHandle, + testEntities[index].watchedTimestamp + ) + ).thenReturn(item) + } + underTest.getAllRecentlyWatchedVideos().test { + assertThat(awaitItem()).isEqualTo(testItems) + awaitComplete() + } + } } diff --git a/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt b/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt new file mode 100644 index 0000000000..c90f12668d --- /dev/null +++ b/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt @@ -0,0 +1,47 @@ +package mega.privacy.android.data.mapper.videosection + +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import mega.privacy.android.data.model.VideoRecentlyWatchedItem +import org.junit.jupiter.api.Assertions.assertAll +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.mockito.kotlin.mock + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class VideoRecentlyWatchedEntityMapperTest { + private lateinit var underTest: VideoRecentlyWatchedEntityMapper + + private val expectedHandle = 123456L + private val expectedTimestamp = 100000L + private val expectedVideoRecentlyWatchedItem = mock { + on { videoHandle }.thenReturn(expectedHandle) + on { watchedTimestamp }.thenReturn(expectedTimestamp) + } + + @BeforeAll + fun setUp() { + underTest = VideoRecentlyWatchedEntityMapper() + } + + @Test + fun `test that VideoRecentlyWatchedItem can be mapped correctly`() = + runTest { + val item = underTest(expectedVideoRecentlyWatchedItem) + assertMappedVideoRecentlyWatchedItemObject(item) + } + + private fun assertMappedVideoRecentlyWatchedItemObject( + item: VideoRecentlyWatchedEntity, + ) { + item.let { + assertAll( + "Grouped Assertions of ${VideoRecentlyWatchedEntity::class.simpleName}", + { assertThat(it.videoHandle).isEqualTo(expectedHandle) }, + { assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) }, + ) + } + } +} \ No newline at end of file diff --git a/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt b/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt index 71f7766a13..727a2b50a1 100644 --- a/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt +++ b/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt @@ -641,7 +641,7 @@ class VideoSectionRepositoryImplTest { } @Test - fun `test that saveVideoRecentlyWatched function is invoked with the correct parameters`() = + fun `test that saveVideoRecentlyWatched function is invoked as expected with migrating the old data`() = runTest { val testHandle = 12345L val testTimestamp = 100000L @@ -650,102 +650,86 @@ class VideoSectionRepositoryImplTest { } val addedHandle = 54321L val addedTimestamp = 200000L - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - testVideoRecentlyWatchedData.add(addedRecentlyWatchedItem) - val newJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() + val jsonString = Json.encodeToString(testVideoRecentlyWatchedData) whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) + flowOf(jsonString) ) - whenever(videoRecentlyWatchedItemMapper(addedHandle, addedTimestamp)).thenReturn( + whenever(videoRecentlyWatchedItemMapper(anyOrNull(), anyOrNull())).thenReturn( addedRecentlyWatchedItem ) + initUnderTest() underTest.saveVideoRecentlyWatched(addedHandle, addedTimestamp) + verify(megaLocalRoomGateway).saveRecentlyWatchedVideos(testVideoRecentlyWatchedData) verify(appPreferencesGateway).putString( "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - newJsonString + Json.encodeToString(emptyList()) ) + verify(megaLocalRoomGateway).saveRecentlyWatchedVideo(addedRecentlyWatchedItem) } @Test - fun `test that saveVideoRecentlyWatched function updated the existing value when added video node is existing`() = + fun `test that getRecentlyWatchedVideoNodes returns the correct result with migrating the old data`() = runTest { val testHandle = 12345L val testTimestamp = 100000L val testVideoRecentlyWatchedData = mutableListOf().apply { add(VideoRecentlyWatchedItem(testHandle, testTimestamp)) } - val addedHandle = 12345L - val addedTimestamp = 200000L - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - testVideoRecentlyWatchedData[0] = addedRecentlyWatchedItem - val newJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() + val jsonString = Json.encodeToString(testVideoRecentlyWatchedData) whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - whenever(videoRecentlyWatchedItemMapper(addedHandle, addedTimestamp)).thenReturn( - addedRecentlyWatchedItem + flowOf(jsonString) ) - underTest.saveVideoRecentlyWatched(addedHandle, addedTimestamp) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - newJsonString - ) - } + val testHandles = listOf(12345L, 23456L, 34567L) + val testTimestamps = listOf(100000L, 200000L, 300000L) - @Test - fun `test that getRecentlyWatchedVideoNodes returns the correct result`() = runTest { - val testHandles = listOf(12345L, 23456L, 34567L) - val testTimestamps = listOf(100000L, 200000L, 300000L) - val testVideoRecentlyWatchedData = mutableListOf() - testHandles.mapIndexed { index, handle -> - testVideoRecentlyWatchedData.add( + val testItems = testHandles.mapIndexed { index, handle -> VideoRecentlyWatchedItem( - handle, - testTimestamps[index] + handle, testTimestamps[index] ) - ) - } - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) + } - val testMegaNodes = testHandles.map { handle -> - initMegaNode(handle) - } - val testFileNodes = testHandles.map { - mock() - } - val testTypedVideoNodes = testHandles.mapIndexed { index, handle -> - initTypedVideoNode(handle, testTimestamps[index]) - } - testMegaNodes.mapIndexed { index, node -> - whenever(megaApiGateway.getMegaNodeByHandle(node.handle)).thenReturn(node) - whenever(fileNodeMapper(node, false, null)).thenReturn(testFileNodes[index]) - whenever( - typedVideoNodeMapper( - fileNode = testFileNodes[index], - duration = 100, - watchedTimestamp = testTimestamps[index] + val testMegaNodes = testHandles.map { handle -> + initMegaNode(handle) + } + val testFileNodes = testHandles.map { + mock() + } + val testTypedVideoNodes = testHandles.mapIndexed { index, handle -> + initTypedVideoNode(handle, testTimestamps[index]) + } + testMegaNodes.mapIndexed { index, node -> + whenever(megaApiGateway.getMegaNodeByHandle(node.handle)).thenReturn(node) + whenever(fileNodeMapper(node, false, null)).thenReturn(testFileNodes[index]) + whenever( + typedVideoNodeMapper( + fileNode = testFileNodes[index], + duration = 100, + watchedTimestamp = testTimestamps[index] + ) ) - ) - .thenReturn(testTypedVideoNodes[index]) - } + .thenReturn(testTypedVideoNodes[index]) + } - initUnderTest() - whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - whenever(megaLocalRoomGateway.getAllOfflineInfo()).thenReturn(emptyList()) + initUnderTest() + whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( + flowOf(jsonString) + ) + whenever(megaLocalRoomGateway.getAllRecentlyWatchedVideos()).thenReturn(flowOf(testItems)) + whenever(megaLocalRoomGateway.getAllOfflineInfo()).thenReturn(emptyList()) - val actual = underTest.getRecentlyWatchedVideoNodes() - assertThat(actual.isNotEmpty()).isTrue() - assertThat(actual.size).isEqualTo(3) - testTimestamps.sortedByDescending { it }.mapIndexed { index, expectedTimestamp -> - assertThat(actual[index].watchedTimestamp).isEqualTo(expectedTimestamp) + val actual = underTest.getRecentlyWatchedVideoNodes() + verify(megaLocalRoomGateway).saveRecentlyWatchedVideos(testVideoRecentlyWatchedData) + verify(appPreferencesGateway).putString( + "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", + Json.encodeToString(emptyList()) + ) + assertThat(actual.isNotEmpty()).isTrue() + assertThat(actual.size).isEqualTo(3) + testTimestamps.sortedByDescending { it }.mapIndexed { index, expectedTimestamp -> + assertThat(actual[index].watchedTimestamp).isEqualTo(expectedTimestamp) + } } - } private fun initMegaNode(nodeHandle: Long) = mock { on { handle }.thenReturn(nodeHandle) @@ -761,35 +745,14 @@ class VideoSectionRepositoryImplTest { @Test fun `test that clearRecentlyWatchedVideos function is invoked as expected`() = runTest { underTest.clearRecentlyWatchedVideos() - val jsonString = Json.encodeToString(emptyList()) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - jsonString - ) + verify(megaLocalRoomGateway).clearRecentlyWatchedVideos() } @Test - fun `test that removeRecentlyWatchedItem function is invoked with the correct parameters`() = + fun `test that removeRecentlyWatchedItem function is invoked as expected`() = runTest { - val testHandle = 12345L - val testTimestamp = 100000L - val testRecentlyWatchedItem = VideoRecentlyWatchedItem(testHandle, testTimestamp) - val addedHandle = 54321L - val addedTimestamp = 200000L - val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - val testVideoRecentlyWatchedData = - mutableListOf(addedRecentlyWatchedItem, testRecentlyWatchedItem) - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() - whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - testVideoRecentlyWatchedData.removeAll { it.videoHandle == addedHandle } - val expectedJson = Json.encodeToString(testVideoRecentlyWatchedData) - underTest.removeRecentlyWatchedItem(addedHandle) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - expectedJson - ) + val testHandle = 123456L + underTest.removeRecentlyWatchedItem(testHandle) + verify(megaLocalRoomGateway).removeRecentlyWatchedVideo(testHandle) } } \ No newline at end of file From 8d6a468d739f029e7b77b99f5fabf460afbbd7fd Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 23 Sep 2024 17:02:03 +0800 Subject: [PATCH 251/261] The code changes for hotfix Android 14.3.1 CC-8161 AND -Non-fatal Exception: java.lang.OutOfMemoryError --- .../videosection/VideoSectionFragment.kt | 10 +- .../videosection/VideoSectionViewModel.kt | 13 +- .../videosection/VideoSectionViewModelTest.kt | 57 +- .../90.json | 744 ++++++++++++++++++ .../dao/VideoRecentlyWatchedDaoTest.kt | 197 +++++ .../android/data/database/MegaDatabase.kt | 7 +- .../data/database/MegaDatabaseConstant.kt | 7 +- .../database/dao/VideoRecentlyWatchedDao.kt | 27 + .../entity/VideoRecentlyWatchedEntity.kt | 14 + .../android/data/di/RoomDatabaseModule.kt | 6 + .../data/facade/MegaLocalRoomFacade.kt | 46 +- .../data/gateway/MegaLocalRoomGateway.kt | 34 + .../VideoRecentlyWatchedEntityMapper.kt | 11 + .../repository/VideoSectionRepositoryImpl.kt | 76 +- .../data/facade/MegaLocalRoomFacadeTest.kt | 89 +++ .../VideoRecentlyWatchedEntityMapperTest.kt | 47 ++ .../VideoSectionRepositoryImplTest.kt | 153 ++-- 17 files changed, 1336 insertions(+), 202 deletions(-) create mode 100644 data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json create mode 100644 data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt create mode 100644 data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt create mode 100644 data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt create mode 100644 data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt create mode 100644 data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt index a9ef76917b..dd27529c99 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionFragment.kt @@ -22,6 +22,8 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -41,6 +43,7 @@ import mega.privacy.android.app.presentation.videosection.model.VideoSectionMenu import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity import mega.privacy.android.app.presentation.videosection.view.VideoSectionFeatureScreen +import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute import mega.privacy.android.app.presentation.videosection.view.videoSectionRoute import mega.privacy.android.app.utils.Constants.ORDER_CLOUD import mega.privacy.android.app.utils.Constants.ORDER_VIDEO_PLAYLIST @@ -227,6 +230,7 @@ class VideoSectionFragment : Fragment() { /** * onViewCreated */ + @OptIn(FlowPreview::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { (activity as? ManagerActivity)?.let { managerActivity -> managerActivity.supportActionBar?.hide() @@ -236,11 +240,15 @@ class VideoSectionFragment : Fragment() { } viewLifecycleOwner.collectFlow( - videoSectionViewModel.state.map { it.isPendingRefresh }.distinctUntilChanged() + videoSectionViewModel.state.map { it.isPendingRefresh }.debounce(500L) + .distinctUntilChanged() ) { isPendingRefresh -> if (isPendingRefresh) { with(videoSectionViewModel) { refreshNodes() + if (state.value.currentDestinationRoute == videoRecentlyWatchedRoute) { + loadRecentlyWatchedVideos() + } markHandledPendingRefresh() } } diff --git a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt index 4ff7c16529..d8dd2a046a 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModel.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge @@ -37,7 +38,8 @@ import mega.privacy.android.app.presentation.videosection.model.VideoSectionStat import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoSectionTabState import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity -import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute +import mega.privacy.android.domain.entity.VideoFileTypeInfo +import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.TypedFileNode import mega.privacy.android.domain.entity.node.TypedNode @@ -182,16 +184,17 @@ class VideoSectionViewModel @Inject constructor( private fun refreshNodesIfAnyUpdates() { viewModelScope.launch { merge( - monitorNodeUpdatesUseCase(), + monitorNodeUpdatesUseCase().filter { + it.changes.keys.any { node -> + node is FileNode && node.type is VideoFileTypeInfo + } + }, monitorOfflineNodeUpdatesUseCase() ).conflate() .catch { Timber.e(it) }.collect { setPendingRefreshNodes() - if (_state.value.currentDestinationRoute == videoRecentlyWatchedRoute) { - loadRecentlyWatchedVideos() - } } } } diff --git a/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt index 1a6e7a4ffe..bc84616a4e 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/videosection/VideoSectionViewModelTest.kt @@ -20,14 +20,15 @@ import mega.privacy.android.app.presentation.videosection.model.LocationFilterOp import mega.privacy.android.app.presentation.videosection.model.VideoPlaylistUIEntity import mega.privacy.android.app.presentation.videosection.model.VideoSectionTab import mega.privacy.android.app.presentation.videosection.model.VideoUIEntity -import mega.privacy.android.app.presentation.videosection.view.recentlywatched.videoRecentlyWatchedRoute import mega.privacy.android.core.test.extension.CoroutineMainDispatcherExtension import mega.privacy.android.domain.entity.AccountType import mega.privacy.android.domain.entity.Offline import mega.privacy.android.domain.entity.SortOrder +import mega.privacy.android.domain.entity.VideoFileTypeInfo import mega.privacy.android.domain.entity.account.AccountDetail import mega.privacy.android.domain.entity.account.AccountLevelDetail import mega.privacy.android.domain.entity.node.ExportedData +import mega.privacy.android.domain.entity.node.FileNode import mega.privacy.android.domain.entity.node.NodeContentUri import mega.privacy.android.domain.entity.node.NodeId import mega.privacy.android.domain.entity.node.NodeUpdate @@ -129,6 +130,7 @@ class VideoSectionViewModelTest { on { title }.thenReturn("playlist") on { videos }.thenReturn(listOf(expectedVideo, expectedVideo)) } + private fun mockAccountDetail(paidAccount: Boolean): AccountDetail { val testAccountType = mock { on { isPaid }.thenReturn(paidAccount) @@ -269,10 +271,13 @@ class VideoSectionViewModelTest { @Test fun `test that isPendingRefresh is correctly updated when monitorNodeUpdatesUseCase is triggered`() = runTest { + val testFileNode = mock { + on { type }.thenReturn(VideoFileTypeInfo("video", "mp4", 10.seconds)) + } testScheduler.advanceUntilIdle() underTest.state.drop(1).test { - fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(emptyMap())) + fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(mapOf(testFileNode to emptyList()))) assertThat(awaitItem().isPendingRefresh).isTrue() underTest.markHandledPendingRefresh() @@ -1555,54 +1560,6 @@ class VideoSectionViewModelTest { } } - @Test - fun `test that state is correctly updated when monitorOfflineNodeUpdatesUseCase is triggered`() = - runTest { - val testHandle = 1L - val testTimestamp = 1000L - val testWatchDate = "12 April 2024" - val testVideoNodes = listOf(initTypedVideoNode(testHandle, testTimestamp)) - val testVideoEntity = initVideoUIEntity(testHandle, testWatchDate) - val expectedRecentlyWatchedItems = mapOf((testWatchDate to listOf(testVideoEntity))) - whenever(videoUIEntityMapper(anyOrNull())).thenReturn(testVideoEntity) - whenever(getVideoRecentlyWatchedUseCase()).thenReturn(testVideoNodes) - - testScheduler.advanceUntilIdle() - underTest.setCurrentDestinationRoute(videoRecentlyWatchedRoute) - - underTest.state.drop(2).test { - fakeMonitorOfflineNodeUpdatesFlow.emit(emptyList()) - assertThat(awaitItem().groupedVideoRecentlyWatchedItems).isEqualTo( - expectedRecentlyWatchedItems - ) - cancelAndIgnoreRemainingEvents() - } - } - - @Test - fun `test that state is correctly updated when monitorNodeUpdatesUseCase is triggered`() = - runTest { - val testHandle = 1L - val testTimestamp = 1000L - val testWatchDate = "12 April 2024" - val testVideoNodes = listOf(initTypedVideoNode(testHandle, testTimestamp)) - val testVideoEntity = initVideoUIEntity(testHandle, testWatchDate) - val expectedRecentlyWatchedItems = mapOf((testWatchDate to listOf(testVideoEntity))) - whenever(videoUIEntityMapper(anyOrNull())).thenReturn(testVideoEntity) - whenever(getVideoRecentlyWatchedUseCase()).thenReturn(testVideoNodes) - - testScheduler.advanceUntilIdle() - underTest.setCurrentDestinationRoute(videoRecentlyWatchedRoute) - - underTest.state.drop(2).test { - fakeMonitorNodeUpdatesFlow.emit(NodeUpdate(emptyMap())) - assertThat(awaitItem().groupedVideoRecentlyWatchedItems).isEqualTo( - expectedRecentlyWatchedItems - ) - cancelAndIgnoreRemainingEvents() - } - } - companion object { @JvmField @RegisterExtension diff --git a/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json b/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json new file mode 100644 index 0000000000..5dddbe4f42 --- /dev/null +++ b/data/schemas/mega.privacy.android.data.database.MegaDatabase/90.json @@ -0,0 +1,744 @@ +{ + "formatVersion": 1, + "database": { + "version": 90, + "identityHash": "a057a802e7cd89ee44458a027f7cf700", + "entities": [ + { + "tableName": "contacts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `handle` TEXT, `mail` TEXT, `name` TEXT, `lastname` TEXT, `nickname` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "handle", + "columnName": "handle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "mail", + "columnName": "mail", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "firstName", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastName", + "columnName": "lastname", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "nickName", + "columnName": "nickname", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "completedtransfers_2", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `transferfilename` TEXT NOT NULL, `transfertype` INTEGER NOT NULL, `transferstate` INTEGER NOT NULL, `transfersize` TEXT NOT NULL, `transferhandle` INTEGER NOT NULL, `transferpath` TEXT NOT NULL, `transferoffline` INTEGER, `transfertimestamp` INTEGER NOT NULL, `transfererror` TEXT, `transferoriginalpath` TEXT NOT NULL, `transferparenthandle` INTEGER NOT NULL, `transferappdata` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "fileName", + "columnName": "transferfilename", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "transfertype", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "transferstate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "size", + "columnName": "transfersize", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "handle", + "columnName": "transferhandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "path", + "columnName": "transferpath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isOffline", + "columnName": "transferoffline", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "transfertimestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "error", + "columnName": "transfererror", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalPath", + "columnName": "transferoriginalpath", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentHandle", + "columnName": "transferparenthandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "appData", + "columnName": "transferappdata", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "completedtransfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `transferfilename` TEXT, `transfertype` TEXT, `transferstate` TEXT, `transfersize` TEXT, `transferhandle` TEXT, `transferpath` TEXT, `transferoffline` TEXT, `transfertimestamp` TEXT, `transfererror` TEXT, `transferoriginalpath` TEXT, `transferparenthandle` TEXT, `transferappdata` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "fileName", + "columnName": "transferfilename", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "transfertype", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "state", + "columnName": "transferstate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "size", + "columnName": "transfersize", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "handle", + "columnName": "transferhandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "path", + "columnName": "transferpath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isOffline", + "columnName": "transferoffline", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "timestamp", + "columnName": "transfertimestamp", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "error", + "columnName": "transfererror", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originalPath", + "columnName": "transferoriginalpath", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "parentHandle", + "columnName": "transferparenthandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "appData", + "columnName": "transferappdata", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "active_transfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` INTEGER NOT NULL, `transfer_type` TEXT NOT NULL, `total_bytes` INTEGER NOT NULL, `is_finished` INTEGER NOT NULL, `is_folder_transfer` INTEGER NOT NULL DEFAULT 0, `is_paused` INTEGER NOT NULL DEFAULT 0, `is_already_downloaded` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`tag`))", + "fields": [ + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "transferType", + "columnName": "transfer_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalBytes", + "columnName": "total_bytes", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFinished", + "columnName": "is_finished", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isFolderTransfer", + "columnName": "is_folder_transfer", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "isPaused", + "columnName": "is_paused", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "isAlreadyTransferred", + "columnName": "is_already_downloaded", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tag" + ] + }, + "indices": [ + { + "name": "index_active_transfers_transfer_type", + "unique": false, + "columnNames": [ + "transfer_type" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_active_transfers_transfer_type` ON `${TABLE_NAME}` (`transfer_type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "sdtransfers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `sdtransfertag` INTEGER, `sdtransfername` TEXT, `sdtransfersize` TEXT, `sdtransferhandle` TEXT, `sdtransferappdata` TEXT, `sdtransferpath` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "tag", + "columnName": "sdtransfertag", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedName", + "columnName": "sdtransfername", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedSize", + "columnName": "sdtransfersize", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedHandle", + "columnName": "sdtransferhandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedAppData", + "columnName": "sdtransferappdata", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedPath", + "columnName": "sdtransferpath", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "backups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `backup_id` TEXT NOT NULL, `backup_type` INTEGER NOT NULL, `target_node` TEXT NOT NULL, `local_folder` TEXT NOT NULL, `backup_name` TEXT NOT NULL, `state` INTEGER NOT NULL, `sub_state` INTEGER NOT NULL, `extra_data` TEXT NOT NULL, `start_timestamp` TEXT NOT NULL, `last_sync_timestamp` TEXT NOT NULL, `target_folder_path` TEXT NOT NULL, `exclude_subFolders` TEXT NOT NULL, `delete_empty_subFolders` TEXT NOT NULL, `outdated` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedBackupId", + "columnName": "backup_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backupType", + "columnName": "backup_type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "encryptedTargetNode", + "columnName": "target_node", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedLocalFolder", + "columnName": "local_folder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedBackupName", + "columnName": "backup_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "subState", + "columnName": "sub_state", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "encryptedExtraData", + "columnName": "extra_data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedStartTimestamp", + "columnName": "start_timestamp", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedLastFinishTimestamp", + "columnName": "last_sync_timestamp", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedTargetFolderPath", + "columnName": "target_folder_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedShouldExcludeSubFolders", + "columnName": "exclude_subFolders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedShouldDeleteEmptySubFolders", + "columnName": "delete_empty_subFolders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encryptedIsOutdated", + "columnName": "outdated", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "offline", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `handle` TEXT, `path` TEXT, `name` TEXT, `parentId` INTEGER, `type` TEXT, `incoming` INTEGER, `incomingHandle` TEXT, `lastModifiedTime` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedHandle", + "columnName": "handle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedPath", + "columnName": "path", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "encryptedName", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedType", + "columnName": "type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "incoming", + "columnName": "incoming", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "encryptedIncomingHandle", + "columnName": "incomingHandle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastModifiedTime", + "columnName": "lastModifiedTime", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "syncsolvedissues", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`entityId` INTEGER PRIMARY KEY AUTOINCREMENT, `syncId` INTEGER NOT NULL DEFAULT -1, `nodeIds` TEXT NOT NULL, `localPaths` TEXT NOT NULL, `resolutionExplanation` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "entityId", + "columnName": "entityId", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "syncId", + "columnName": "syncId", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "-1" + }, + { + "fieldPath": "nodeIds", + "columnName": "nodeIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localPaths", + "columnName": "localPaths", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resolutionExplanation", + "columnName": "resolutionExplanation", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "entityId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "userpausedsyncs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sync_id` INTEGER NOT NULL, PRIMARY KEY(`sync_id`))", + "fields": [ + { + "fieldPath": "syncId", + "columnName": "sync_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "sync_id" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "camerauploadsrecords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`media_id` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `folder_type` TEXT NOT NULL, `file_name` TEXT NOT NULL, `file_path` TEXT NOT NULL, `file_type` TEXT NOT NULL, `upload_status` TEXT NOT NULL, `original_fingerprint` TEXT NOT NULL, `generated_fingerprint` TEXT, `temp_file_path` TEXT NOT NULL, PRIMARY KEY(`media_id`, `timestamp`, `folder_type`))", + "fields": [ + { + "fieldPath": "mediaId", + "columnName": "media_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "folderType", + "columnName": "folder_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fileName", + "columnName": "file_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "filePath", + "columnName": "file_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fileType", + "columnName": "file_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uploadStatus", + "columnName": "upload_status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originalFingerprint", + "columnName": "original_fingerprint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "generatedFingerprint", + "columnName": "generated_fingerprint", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tempFilePath", + "columnName": "temp_file_path", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "media_id", + "timestamp", + "folder_type" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "chatroompreference", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chatId` INTEGER NOT NULL, `draft_message` TEXT NOT NULL, `editing_message_id` INTEGER, PRIMARY KEY(`chatId`))", + "fields": [ + { + "fieldPath": "chatId", + "columnName": "chatId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "draftMessage", + "columnName": "draft_message", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "editingMessageId", + "columnName": "editing_message_id", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chatId" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "recentlywatchedvideo", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`videoHandle` INTEGER NOT NULL, `watched_timestamp` INTEGER NOT NULL, PRIMARY KEY(`videoHandle`))", + "fields": [ + { + "fieldPath": "videoHandle", + "columnName": "videoHandle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "watchedTimestamp", + "columnName": "watched_timestamp", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "videoHandle" + ] + }, + "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, 'a057a802e7cd89ee44458a027f7cf700')" + ] + } +} \ No newline at end of file diff --git a/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt b/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt new file mode 100644 index 0000000000..1d53e639f5 --- /dev/null +++ b/data/src/androidTest/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDaoTest.kt @@ -0,0 +1,197 @@ +package mega.privacy.android.data.database.dao + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import mega.privacy.android.data.database.MegaDatabase +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.io.IOException + +@RunWith(AndroidJUnit4::class) +class VideoRecentlyWatchedDaoTest { + private lateinit var videoRecentlyWatchedDao: VideoRecentlyWatchedDao + private lateinit var db: MegaDatabase + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder( + context, MegaDatabase::class.java + ).build() + videoRecentlyWatchedDao = db.videoRecentlyWatchedDao() + } + + @After + @Throws(IOException::class) + fun closeDb() { + db.close() + } + + @Test + fun `test_that_getAllRecentlyWatchedVideos_returns_as_expected`() = runTest { + val entities = (1..100L).map { + val entity = VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(entity) + entity + } + + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + .forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(entities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(entities[index].watchedTimestamp) + } + } + + @Test + fun `test_that_table_empty_when_call_clearRecentlyWatchedVideos`() = runTest { + (1..100L).map { + val entity = VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(entity) + } + + videoRecentlyWatchedDao.clearRecentlyWatchedVideos() + assertThat(videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first()).isEmpty() + } + + @Test + fun `test_that_corresponding_item_is_deleted_after_call_removeRecentlyWatchedVideo`() = + runTest { + val testEntities = (1..10L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + val removedHandle = 5L + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + } + + videoRecentlyWatchedDao.removeRecentlyWatchedVideo(removedHandle) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size - 1) + assertThat(entities.find { it.videoHandle == removedHandle }).isNull() + } + + @Test + fun `test_that_corresponding_item_is_added_after_call_insertOrUpdateRecentlyWatchedVideo`() = + runTest { + val expectedVideoHandle = 123456L + val expectedTimestamp = 1000000L + val newEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, expectedTimestamp) + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(newEntity) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) + } + } + + @Test + fun `test_that_corresponding_item_is_updated_after_call_insertOrUpdateRecentlyWatchedVideo_if_item_exists`() = + runTest { + val expectedVideoHandle = 123456L + val expectedTimestamp = 1000000L + val newTimestamp = 200000L + val testEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, expectedTimestamp) + val newEntity = VideoRecentlyWatchedEntity(expectedVideoHandle, newTimestamp) + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(testEntity) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) + } + } + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideo(newEntity) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(1) + entities.forEach { + assertThat(it.videoHandle).isEqualTo(expectedVideoHandle) + assertThat(it.watchedTimestamp).isEqualTo(newTimestamp) + } + } + } + + @Test + fun `test_that_corresponding_items_are_added_after_call_insertOrUpdateRecentlyWatchedVideos`() = + runTest { + val testEntities = (1..100L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + entities.forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(testEntities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(testEntities[index].watchedTimestamp) + } + } + + @Test + fun `test_that_corresponding_items_are_updated_after_call_insertOrUpdateRecentlyWatchedVideos_if_items_exists`() = + runTest { + val testEntities = (1..100L).map { + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = it + ) + } + val newEntities = (10L downTo 1).mapIndexed { index, it -> + VideoRecentlyWatchedEntity( + videoHandle = it, + watchedTimestamp = index.toLong() + ) + } + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(testEntities) + videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first().let { entities -> + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + entities.forEachIndexed { index, entity -> + assertThat(entity.videoHandle).isEqualTo(testEntities[index].videoHandle) + assertThat(entity.watchedTimestamp).isEqualTo(testEntities[index].watchedTimestamp) + } + } + + videoRecentlyWatchedDao.insertOrUpdateRecentlyWatchedVideos(newEntities) + val entities = videoRecentlyWatchedDao.getAllRecentlyWatchedVideos().first() + assertThat(entities).isNotEmpty() + assertThat(entities.size).isEqualTo(testEntities.size) + newEntities.map { entity -> + assertThat( + entities.first { + it.videoHandle == entity.videoHandle + }.watchedTimestamp + ).isEqualTo( + entity.watchedTimestamp + ) + } + } +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt index ad2bf09ea0..7d0fc4d005 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt @@ -18,6 +18,7 @@ import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao import mega.privacy.android.data.database.dao.SyncSolvedIssuesDao import mega.privacy.android.data.database.dao.UserPausedSyncsDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.database.entity.ActiveTransferEntity import mega.privacy.android.data.database.entity.BackupEntity import mega.privacy.android.data.database.entity.CameraUploadsRecordEntity @@ -29,6 +30,7 @@ import mega.privacy.android.data.database.entity.OfflineEntity import mega.privacy.android.data.database.entity.SdTransferEntity import mega.privacy.android.data.database.entity.SyncSolvedIssueEntity import mega.privacy.android.data.database.entity.UserPausedSyncEntity +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity import mega.privacy.android.data.database.spec.AutoMigrationSpec73to74 import mega.privacy.android.data.database.spec.AutoMigrationSpec81to82 import timber.log.Timber @@ -46,6 +48,7 @@ import timber.log.Timber UserPausedSyncEntity::class, CameraUploadsRecordEntity::class, ChatPendingChangesEntity::class, + VideoRecentlyWatchedEntity::class, ], version = MegaDatabaseConstant.DATABASE_VERSION, exportSchema = true, @@ -62,7 +65,7 @@ import timber.log.Timber AutoMigration(84, 85), AutoMigration(86, 87), AutoMigration(87, 88), - AutoMigration(88, 89), + AutoMigration(89, 90), ], ) internal abstract class MegaDatabase : RoomDatabase() { @@ -86,6 +89,8 @@ internal abstract class MegaDatabase : RoomDatabase() { abstract fun chatPendingChangesDao(): ChatPendingChangesDao + abstract fun videoRecentlyWatchedDao(): VideoRecentlyWatchedDao + companion object { /** diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt index f843c935f2..ace30a66da 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabaseConstant.kt @@ -8,7 +8,7 @@ object MegaDatabaseConstant { /** * Database Version */ - const val DATABASE_VERSION = 89 + const val DATABASE_VERSION = 90 /** * Database Name @@ -74,4 +74,9 @@ object MegaDatabaseConstant { * Passphrase File Name */ const val PASSPHRASE_FILE_NAME = "passphrase.bin" + + /** + * Table recently watched video + */ + const val TABLE_RECENTLY_WATCHED_VIDEO = "recentlywatchedvideo" } diff --git a/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt b/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt new file mode 100644 index 0000000000..8449a0719e --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/database/dao/VideoRecentlyWatchedDao.kt @@ -0,0 +1,27 @@ +package mega.privacy.android.data.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import kotlinx.coroutines.flow.Flow +import mega.privacy.android.data.database.MegaDatabaseConstant +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity + +@Dao +internal interface VideoRecentlyWatchedDao { + @Query("SELECT * FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO}") + fun getAllRecentlyWatchedVideos(): Flow> + + @Query("DELETE FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO}") + suspend fun clearRecentlyWatchedVideos() + + @Query("DELETE FROM ${MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO} WHERE videoHandle = :handle") + suspend fun removeRecentlyWatchedVideo(handle: Long) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdateRecentlyWatchedVideo(entity: VideoRecentlyWatchedEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrUpdateRecentlyWatchedVideos(entities: List) +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt b/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt new file mode 100644 index 0000000000..2bf25f48aa --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/database/entity/VideoRecentlyWatchedEntity.kt @@ -0,0 +1,14 @@ +package mega.privacy.android.data.database.entity + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import mega.privacy.android.data.database.MegaDatabaseConstant + +@Entity(tableName = MegaDatabaseConstant.TABLE_RECENTLY_WATCHED_VIDEO) +internal data class VideoRecentlyWatchedEntity( + @PrimaryKey + val videoHandle: Long = 0L, + @ColumnInfo(name = "watched_timestamp") + val watchedTimestamp: Long = 0L, +) diff --git a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt index 581728859d..ce1f9164f0 100644 --- a/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt +++ b/data/src/main/java/mega/privacy/android/data/di/RoomDatabaseModule.kt @@ -28,6 +28,7 @@ import mega.privacy.android.data.database.dao.SdTransferDao import mega.privacy.android.data.database.dao.SyncSolvedIssuesDao import mega.privacy.android.data.database.dao.TypedMessageDao import mega.privacy.android.data.database.dao.UserPausedSyncsDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import net.sqlcipher.database.SupportFactory import timber.log.Timber import java.io.File @@ -208,4 +209,9 @@ internal object RoomDatabaseModule { internal fun provideTypedMessageRequestDao(chatDatabase: ChatDatabase): TypedMessageDao = chatDatabase.typedMessageDao() + @Provides + @Singleton + internal fun provideVideoRecentlyWatchedDao(database: MegaDatabase): VideoRecentlyWatchedDao = + database.videoRecentlyWatchedDao() + } diff --git a/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt index 4e92329e77..d59572d7b9 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/MegaLocalRoomFacade.kt @@ -14,6 +14,7 @@ import mega.privacy.android.data.database.dao.CompletedTransferDao import mega.privacy.android.data.database.dao.ContactDao import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.gateway.MegaLocalRoomGateway import mega.privacy.android.data.mapper.backup.BackupEntityMapper import mega.privacy.android.data.mapper.backup.BackupInfoTypeIntMapper @@ -32,6 +33,9 @@ import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferLega import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferModelMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferEntityMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferModelMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedEntityMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedItemMapper +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.Contact import mega.privacy.android.domain.entity.Offline @@ -75,6 +79,9 @@ internal class MegaLocalRoomFacade @Inject constructor( private val chatPendingChangesDao: Lazy, private val chatRoomPendingChangesEntityMapper: ChatRoomPendingChangesEntityMapper, private val chatRoomPendingChangesModelMapper: ChatRoomPendingChangesModelMapper, + private val videoRecentlyWatchedDao: Lazy, + private val videoRecentlyWatchedEntityMapper: VideoRecentlyWatchedEntityMapper, + private val videoRecentlyWatchedItemMapper: VideoRecentlyWatchedItemMapper, ) : MegaLocalRoomGateway { override suspend fun insertContact(contact: Contact) { contactDao.get().insertOrUpdateContact(contactEntityMapper(contact)) @@ -144,7 +151,8 @@ internal class MegaLocalRoomFacade @Inject constructor( } override suspend fun addCompletedTransfer(transfer: CompletedTransfer) { - completedTransferDao.get().insertOrUpdateCompletedTransfer(completedTransferEntityMapper(transfer)) + completedTransferDao.get() + .insertOrUpdateCompletedTransfer(completedTransferEntityMapper(transfer)) } override suspend fun addCompletedTransfers(transfers: List) { @@ -213,9 +221,10 @@ internal class MegaLocalRoomFacade @Inject constructor( activeTransferDao.get().getActiveTransferByTag(tag) override fun getActiveTransfersByType(transferType: TransferType) = - activeTransferDao.get().getActiveTransfersByType(transferType).map { activeTransferEntities -> - activeTransferEntities.map { it } - } + activeTransferDao.get().getActiveTransfersByType(transferType) + .map { activeTransferEntities -> + activeTransferEntities.map { it } + } override suspend fun getCurrentActiveTransfersByType(transferType: TransferType) = activeTransferDao.get().getCurrentActiveTransfersByType(transferType).map { it } @@ -224,7 +233,8 @@ internal class MegaLocalRoomFacade @Inject constructor( activeTransferDao.get().getCurrentActiveTransfers() override suspend fun insertOrUpdateActiveTransfer(activeTransfer: ActiveTransfer) = - activeTransferDao.get().insertOrUpdateActiveTransfer(activeTransferEntityMapper(activeTransfer)) + activeTransferDao.get() + .insertOrUpdateActiveTransfer(activeTransferEntityMapper(activeTransfer)) override suspend fun insertOrUpdateActiveTransfers(activeTransfers: List) = activeTransfers.map { activeTransferEntityMapper(it) }.let { mappedActiveTransfers -> @@ -237,7 +247,8 @@ internal class MegaLocalRoomFacade @Inject constructor( override suspend fun deleteAllActiveTransfersByType(transferType: TransferType) = activeTransferDao.get().deleteAllActiveTransfersByType(transferType) - override suspend fun deleteAllActiveTransfers() = activeTransferDao.get().deleteAllActiveTransfers() + override suspend fun deleteAllActiveTransfers() = + activeTransferDao.get().deleteAllActiveTransfers() override suspend fun setActiveTransferAsFinishedByTag(tags: List) = activeTransferDao.get().setActiveTransferAsFinishedByTag(tags) @@ -450,6 +461,29 @@ internal class MegaLocalRoomFacade @Inject constructor( ) } + override suspend fun getAllRecentlyWatchedVideos() = + videoRecentlyWatchedDao.get().getAllRecentlyWatchedVideos().map { entities -> + entities.map { entity -> + videoRecentlyWatchedItemMapper(entity.videoHandle, entity.watchedTimestamp) + } + } + + override suspend fun removeRecentlyWatchedVideo(handle: Long) = + videoRecentlyWatchedDao.get().removeRecentlyWatchedVideo(handle) + + override suspend fun clearRecentlyWatchedVideos() = + videoRecentlyWatchedDao.get().clearRecentlyWatchedVideos() + + override suspend fun saveRecentlyWatchedVideo(item: VideoRecentlyWatchedItem) { + val entity = videoRecentlyWatchedEntityMapper(item) + videoRecentlyWatchedDao.get().insertOrUpdateRecentlyWatchedVideo(entity) + } + + override suspend fun saveRecentlyWatchedVideos(items: List) { + val entities = items.map { videoRecentlyWatchedEntityMapper(it) } + videoRecentlyWatchedDao.get().insertOrUpdateRecentlyWatchedVideos(entities) + } + override fun monitorChatPendingChanges(chatId: Long): Flow = chatPendingChangesDao.get().getChatPendingChanges(chatId) .map { entity -> entity?.let { chatRoomPendingChangesModelMapper(it) } } diff --git a/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt b/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt index 1aed34c56b..a3d78ea397 100644 --- a/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt +++ b/data/src/main/java/mega/privacy/android/data/gateway/MegaLocalRoomGateway.kt @@ -1,6 +1,7 @@ package mega.privacy.android.data.gateway import kotlinx.coroutines.flow.Flow +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.Contact import mega.privacy.android.domain.entity.Offline @@ -460,4 +461,37 @@ interface MegaLocalRoomGateway { * @param chatPendingChanges [ChatPendingChanges] */ suspend fun setChatPendingChanges(chatPendingChanges: ChatPendingChanges) + + /** + * Get all recently watched videos + * + * @return flow of [VideoRecentlyWatchedItem] list + */ + suspend fun getAllRecentlyWatchedVideos(): Flow> + + /** + * Remove recently watched video + * + * @param handle removed video handle + */ + suspend fun removeRecentlyWatchedVideo(handle: Long) + + /** + * Clear recently watched videos + */ + suspend fun clearRecentlyWatchedVideos() + + /** + * Save recently watched video + * + * @param item saved [VideoRecentlyWatchedItem] + */ + suspend fun saveRecentlyWatchedVideo(item: VideoRecentlyWatchedItem) + + /** + * Save recently watched videos + * + * @param items [VideoRecentlyWatchedItem] list + */ + suspend fun saveRecentlyWatchedVideos(items: List) } diff --git a/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt b/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt new file mode 100644 index 0000000000..1ab400eac7 --- /dev/null +++ b/data/src/main/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapper.kt @@ -0,0 +1,11 @@ +package mega.privacy.android.data.mapper.videosection + +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import mega.privacy.android.data.model.VideoRecentlyWatchedItem +import javax.inject.Inject + +internal class VideoRecentlyWatchedEntityMapper @Inject constructor() { + + operator fun invoke(item: VideoRecentlyWatchedItem) = + VideoRecentlyWatchedEntity(item.videoHandle, item.watchedTimestamp) +} \ No newline at end of file diff --git a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt index 4b99347402..085c58d74b 100644 --- a/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt +++ b/data/src/main/java/mega/privacy/android/data/repository/VideoSectionRepositoryImpl.kt @@ -67,7 +67,6 @@ internal class VideoSectionRepositoryImpl @Inject constructor( ) : VideoSectionRepository { private val videoPlaylistsMap: MutableMap = mutableMapOf() private val videoSetsMap: MutableMap> = mutableMapOf() - private val recentlyWatchedVideosData = mutableListOf() override suspend fun getAllVideos(order: SortOrder): List = withContext(ioDispatcher) { @@ -305,44 +304,39 @@ internal class VideoSectionRepositoryImpl @Inject constructor( override suspend fun getVideoPlaylistSets(): List = getAllUserSets() - override suspend fun saveVideoRecentlyWatched(handle: Long, timestamp: Long) { - initVideoRecentlyWatchedData() - recentlyWatchedVideosData.indexOfFirst { it.videoHandle == handle }.let { index -> - if (index == -1) { - recentlyWatchedVideosData.add(videoRecentlyWatchedItemMapper(handle, timestamp)) - } else { - recentlyWatchedVideosData[index] = - recentlyWatchedVideosData[index].copy(watchedTimestamp = timestamp) - } - - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) + override suspend fun saveVideoRecentlyWatched(handle: Long, timestamp: Long) = + withContext(ioDispatcher) { + migrateOldDataToDatabase() + megaLocalRoomGateway.saveRecentlyWatchedVideo( + videoRecentlyWatchedItemMapper( + handle, + timestamp + ) ) } - } - private suspend fun initVideoRecentlyWatchedData() { - if (recentlyWatchedVideosData.isEmpty()) { - getRecentlyWatchedData()?.let { - recentlyWatchedVideosData.addAll(it) + private suspend fun migrateOldDataToDatabase() = withContext(ioDispatcher) { + val items: List? = + appPreferencesGateway.monitorString( + PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, + null + ).firstOrNull()?.let { jsonString -> + Json.decodeFromString(jsonString) } - } - } + if (items.isNullOrEmpty()) return@withContext - private suspend fun getRecentlyWatchedData(): List? = - appPreferencesGateway.monitorString( + megaLocalRoomGateway.saveRecentlyWatchedVideos(items) + + appPreferencesGateway.putString( PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - null - ).firstOrNull()?.let { jsonString -> - Json.decodeFromString(jsonString) - } + Json.encodeToString(emptyList()) + ) + } override suspend fun getRecentlyWatchedVideoNodes(): List = withContext(ioDispatcher) { - initVideoRecentlyWatchedData() val offlineItems = getAllOfflineNodeHandle() - recentlyWatchedVideosData.mapNotNull { item -> + getRecentlyWatchedData()?.mapNotNull { item -> megaApiGateway.getMegaNodeByHandle(item.videoHandle)?.let { megaNode -> typedVideoNodeMapper( fileNode = megaNode.convertToFileNode(offlineItems[megaNode.handle.toString()]), @@ -350,28 +344,24 @@ internal class VideoSectionRepositoryImpl @Inject constructor( watchedTimestamp = item.watchedTimestamp ) } - }.sortedByDescending { it.watchedTimestamp } + }?.sortedByDescending { it.watchedTimestamp } ?: emptyList() } - override suspend fun clearRecentlyWatchedVideos() = withContext(ioDispatcher) { - recentlyWatchedVideosData.clear() - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) - ) + private suspend fun getRecentlyWatchedData(): List? { + migrateOldDataToDatabase() + return megaLocalRoomGateway.getAllRecentlyWatchedVideos().firstOrNull() } - override suspend fun removeRecentlyWatchedItem(handle: Long) { - initVideoRecentlyWatchedData() - recentlyWatchedVideosData.removeAll { it.videoHandle == handle } - appPreferencesGateway.putString( - PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS, - Json.encodeToString(recentlyWatchedVideosData) - ) + override suspend fun clearRecentlyWatchedVideos() = withContext(ioDispatcher) { + megaLocalRoomGateway.clearRecentlyWatchedVideos() } + override suspend fun removeRecentlyWatchedItem(handle: Long) = + megaLocalRoomGateway.removeRecentlyWatchedVideo(handle) + companion object { private const val PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS = "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS" } } + diff --git a/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt b/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt index e519d61365..3bd9dc0293 100644 --- a/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt +++ b/data/src/test/java/mega/privacy/android/data/facade/MegaLocalRoomFacadeTest.kt @@ -15,6 +15,7 @@ import mega.privacy.android.data.database.dao.CompletedTransferDao import mega.privacy.android.data.database.dao.ContactDao import mega.privacy.android.data.database.dao.OfflineDao import mega.privacy.android.data.database.dao.SdTransferDao +import mega.privacy.android.data.database.dao.VideoRecentlyWatchedDao import mega.privacy.android.data.database.entity.ActiveTransferEntity import mega.privacy.android.data.database.entity.BackupEntity import mega.privacy.android.data.database.entity.CameraUploadsRecordEntity @@ -22,6 +23,7 @@ import mega.privacy.android.data.database.entity.ChatPendingChangesEntity import mega.privacy.android.data.database.entity.CompletedTransferEntity import mega.privacy.android.data.database.entity.CompletedTransferEntityLegacy import mega.privacy.android.data.database.entity.SdTransferEntity +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity import mega.privacy.android.data.facade.MegaLocalRoomFacade.Companion.MAX_INSERT_LIST_SIZE import mega.privacy.android.data.mapper.backup.BackupEntityMapper import mega.privacy.android.data.mapper.backup.BackupInfoTypeIntMapper @@ -40,6 +42,9 @@ import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferLega import mega.privacy.android.data.mapper.transfer.completed.CompletedTransferModelMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferEntityMapper import mega.privacy.android.data.mapper.transfer.sd.SdTransferModelMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedEntityMapper +import mega.privacy.android.data.mapper.videosection.VideoRecentlyWatchedItemMapper +import mega.privacy.android.data.model.VideoRecentlyWatchedItem import mega.privacy.android.domain.entity.CameraUploadsRecordType import mega.privacy.android.domain.entity.SdTransfer import mega.privacy.android.domain.entity.backup.Backup @@ -96,6 +101,9 @@ internal class MegaLocalRoomFacadeTest { private val chatRoomPendingChangesEntityMapper: ChatRoomPendingChangesEntityMapper = mock() private val chatRoomPendingChangesModelMapper: ChatRoomPendingChangesModelMapper = mock() private val completedTransferLegacyModelMapper = mock() + private val videoRecentlyWatchedDao: VideoRecentlyWatchedDao = mock() + private val videoRecentlyWatchedEntityMapper: VideoRecentlyWatchedEntityMapper = mock() + private val videoRecentlyWatchedItemMapper: VideoRecentlyWatchedItemMapper = mock() @BeforeAll fun setUp() { @@ -127,6 +135,9 @@ internal class MegaLocalRoomFacadeTest { chatPendingChangesDao = { chatPendingChangesDao }, chatRoomPendingChangesEntityMapper = chatRoomPendingChangesEntityMapper, chatRoomPendingChangesModelMapper = chatRoomPendingChangesModelMapper, + videoRecentlyWatchedDao = { videoRecentlyWatchedDao }, + videoRecentlyWatchedItemMapper = videoRecentlyWatchedItemMapper, + videoRecentlyWatchedEntityMapper = videoRecentlyWatchedEntityMapper ) } @@ -152,6 +163,9 @@ internal class MegaLocalRoomFacadeTest { chatRoomPendingChangesEntityMapper, chatRoomPendingChangesModelMapper, completedTransferLegacyModelMapper, + videoRecentlyWatchedDao, + videoRecentlyWatchedItemMapper, + videoRecentlyWatchedEntityMapper ) } @@ -702,4 +716,79 @@ internal class MegaLocalRoomFacadeTest { verify(completedTransferDao, never()).deleteAllLegacyCompletedTransfers() } + + @Test + fun `test that removeRecentlyWatchedVideo invokes as expected`() = + runTest { + val testVideoHandle = 123456L + underTest.removeRecentlyWatchedVideo(testVideoHandle) + verify(videoRecentlyWatchedDao).removeRecentlyWatchedVideo(testVideoHandle) + } + + @Test + fun `test that clearRecentlyWatchedVideos invokes as expected`() = + runTest { + underTest.clearRecentlyWatchedVideos() + verify(videoRecentlyWatchedDao).clearRecentlyWatchedVideos() + } + + @Test + fun `test that saveRecentlyWatchedVideo insert the mapped entity`() = runTest { + val testItem = mock() + val testEntity = mock() + whenever(videoRecentlyWatchedEntityMapper(testItem)).thenReturn(testEntity) + + underTest.saveRecentlyWatchedVideo(testItem) + verify(videoRecentlyWatchedDao).insertOrUpdateRecentlyWatchedVideo(testEntity) + } + + @Test + fun `test that saveRecentlyWatchedVideos insert the mapped entities`() = runTest { + val testItems = (1..100).map { + mock() + } + val testEntities = (1..100).map { + mock() + } + testItems.forEachIndexed { index, item -> + whenever(videoRecentlyWatchedEntityMapper(item)).thenReturn(testEntities[index]) + } + + underTest.saveRecentlyWatchedVideos(testItems) + verify(videoRecentlyWatchedDao).insertOrUpdateRecentlyWatchedVideos(testEntities) + } + + @Test + fun `test that getAllRecentlyWatchedVideos returns as expected`() = + runTest { + val testItems = (1..100L).map { value -> + mock { + on { videoHandle }.thenReturn(value) + on { watchedTimestamp }.thenReturn(value) + } + } + val testEntities = (1..100L).map { value -> + mock { + on { videoHandle }.thenReturn(value) + on { watchedTimestamp }.thenReturn(value) + } + } + whenever(videoRecentlyWatchedDao.getAllRecentlyWatchedVideos()).thenReturn( + flowOf( + testEntities + ) + ) + testItems.forEachIndexed { index, item -> + whenever( + videoRecentlyWatchedItemMapper( + testEntities[index].videoHandle, + testEntities[index].watchedTimestamp + ) + ).thenReturn(item) + } + underTest.getAllRecentlyWatchedVideos().test { + assertThat(awaitItem()).isEqualTo(testItems) + awaitComplete() + } + } } diff --git a/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt b/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt new file mode 100644 index 0000000000..c90f12668d --- /dev/null +++ b/data/src/test/java/mega/privacy/android/data/mapper/videosection/VideoRecentlyWatchedEntityMapperTest.kt @@ -0,0 +1,47 @@ +package mega.privacy.android.data.mapper.videosection + +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import mega.privacy.android.data.database.entity.VideoRecentlyWatchedEntity +import mega.privacy.android.data.model.VideoRecentlyWatchedItem +import org.junit.jupiter.api.Assertions.assertAll +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.mockito.kotlin.mock + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class VideoRecentlyWatchedEntityMapperTest { + private lateinit var underTest: VideoRecentlyWatchedEntityMapper + + private val expectedHandle = 123456L + private val expectedTimestamp = 100000L + private val expectedVideoRecentlyWatchedItem = mock { + on { videoHandle }.thenReturn(expectedHandle) + on { watchedTimestamp }.thenReturn(expectedTimestamp) + } + + @BeforeAll + fun setUp() { + underTest = VideoRecentlyWatchedEntityMapper() + } + + @Test + fun `test that VideoRecentlyWatchedItem can be mapped correctly`() = + runTest { + val item = underTest(expectedVideoRecentlyWatchedItem) + assertMappedVideoRecentlyWatchedItemObject(item) + } + + private fun assertMappedVideoRecentlyWatchedItemObject( + item: VideoRecentlyWatchedEntity, + ) { + item.let { + assertAll( + "Grouped Assertions of ${VideoRecentlyWatchedEntity::class.simpleName}", + { assertThat(it.videoHandle).isEqualTo(expectedHandle) }, + { assertThat(it.watchedTimestamp).isEqualTo(expectedTimestamp) }, + ) + } + } +} \ No newline at end of file diff --git a/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt b/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt index 71f7766a13..727a2b50a1 100644 --- a/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt +++ b/data/src/test/java/mega/privacy/android/data/repository/VideoSectionRepositoryImplTest.kt @@ -641,7 +641,7 @@ class VideoSectionRepositoryImplTest { } @Test - fun `test that saveVideoRecentlyWatched function is invoked with the correct parameters`() = + fun `test that saveVideoRecentlyWatched function is invoked as expected with migrating the old data`() = runTest { val testHandle = 12345L val testTimestamp = 100000L @@ -650,102 +650,86 @@ class VideoSectionRepositoryImplTest { } val addedHandle = 54321L val addedTimestamp = 200000L - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - testVideoRecentlyWatchedData.add(addedRecentlyWatchedItem) - val newJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() + val jsonString = Json.encodeToString(testVideoRecentlyWatchedData) whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) + flowOf(jsonString) ) - whenever(videoRecentlyWatchedItemMapper(addedHandle, addedTimestamp)).thenReturn( + whenever(videoRecentlyWatchedItemMapper(anyOrNull(), anyOrNull())).thenReturn( addedRecentlyWatchedItem ) + initUnderTest() underTest.saveVideoRecentlyWatched(addedHandle, addedTimestamp) + verify(megaLocalRoomGateway).saveRecentlyWatchedVideos(testVideoRecentlyWatchedData) verify(appPreferencesGateway).putString( "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - newJsonString + Json.encodeToString(emptyList()) ) + verify(megaLocalRoomGateway).saveRecentlyWatchedVideo(addedRecentlyWatchedItem) } @Test - fun `test that saveVideoRecentlyWatched function updated the existing value when added video node is existing`() = + fun `test that getRecentlyWatchedVideoNodes returns the correct result with migrating the old data`() = runTest { val testHandle = 12345L val testTimestamp = 100000L val testVideoRecentlyWatchedData = mutableListOf().apply { add(VideoRecentlyWatchedItem(testHandle, testTimestamp)) } - val addedHandle = 12345L - val addedTimestamp = 200000L - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - testVideoRecentlyWatchedData[0] = addedRecentlyWatchedItem - val newJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() + val jsonString = Json.encodeToString(testVideoRecentlyWatchedData) whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - whenever(videoRecentlyWatchedItemMapper(addedHandle, addedTimestamp)).thenReturn( - addedRecentlyWatchedItem + flowOf(jsonString) ) - underTest.saveVideoRecentlyWatched(addedHandle, addedTimestamp) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - newJsonString - ) - } + val testHandles = listOf(12345L, 23456L, 34567L) + val testTimestamps = listOf(100000L, 200000L, 300000L) - @Test - fun `test that getRecentlyWatchedVideoNodes returns the correct result`() = runTest { - val testHandles = listOf(12345L, 23456L, 34567L) - val testTimestamps = listOf(100000L, 200000L, 300000L) - val testVideoRecentlyWatchedData = mutableListOf() - testHandles.mapIndexed { index, handle -> - testVideoRecentlyWatchedData.add( + val testItems = testHandles.mapIndexed { index, handle -> VideoRecentlyWatchedItem( - handle, - testTimestamps[index] + handle, testTimestamps[index] ) - ) - } - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) + } - val testMegaNodes = testHandles.map { handle -> - initMegaNode(handle) - } - val testFileNodes = testHandles.map { - mock() - } - val testTypedVideoNodes = testHandles.mapIndexed { index, handle -> - initTypedVideoNode(handle, testTimestamps[index]) - } - testMegaNodes.mapIndexed { index, node -> - whenever(megaApiGateway.getMegaNodeByHandle(node.handle)).thenReturn(node) - whenever(fileNodeMapper(node, false, null)).thenReturn(testFileNodes[index]) - whenever( - typedVideoNodeMapper( - fileNode = testFileNodes[index], - duration = 100, - watchedTimestamp = testTimestamps[index] + val testMegaNodes = testHandles.map { handle -> + initMegaNode(handle) + } + val testFileNodes = testHandles.map { + mock() + } + val testTypedVideoNodes = testHandles.mapIndexed { index, handle -> + initTypedVideoNode(handle, testTimestamps[index]) + } + testMegaNodes.mapIndexed { index, node -> + whenever(megaApiGateway.getMegaNodeByHandle(node.handle)).thenReturn(node) + whenever(fileNodeMapper(node, false, null)).thenReturn(testFileNodes[index]) + whenever( + typedVideoNodeMapper( + fileNode = testFileNodes[index], + duration = 100, + watchedTimestamp = testTimestamps[index] + ) ) - ) - .thenReturn(testTypedVideoNodes[index]) - } + .thenReturn(testTypedVideoNodes[index]) + } - initUnderTest() - whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - whenever(megaLocalRoomGateway.getAllOfflineInfo()).thenReturn(emptyList()) + initUnderTest() + whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( + flowOf(jsonString) + ) + whenever(megaLocalRoomGateway.getAllRecentlyWatchedVideos()).thenReturn(flowOf(testItems)) + whenever(megaLocalRoomGateway.getAllOfflineInfo()).thenReturn(emptyList()) - val actual = underTest.getRecentlyWatchedVideoNodes() - assertThat(actual.isNotEmpty()).isTrue() - assertThat(actual.size).isEqualTo(3) - testTimestamps.sortedByDescending { it }.mapIndexed { index, expectedTimestamp -> - assertThat(actual[index].watchedTimestamp).isEqualTo(expectedTimestamp) + val actual = underTest.getRecentlyWatchedVideoNodes() + verify(megaLocalRoomGateway).saveRecentlyWatchedVideos(testVideoRecentlyWatchedData) + verify(appPreferencesGateway).putString( + "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", + Json.encodeToString(emptyList()) + ) + assertThat(actual.isNotEmpty()).isTrue() + assertThat(actual.size).isEqualTo(3) + testTimestamps.sortedByDescending { it }.mapIndexed { index, expectedTimestamp -> + assertThat(actual[index].watchedTimestamp).isEqualTo(expectedTimestamp) + } } - } private fun initMegaNode(nodeHandle: Long) = mock { on { handle }.thenReturn(nodeHandle) @@ -761,35 +745,14 @@ class VideoSectionRepositoryImplTest { @Test fun `test that clearRecentlyWatchedVideos function is invoked as expected`() = runTest { underTest.clearRecentlyWatchedVideos() - val jsonString = Json.encodeToString(emptyList()) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - jsonString - ) + verify(megaLocalRoomGateway).clearRecentlyWatchedVideos() } @Test - fun `test that removeRecentlyWatchedItem function is invoked with the correct parameters`() = + fun `test that removeRecentlyWatchedItem function is invoked as expected`() = runTest { - val testHandle = 12345L - val testTimestamp = 100000L - val testRecentlyWatchedItem = VideoRecentlyWatchedItem(testHandle, testTimestamp) - val addedHandle = 54321L - val addedTimestamp = 200000L - val addedRecentlyWatchedItem = VideoRecentlyWatchedItem(addedHandle, addedTimestamp) - val testVideoRecentlyWatchedData = - mutableListOf(addedRecentlyWatchedItem, testRecentlyWatchedItem) - val testJsonString = Json.encodeToString(testVideoRecentlyWatchedData) - initUnderTest() - whenever(appPreferencesGateway.monitorString(anyOrNull(), anyOrNull())).thenReturn( - flowOf(testJsonString) - ) - testVideoRecentlyWatchedData.removeAll { it.videoHandle == addedHandle } - val expectedJson = Json.encodeToString(testVideoRecentlyWatchedData) - underTest.removeRecentlyWatchedItem(addedHandle) - verify(appPreferencesGateway).putString( - "PREFERENCE_KEY_RECENTLY_WATCHED_VIDEOS", - expectedJson - ) + val testHandle = 123456L + underTest.removeRecentlyWatchedItem(testHandle) + verify(megaLocalRoomGateway).removeRecentlyWatchedVideo(testHandle) } } \ No newline at end of file From 779785568d85c8758357558fd9d1dae1df46b7c8 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 23 Sep 2024 21:20:22 +0800 Subject: [PATCH 252/261] Added the removed migration item CC-8161 AND -Non-fatal Exception: java.lang.OutOfMemoryError --- .../main/java/mega/privacy/android/data/database/MegaDatabase.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt index 7d0fc4d005..e0f523f594 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt @@ -65,6 +65,7 @@ import timber.log.Timber AutoMigration(84, 85), AutoMigration(86, 87), AutoMigration(87, 88), + AutoMigration(88, 89), AutoMigration(89, 90), ], ) From f57ccfcab1383972c21d91202c5aded645d4f9b9 Mon Sep 17 00:00:00 2001 From: Kevin Sun Date: Mon, 23 Sep 2024 21:23:34 +0800 Subject: [PATCH 253/261] Added the removed migration item CC-8161 AND -Non-fatal Exception: java.lang.OutOfMemoryError --- .../main/java/mega/privacy/android/data/database/MegaDatabase.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt index 7d0fc4d005..e0f523f594 100644 --- a/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt +++ b/data/src/main/java/mega/privacy/android/data/database/MegaDatabase.kt @@ -65,6 +65,7 @@ import timber.log.Timber AutoMigration(84, 85), AutoMigration(86, 87), AutoMigration(87, 88), + AutoMigration(88, 89), AutoMigration(89, 90), ], ) From 55fba982bb75154936e3aa0ab6cfd01fa4c6ee7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Tue, 24 Sep 2024 03:06:51 +1200 Subject: [PATCH 254/261] TRAN-554 Uploading by sharing from Gallery results in wrong modified date --- .../java/mega/privacy/android/app/ShareInfo.java | 13 +++++++++++++ .../mega/privacy/android/data/facade/FileFacade.kt | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/ShareInfo.java b/app/src/main/java/mega/privacy/android/app/ShareInfo.java index 8e1fd0fda8..7fb5d00abd 100644 --- a/app/src/main/java/mega/privacy/android/app/ShareInfo.java +++ b/app/src/main/java/mega/privacy/android/app/ShareInfo.java @@ -491,12 +491,16 @@ private void processContent(Uri uri, Context context) { } int lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED); if (lastModifiedIndex != -1) { + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } if (lastModified == 0) { lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED); if (lastModifiedIndex != -1) { + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } } @@ -508,6 +512,15 @@ private void processContent(Uri uri, Context context) { } } + if (lastModified != 0 && lastModified > (System.currentTimeMillis() * 10)) { + /* Some OS does not follow MediaStore documentation and implements the values using + their own units. This ensures we set the date to the correct value in case the OS + does not follow it. */ + lastModified /= 1000; + } + + Timber.d("Last modified: %s", lastModified); + if (size == -1 || inputStream == null) { Timber.d("Keep going"); int dataIndex = cursor.getColumnIndex("_data"); diff --git a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt index 5a70595cd7..97bf7ef773 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt @@ -467,13 +467,25 @@ internal class FileFacade @Inject constructor( cursor.moveToFirst() cursor.getColumnIndex(DATE_MODIFIED).takeIf { it != -1 }?.let { index -> + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ lastModified = cursor.getLong(index) * 1000 } ?: cursor.getColumnIndex(DATE_ADDED).takeIf { it != -1 }?.let { index -> + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ lastModified = cursor.getLong(index) * 1000 } ?: cursor.getColumnIndex(DATE_TAKEN).takeIf { it != -1 }?.let { index -> lastModified = cursor.getLong(index) } + if (lastModified > (System.currentTimeMillis() * 10)) { + /* Some OS does not follow MediaStore documentation and implements the values using + their own units. This ensures we set the date to the correct value in case the OS + does not follow it. */ + lastModified /= 1000 + } + + Timber.d("Last modified: %s", lastModified); lastModified } ?: 0 } ?: 0 From e39d293c602d3d3cbc97c5a9a0356f4183f121f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yenel=20Rodr=C3=ADguez=20Hern=C3=A1ndez?= Date: Tue, 24 Sep 2024 03:06:51 +1200 Subject: [PATCH 255/261] TRAN-554 Uploading by sharing from Gallery results in wrong modified date --- .../java/mega/privacy/android/app/ShareInfo.java | 13 +++++++++++++ .../mega/privacy/android/data/facade/FileFacade.kt | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/app/src/main/java/mega/privacy/android/app/ShareInfo.java b/app/src/main/java/mega/privacy/android/app/ShareInfo.java index 8e1fd0fda8..7fb5d00abd 100644 --- a/app/src/main/java/mega/privacy/android/app/ShareInfo.java +++ b/app/src/main/java/mega/privacy/android/app/ShareInfo.java @@ -491,12 +491,16 @@ private void processContent(Uri uri, Context context) { } int lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED); if (lastModifiedIndex != -1) { + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } if (lastModified == 0) { lastModifiedIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_ADDED); if (lastModifiedIndex != -1) { + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ this.lastModified = cursor.getLong(lastModifiedIndex) * 1000; } } @@ -508,6 +512,15 @@ private void processContent(Uri uri, Context context) { } } + if (lastModified != 0 && lastModified > (System.currentTimeMillis() * 10)) { + /* Some OS does not follow MediaStore documentation and implements the values using + their own units. This ensures we set the date to the correct value in case the OS + does not follow it. */ + lastModified /= 1000; + } + + Timber.d("Last modified: %s", lastModified); + if (size == -1 || inputStream == null) { Timber.d("Keep going"); int dataIndex = cursor.getColumnIndex("_data"); diff --git a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt index 5a70595cd7..97bf7ef773 100644 --- a/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt +++ b/data/src/main/java/mega/privacy/android/data/facade/FileFacade.kt @@ -467,13 +467,25 @@ internal class FileFacade @Inject constructor( cursor.moveToFirst() cursor.getColumnIndex(DATE_MODIFIED).takeIf { it != -1 }?.let { index -> + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ lastModified = cursor.getLong(index) * 1000 } ?: cursor.getColumnIndex(DATE_ADDED).takeIf { it != -1 }?.let { index -> + /* As MediaStore documentation states, the date is in seconds. + As we work with this property using milliseconds, we need to convert it. */ lastModified = cursor.getLong(index) * 1000 } ?: cursor.getColumnIndex(DATE_TAKEN).takeIf { it != -1 }?.let { index -> lastModified = cursor.getLong(index) } + if (lastModified > (System.currentTimeMillis() * 10)) { + /* Some OS does not follow MediaStore documentation and implements the values using + their own units. This ensures we set the date to the correct value in case the OS + does not follow it. */ + lastModified /= 1000 + } + + Timber.d("Last modified: %s", lastModified); lastModified } ?: 0 } ?: 0 From 3e7a8902775072bd9117965c5129fcc970a35609 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Tue, 24 Sep 2024 12:23:00 +1200 Subject: [PATCH 256/261] AND-19312 - Set correct title when editing passcode (cherry picked from commit 1d7f0920da9fc61918b459b6ed68bae11e97d7f4) 1d7f0920 AND-19312 - Set correct title when editing passcode Co-authored-by: Daniel Oosthuizen --- .../navigation/PasscodeSettingsDestination.kt | 2 +- .../passcode/view/PasscodeSettingsView.kt | 13 ++++--- .../passcode/view/PasscodeSettingsViewTest.kt | 37 ++++++++++++++++--- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/navigation/PasscodeSettingsDestination.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/navigation/PasscodeSettingsDestination.kt index 67e39afac9..58af43b9fd 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/navigation/PasscodeSettingsDestination.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/navigation/PasscodeSettingsDestination.kt @@ -50,7 +50,7 @@ internal fun NavGraphBuilder.passCodeSettings( state = uiState, onDisablePasscode = viewModel::disablePasscode, onDisableBiometrics = viewModel::disableBiometrics, - navigateToChangePasscode = { launcher.launch(false) }, + navigateToSetOrChangePasscode = launcher::launch, navigateToSelectTimeout = navigateToSelectTimeout, hasBiometricCapability = hasBiometricCapability, authenticateBiometrics = { onSuccess, onComplete -> diff --git a/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsView.kt b/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsView.kt index 2921e2a0db..3530c35625 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsView.kt @@ -39,6 +39,7 @@ import mega.privacy.android.shared.original.core.ui.controls.appbar.MegaAppBar import mega.privacy.android.shared.original.core.ui.controls.layouts.MegaScaffold import mega.privacy.android.shared.original.core.ui.preview.CombinedThemePreviews import mega.privacy.android.shared.original.core.ui.theme.OriginalTempTheme +import mega.privacy.android.shared.original.core.ui.utils.showAutoDurationSnackbar @OptIn(ExperimentalComposeUiApi::class) @Composable @@ -46,7 +47,7 @@ internal fun PasscodeSettingsView( state: PasscodeSettingsUIState, onDisablePasscode: () -> Unit, onDisableBiometrics: () -> Unit, - navigateToChangePasscode: () -> Unit, + navigateToSetOrChangePasscode: (isEdit: Boolean) -> Unit, navigateToSelectTimeout: () -> Unit, hasBiometricCapability: Boolean, authenticateBiometrics: @Composable (onSuccess: () -> Unit, onComplete: () -> Unit) -> Unit, @@ -87,12 +88,14 @@ internal fun PasscodeSettingsView( EnablePasscodeTile( isChecked = state.isEnabled, onItemClicked = { - if (state.isEnabled) onDisablePasscode() else navigateToChangePasscode() + if (state.isEnabled) onDisablePasscode() else navigateToSetOrChangePasscode( + false + ) } ) if (state.isEnabled) { ChangePasscodeTile( - onItemClicked = navigateToChangePasscode + onItemClicked = { navigateToSetOrChangePasscode(true) } ) if (hasBiometricCapability) { FingerprintIdTile( @@ -118,7 +121,7 @@ internal fun PasscodeSettingsView( authenticateBiometrics( { coroutineScope.launch { - scaffoldState.snackbarHostState.showSnackbar(message) + scaffoldState.snackbarHostState.showAutoDurationSnackbar(message) } showBiometricPrompt = false }, @@ -156,7 +159,7 @@ private fun PasscodeSettingsViewPreview( onDisableBiometrics = { state = state.copy(isBiometricsEnabled = !state.isBiometricsEnabled) }, - navigateToChangePasscode = {}, + navigateToSetOrChangePasscode = {}, authenticateBiometrics = { _, _ -> }, navigateToSelectTimeout = {}, hasBiometricCapability = params.second, diff --git a/app/src/test/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsViewTest.kt b/app/src/test/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsViewTest.kt index 4fc52543ec..b9d5436002 100644 --- a/app/src/test/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsViewTest.kt +++ b/app/src/test/java/mega/privacy/android/app/presentation/settings/passcode/view/PasscodeSettingsViewTest.kt @@ -16,6 +16,7 @@ import mega.privacy.android.app.presentation.settings.passcode.view.tile.REQUIRE import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.verify @@ -80,12 +81,12 @@ class PasscodeSettingsViewTest { @Test fun `test that view navigates to enable passcode if not yet enabled on toggle`() { - val navigateToChangePasscode = mock<() -> Unit>() - initialiseView(isEnabled = false, navigateToChangePasscode = navigateToChangePasscode) + val navigateToChangePasscode = mock<(Boolean) -> Unit>() + initialiseView(isEnabled = false, navigateToSetOrChangePasscode = navigateToChangePasscode) composeTestRule.onNodeWithTag(ENABLE_PASSCODE_TILE).performClick() - verify(navigateToChangePasscode).invoke() + verify(navigateToChangePasscode).invoke(any()) } @Test @@ -133,11 +134,37 @@ class PasscodeSettingsViewTest { verify(disableBiometrics).invoke() } + @Test + fun `test that navigateToSetOrChangePasscode is called with isEdit set to false when setting the passcode`() { + val navigateToSetOrChangePasscode = mock<(Boolean) -> Unit>() + initialiseView( + isEnabled = false, + navigateToSetOrChangePasscode = navigateToSetOrChangePasscode + ) + + composeTestRule.onNodeWithTag(ENABLE_PASSCODE_TILE).performClick() + + verify(navigateToSetOrChangePasscode).invoke(false) + } + + @Test + fun `test that navigateToSetOrChangePasscode is called with isEdit set to true when changing the passcode`() { + val navigateToSetOrChangePasscode = mock<(Boolean) -> Unit>() + initialiseView( + isEnabled = true, + navigateToSetOrChangePasscode = navigateToSetOrChangePasscode + ) + + composeTestRule.onNodeWithTag(CHANGE_PASSCODE_TILE).performClick() + + verify(navigateToSetOrChangePasscode).invoke(true) + } + private fun initialiseView( isEnabled: Boolean = false, hasBiometricCapability: Boolean = false, isBiometricsEnabled: Boolean = false, - navigateToChangePasscode: () -> Unit = {}, + navigateToSetOrChangePasscode: (Boolean) -> Unit = {}, onDisablePasscode: () -> Unit = {}, onDisableBiometrics: () -> Unit = {}, navigateToSelectTimeout: () -> Unit = {}, @@ -154,7 +181,7 @@ class PasscodeSettingsViewTest { ), onDisablePasscode = onDisablePasscode, onDisableBiometrics = onDisableBiometrics, - navigateToChangePasscode = navigateToChangePasscode, + navigateToSetOrChangePasscode = navigateToSetOrChangePasscode, navigateToSelectTimeout = navigateToSelectTimeout, hasBiometricCapability = hasBiometricCapability, authenticateBiometrics = authenticateBiometrics From c1ce9da79d70eff45de18af2aff7d55788b1ddc0 Mon Sep 17 00:00:00 2001 From: Daniel Oosthuizen Date: Tue, 24 Sep 2024 16:11:41 +1200 Subject: [PATCH 257/261] AND-19312 - Passcode view not displaying correctly in settings (cherry picked from commit b390e930b04bb95dca0cd1ce577db79b17662b31) b390e930 AND-19312 - Passcode view not displaying correctly in settings Co-authored-by: Daniel Oosthuizen --- .../app/presentation/passcode/view/PasscodeView.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/presentation/passcode/view/PasscodeView.kt b/app/src/main/java/mega/privacy/android/app/presentation/passcode/view/PasscodeView.kt index 2805f78852..71091bc699 100644 --- a/app/src/main/java/mega/privacy/android/app/presentation/passcode/view/PasscodeView.kt +++ b/app/src/main/java/mega/privacy/android/app/presentation/passcode/view/PasscodeView.kt @@ -13,7 +13,9 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.material.MaterialTheme @@ -91,7 +93,12 @@ internal fun PasscodeView( activity?.finishAffinity() } - Surface(modifier = Modifier.fillMaxSize()) { + Surface( + modifier = Modifier + .fillMaxSize() + .systemBarsPadding() + .imePadding() + ) { when (val currentState = uiState) { PasscodeUnlockState.Loading -> {} is PasscodeUnlockState.Data -> { From cabd89126569d6a98936093c8a0b05f267402dbd Mon Sep 17 00:00:00 2001 From: Gregg Meyrick Jover Date: Tue, 24 Sep 2024 16:06:48 +1200 Subject: [PATCH 258/261] AND-19490: Update Android Document Scanner Library Version Update the com.github.meganz.AndroidDocumentScanner:documentscanner to Version 2.0.13 to resolve a crash when using the Document Scanner caused by updating the Fresco version to 3.2.0. --- gradle/catalogs/lib.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/catalogs/lib.versions.toml b/gradle/catalogs/lib.versions.toml index 88b2ccbe0e..837412bf12 100644 --- a/gradle/catalogs/lib.versions.toml +++ b/gradle/catalogs/lib.versions.toml @@ -43,7 +43,7 @@ coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } -documentscanner = 'com.github.meganz.AndroidDocumentScanner:documentscanner:2.0.12' +documentscanner = 'com.github.meganz.AndroidDocumentScanner:documentscanner:2.0.13' facebook-inferannotation = "com.facebook.infer.annotation:infer-annotation:0.18.0" fresco = { module = "com.facebook.fresco:fresco", version.ref = "fresco" } fresco-gif = { module = "com.facebook.fresco:animated-gif", version.ref = "fresco" } From d2ea7ecefa51cd3cd68a4ea9891c59060e3c20ef Mon Sep 17 00:00:00 2001 From: JoeJi Date: Wed, 25 Sep 2024 16:59:45 +1200 Subject: [PATCH 259/261] turn off map location flag --- .../java/mega/privacy/android/app/featuretoggle/AppFeatures.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt b/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt index dfc2c48328..30c3e721f0 100644 --- a/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt +++ b/app/src/main/java/mega/privacy/android/app/featuretoggle/AppFeatures.kt @@ -44,7 +44,7 @@ enum class AppFeatures(override val description: String, private val defaultValu */ MapLocation( "Enable map location feature", - true, + false, ), /** From 43418ae642cf8219c25d3cc91d8318934696de76 Mon Sep 17 00:00:00 2001 From: Atiqur Rahman Date: Wed, 25 Sep 2024 20:15:26 +1200 Subject: [PATCH 260/261] Pre-release - v14.4 --- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-ko/strings.xml | 20 +-- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 6 +- .../src/main/res/values-ar/strings_shared.xml | 12 +- .../src/main/res/values-de/strings_shared.xml | 18 +- .../src/main/res/values-es/strings_shared.xml | 159 +++++++++--------- .../src/main/res/values-fr/strings_shared.xml | 12 +- .../src/main/res/values-in/strings_shared.xml | 12 +- .../src/main/res/values-it/strings_shared.xml | 12 +- .../src/main/res/values-ja/strings_shared.xml | 12 +- .../src/main/res/values-ko/strings_shared.xml | 69 ++++---- .../src/main/res/values-nl/strings_shared.xml | 14 +- .../src/main/res/values-pl/strings_shared.xml | 12 +- .../src/main/res/values-pt/strings_shared.xml | 12 +- .../src/main/res/values-ro/strings_shared.xml | 12 +- .../src/main/res/values-ru/strings_shared.xml | 12 +- .../src/main/res/values-th/strings_shared.xml | 12 +- .../src/main/res/values-vi/strings_shared.xml | 12 +- .../main/res/values-zh-rCN/strings_shared.xml | 12 +- .../main/res/values-zh-rTW/strings_shared.xml | 18 +- .../src/main/res/values/strings_shared.xml | 6 +- 24 files changed, 283 insertions(+), 179 deletions(-) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2f5fa0800e..c88fd6707e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1825,7 +1825,7 @@ Schließen - Two-factor authenticator app + App für Zwei-Faktor-Authentifizierung Möchten Sie Google Play zur Installation einer Authenticator App öffnen? diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f0ea102afc..adfe541503 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -137,7 +137,7 @@ Première fois sur MEGA ? - Créer un compte MEGA + M’inscrire Saisissez votre adresse courriel diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3397411988..544a9266a9 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -159,7 +159,7 @@ MEGA로 공유하려면 로그인하세요 - Your confirmation link is no longer valid. Your account may already be activated or you may have cancelled your signup. + 확인 링크가 더 이상 유효하지 않습니다. 계정이 이미 활성화되었거나 가입을 취소했을 수 있습니다. 이름 @@ -179,7 +179,7 @@ 암호가 일치하지 않습니다 - This email address has already signed up for an account with MEGA + 이 이메일 주소는 이미 MEGA에 가입되어 있습니다 서버에 연결 중: 계정 생성 중 @@ -1326,7 +1326,7 @@ MEGA 모바일 앱 설치 - Signup bonus + 가입 보너스 MEGA 데스크톱 앱 설치 @@ -1340,7 +1340,7 @@ 작동 원리 - Invite your friends to sign up for a free MEGA account and to install a MEGA Mobile App. You will receive free storage as a bonus for every signup and app installation. + 친구를 초대하여 무료 MEGA 계정에 가입하고 MEGA 모바일 앱을 설치하게 하세요. 가입과 앱 설치마다 당신은 무료 저장소를 보너스로 받게 됩니다. 무료 저장소 보너스는 새 초대에만 적용되며 MEGA 모바일 앱 또는 MEGA 데스크톱 앱이 설치되어야 합니다. @@ -1356,7 +1356,7 @@ MEGA 모바일 앱을 설치하여 저장소 공간 %1$s를 받았습니다. - You have received %1$s storage space as your free signup bonus. + 당신은 무료 가입 보너스로 저장 공간 %1$s를 받았습니다. 폴더 공유 @@ -1783,7 +1783,7 @@ 닫기 - Two-factor authenticator app + 2단계 인증기 앱 인증기 앱을 설치할 수 있도록 Google Play를 여시겠습니까? @@ -1895,7 +1895,7 @@ 계정 전체에 대한 파일 버전 관리를 활성화하거나 비활성화 합니다.\n파일 버전 관리를 해제하는 것이 연락처가 공유된 폴더에 새로운 버전을 만드는 것을 막을 수 없습니다. - Search contacts or type email address + 연락처 검색 또는 이메일 주소 입력 %s을/를 연락처에 추가할까요? @@ -2339,7 +2339,7 @@ 클라우드 속 당신의 사진 - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + 카메라 업로드는 어떠한 모바일 기기에서든 필요한 기능이며 우리는 이 기능이 준비되어 있습니다. 지금 계정에 가입하세요. 암호를 입력하세요 @@ -2429,7 +2429,7 @@ MEGA에 로그인 - Sign up for a MEGA account + MEGA 계정에 가입 최근 @@ -3569,7 +3569,7 @@ 당신의 MEGA 계정이 반복된 저작권 침해 혐의로 인해 정지 되었습니다. 이것은 당신의 계정이나 그 안의 데이터에 접근할 수 없다는 뜻입니다.\n이의 제기를 제출하는 방법에 대한 자세한 정보는 이메일 수신함을 확인하세요. - Your account was terminated due to a breach of MEGA’s Terms of Service.\nYou will not be able to regain access to your stored data or be authorised to sign up for a new MEGA account. + 당신의 계정이 MEGA의 이용 약관 위반으로 삭제되었습니다.\n저장된 데이터에 대한 접근 또는 새 MEGA 계정에 가입하는 것이 금지됩니다. 회의 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 403ef53ef8..a38f35f54a 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1825,7 +1825,7 @@ Sluiten - Two-factor authenticator app + Twee-staps-authenticatie-applicatie Wilt u Google Play openen zodat u een authenticatie applicatie kunt installeren? diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 92ad34a2da..31692bad61 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1783,7 +1783,7 @@ 关闭 - Two-factor authenticator app + 双重验证应用程序 您想打开Google Play来安装验证应用程序吗? diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ea64b57fda..d3a37a6c5e 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -133,7 +133,7 @@ 還沒有MEGA帳戶? - 建立MEGA帳戶 + 註冊 請輸入您的電子信箱地址 @@ -1783,7 +1783,7 @@ 關閉 - Two-factor authenticator app + 雙重驗證應用程式 您想開啟Google Play來安裝身份驗證程式嗎? @@ -3569,7 +3569,7 @@ 由於多次侵犯版權的指控,您的MEGA帳戶已被暫停。這意味著您無法存取您的帳戶或當中的資料。\n檢查您的電子郵件收件匣,瞭解有關如何提交反對通知的更多資訊。 - 由於違反MEGA的服務條款,您的帳戶已被終止。\n您將無法重新存取您儲存的資料,也無法獲得註冊新MEGA帳戶的授權。 + 由於違反MEGA的服務條款,您的帳戶已被終止。\n您將無法再存取您儲存的資料,也無法獲得註冊新MEGA帳戶的授權。 會議 diff --git a/shared/resources/src/main/res/values-ar/strings_shared.xml b/shared/resources/src/main/res/values-ar/strings_shared.xml index 9736106601..5daa781bc3 100644 --- a/shared/resources/src/main/res/values-ar/strings_shared.xml +++ b/shared/resources/src/main/res/values-ar/strings_shared.xml @@ -323,11 +323,11 @@ تم إلغاء تنشيط حساب برو فلاكسي Pro Flexi الخاص بك بسبب فشل الدفع أو إلغاء اشتراكك. لن تتمكن من الوصول إلى البيانات المخزنة في حسابك. \nلإجراء الدفع وإعادة تفعيل اشتراكك قم بتسجيل الدخول إلى ميغا MEGA من خلال متصفح. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential سيتم إيقاف الترفيعات مؤقتًا حتى تبدأ في شحن جهازك. ستظل الترفيعات متوقفة مؤقتًا إذا كانت بطاريتك أقل من 20%. @@ -744,4 +744,10 @@ In order to invite friends, you must allow MEGA to access your contact list السماح بالوصول + + PDF + + JPG + + المحادثة \ No newline at end of file diff --git a/shared/resources/src/main/res/values-de/strings_shared.xml b/shared/resources/src/main/res/values-de/strings_shared.xml index 5b23e255cd..b6c244954e 100644 --- a/shared/resources/src/main/res/values-de/strings_shared.xml +++ b/shared/resources/src/main/res/values-de/strings_shared.xml @@ -291,11 +291,11 @@ Ihr Pro-Flexi-Account wurde aufgrund eines Zahlungsproblems deaktiviert oder Sie haben Ihr Abonnement gekündigt. Sie können auf die Daten in Ihrem Account nicht zugreifen. \nUm eine Zahlung vorzunehmen und Ihr Abonnement erneut zu aktivieren, melden Sie sich in einem Browser bei MEGA an. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Die Uploads werden pausiert, bis Sie Ihr Gerät an ein Ladegerät anschließen. Die Uploads bleiben auch dann pausiert, wenn der Ladestand weniger als 20 % beträgt. @@ -689,11 +689,17 @@ Abbrechen - Sync options updated + Synchronisierungsoptionen aktualisiert - Enable access to invite friends + Zugriff erlauben, um Freunde einladen zu können - In order to invite friends, you must allow MEGA to access your contact list + Um Freunde einladen zu können, müssen Sie MEGA den Zugriff auf Ihre Kontaktliste erlauben Zugriff erlauben + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-es/strings_shared.xml b/shared/resources/src/main/res/values-es/strings_shared.xml index 8b0b2d6bbc..627d8c0d42 100644 --- a/shared/resources/src/main/res/values-es/strings_shared.xml +++ b/shared/resources/src/main/res/values-es/strings_shared.xml @@ -65,7 +65,7 @@ No se ha podido leer la ubicación de la sincronización. Comprueba que se pueda acceder a la ubicación y que se hayan concedido los permisos para la ubicación de la carpeta. - An unknown error occurred. Contact support@mega.nz. + Se ha producido un error. Ponte en contacto con support@mega.nz. Something went wrong. @@ -291,7 +291,7 @@ Ampliar - Upload paused, device is not charging + La subida está en pausa, el dispositivo no se está cargando Ninguna sincronización configurada @@ -299,23 +299,23 @@ Tu cuenta Pro Flexi ha sido desactivada porque has cancelado la suscripción o porque el pago ha fallado. No podrás acceder a los datos almacenados en tu cuenta. \nPara realizar el pago y reactivar la suscripción, inicia sesión en MEGA a través de un navegador. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Las subidas solo se realizarán cuando el dispositivo se esté cargando y la batería esté por encima del 20%. Ninguna sincronización configurada - Sync a folder on your device with a folder on MEGA. + Sincroniza una carpeta de tu dispositivo con una carpeta de MEGA. Añadir sincronización Problemas resueltos - This folder can’t be synced. Set it up to sync to MEGA using Camera uploads. + No se puede sincronizar esta carpeta. Configúrala para que se sincronice con MEGA mediante las subidas de la cámara. Descripción @@ -377,27 +377,27 @@ Ampliar cuenta a Pro - Unlock the power to sync your mobile device to the cloud with our Pro plans. + Mantén tu dispositivo móvil sincronizado con la nube con nuestros planes Pro. Ampliar Ahora no - Uploads folder conflict + Conflicto de carpetas de subida - Your Camera uploads folder and secondary media uploads folder cannot be related to each other. Choose a different folder. + La carpeta de subidas de la cámara y la carpeta de subidas multimedia secundarias no pueden estar relacionadas entre sí. Elige una carpeta diferente. - Okay, got it + Entendido - This device doesn’t have an app to select folders + Este dispositivo no tiene ninguna aplicación para seleccionar carpetas - • Automatically sync the folders on your mobile device + • Sincronización automática de las carpetas de tu dispositivo móvil - Your syncs have been paused. Syncing is a Pro plan feature. + Se han pausado tus sincronizaciones. La sincronización es una característica del plan Pro. Aceptar - Syncing is paused because your MEGA Pro plan was cancelled. Upgrade to continue syncing. + La sincronización está en pausa porque tu plan Pro se ha cancelado. Amplía para continuar con la sincronización. Elementos ocultos @@ -407,15 +407,15 @@ Usa las etiquetas para encontrar y organizar tus datos. Puedes etiquetar por año, ubicación, proyecto o tema. - Tag + Etiqueta - Add “#%1$s” tag + Añadir la etiqueta “%1$s” - Existing tags + Etiquetas existentes - Tags can’t contain spaces or non-alphanumeric symbols. Tags written with capital letters will be displayed in lowercase. + Las etiquetas no pueden contener espacios ni símbolos no alfanuméricos. Las etiquetas escritas en mayúsculas se mostrarán en minúsculas. - The maximum number of tags is %1$d + El número máximo de etiquetas es 1%1$d Tags must be %1$d characters or less @@ -423,7 +423,7 @@ No hay descripción - Add to playlist + Añadir a la lista de reproducción Nueva lista de reproducción @@ -431,9 +431,9 @@ Te perderás estas características - You’ll still have access to these features until your MEGA plan expires, then you’ll be moved to a free account. + Seguirás teniendo acceso a estas características hasta que caduque tu plan de MEGA y, luego, pasarás a una cuenta gratis. - You are currently using %1s of storage, which you will risk losing. + Estás usando %1s de almacenamiento, que correrás el riesgo de perder. Característica @@ -457,23 +457,23 @@ Hasta 30 días (solo lectura) - Up to %1s days + Hasta %1s días MEGA VPN - Call &amp; meeting duration + Duración de llamadas y reuniones Hasta 1 hora Ilimitadas - Call &amp; meeting participants + Participantes de llamadas y reuniones Hasta 100 Ilimitados - Keep %1s + Mantener %1s Cancelar subscripción @@ -487,59 +487,59 @@ Cancelar suscripción - Reactivate subscription + Reactivar la suscripción - Your subscription is not managed by Google + Google no administra tu suscripción - This is because you subscribed to MEGA via Apple. To cancel your subscription, you will need to: + Te has suscrito a MEGA a través de Apple. Para cancelar tu suscripción: - On an iOS Device + En un dispositivo iOS - 1. Open the [A]Settings[/A] app. + 1. Abra los [A]Ajustes[/A] de la aplicación. - 2. Tap on your name. + 2. Pulsa en tu nombre. - 3. Tap [A]Subscriptions[/A]. + 3. Pulsa [A]Suscripciones[/A]. - 4. Tap your MEGA subscription. + 4. Pulsa tu suscripción a MEGA. - 5. Tap [A]Cancel subscription[/A]. + 5. Pulsa [A]Cancelar suscripción[/A]. - [A]Tap here[/A] for detailed instructions on how to cancel your subscription on a computer or other device. + [A]Pulsa aquí[/A] para obtener instrucciones detalladas sobre cómo cancelar la suscripción en un equipo u otro dispositivo. Debes cancelar tu suscripción usando un navegador web - You need to reactivate your subscription using a web browser + Debes reactivar tu suscripción mediante un navegador web - This is because you subscribed to MEGA in your web browser. To reactivate your subscription, you will need to: + Te has suscrito a MEGA en tu navegador web. Para reactivar tu suscripción: Te has suscrito a MEGA en tu navegador web. Para cancelar tu suscripción: En un equipo - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visita [A]www.mega.nz[/A] en tu navegador web. 2. Inicia sesión en tu cuenta de MEGA. 3. Haz clic en el menú principal. - 4. Click [A]Settings.[/A] + 4. Haz clic en [A]Ajustes.[/A] - 5. Click [A]Plan[/A]. + 5. Haz clic en [A]plan[/A]. - 6. Click [A]Cancel subscription[/A]. + 6. Haz clic en [A]Cancelar suscripción[/A]. - 6. Click [A]Reactivate subscription[/A]. + 6. Haz clic en [A]Reactivar la suscripción[/A]. En un dispositivo móvil - 1. Visit [A]www.mega.nz[/A] in your web browser. + 1. Visita [A]www.mega.nz[/A] en tu navegador web. 2. Inicia sesión en tu cuenta de MEGA. 3. Pulsa tu avatar. - 4. Tap [A]Cancel subscription[/A]. + 4. Pulsa [A]Cancelar suscripción[/A]. No hay conexión a internet @@ -563,13 +563,14 @@ Creando carpetas… - Starting transfers… + Iniciando transferencias… No cierres la aplicación. Si la cierras, las transferencias que aún no estén en cola se perderán. - Found 1 folder and %1$d file. - Found 1 folder and %1$d files. + Se han encontrado 1 carpeta y %1$d archivo. + Se han encontrado 1 carpeta y %1$d archivos. + Se han encontrado 1 carpeta y %1$d archivos. @@ -579,42 +580,44 @@ - %1$d/%2$d folder - %1$d/%2$d folders + %1$d/%2$d carpeta + %1$d/%2$d carpetas + %1$d/%2$d carpetas - Clear .debris (local cache) + Borrar .debris (caché local) - Clear debris? + ¿Borrar caché local? - Backups of the previous versions of your synced files will be permanently deleted from your device. \n\nCheck the .debris folder in your local device to see if you need to restore anything. + Los backups de las versiones anteriores de los archivos sincronizados se eliminarán de forma permanente del dispositivo. \n\nRevisa la carpeta .debris de tu dispositivo local para ver si necesitas restaurar algo. Cancelar Continuar - .debris folder successfully cleared + La carpeta .debris se ha borrado correctamente - Found %1$s and %2$d file. - Found %1$s and %2$d files. + Se han encontrado %1$s y %2$d archivo. + Se han encontrado %1$s y %2$d archivos. + Se han encontrado %1$s y %2$d archivos. No hay etiquetas Cancelando transferencias… - Enquiries must be at least 10 characters + La descripción debe tener al menos 10 caracteres Describe el problema con al menos 10 caracteres Mantén tus conversaciones privadas - All your messages, group chats, and calls are protected by our zero-knowledge encryption. [A]Learn more[/A] + Todos tus chats de grupo, llamadas y mensajes están protegidos por nuestro cifrado de conocimiento cero. [A]Obtén más información[/A] Invita a un amigo - Invite friends with confidence + Invita a tus amigos con confianza Con seguridad de primer nivel y códigos de verificación, comunícate sin temor a estafas, minería de datos o robo de información @@ -660,25 +663,25 @@ No hay actividad reciente - Remove from recently watched + Eliminar de lo visto recientemente - Removed from recently watched + Eliminado de lo visto recientemente - Recently watched has been cleared + Se ha borrado lo visto recientemente - Scan incomplete + Escaneo incompleto - Your phone doesn’t meet the minimum memory requirements to complete the scan + El teléfono no cumple con los requisitos mínimos de memoria para completar el escaneo - We’re having trouble scanning this document. Please try again. + No se ha podido escanear el documento, inténtalo de nuevo. Cerrar Protege tus llamadas - Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] + Tus reuniones, llamadas familiares y conversaciones privadas están protegidas por nuestro cifrado de conocimiento cero. [A]Obtén más información[/A] - Message must be at least 10 characters + El mensaje debe tener al menos 10 caracteres Introducir motivo @@ -686,23 +689,29 @@ Novedades - Easy, automated sync + Sincronización sencilla y automatizada - Sync a folder on your device with MEGA to access the latest version of your files anywhere + Sincroniza una carpeta de tu dispositivo con MEGA para acceder a la última versión de tus archivos desde cualquier lugar - Sync folders + Carpetas sincronizadas - Upgrade to use sync + Amplía para usar la sincronización Más información Cancelar - Sync options updated + Opciones de sincronización actualizadas - Enable access to invite friends + Activa el acceso para invitar a tus amigos - In order to invite friends, you must allow MEGA to access your contact list + Para poder invitar a tus amigos, debes permitir que MEGA acceda a tu lista de contactos Permitir acceso + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-fr/strings_shared.xml b/shared/resources/src/main/res/values-fr/strings_shared.xml index 60f0ea9489..1b50a40e8a 100644 --- a/shared/resources/src/main/res/values-fr/strings_shared.xml +++ b/shared/resources/src/main/res/values-fr/strings_shared.xml @@ -299,11 +299,11 @@ Votre compte Pro Flexi a été désactivé pour défaut de paiement. Vous ne pourrez plus accéder aux données stockées dans votre compte.\nPour effectuer un paiement et réactiver votre abonnement, connectez-vous à MEGA dans un navigateur. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Les téléversements seront mis en pause jusqu’à ce votre appareil soit en charge. Les téléversements resteront en pause si le niveau de votre batterie est inférieur à 20 %. @@ -708,4 +708,10 @@ Pour inviter des amis, vous devez autoriser MEGA à accéder à votre liste de contacts Autoriser l’accès + + PDF + + JPG + + Dialogue en ligne \ No newline at end of file diff --git a/shared/resources/src/main/res/values-in/strings_shared.xml b/shared/resources/src/main/res/values-in/strings_shared.xml index 62b98a0687..72287c68a7 100644 --- a/shared/resources/src/main/res/values-in/strings_shared.xml +++ b/shared/resources/src/main/res/values-in/strings_shared.xml @@ -286,11 +286,11 @@ Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Unggahan akan dihentikan sementara sampai anda mulai mengisi daya perangkat anda. Unggahan akan tetap dihentikan sementara jika baterai anda di bawah 20%. @@ -690,4 +690,10 @@ In order to invite friends, you must allow MEGA to access your contact list Izinkan Akses + + PDF + + JPG + + Obrolan \ No newline at end of file diff --git a/shared/resources/src/main/res/values-it/strings_shared.xml b/shared/resources/src/main/res/values-it/strings_shared.xml index ca558ba9cc..976f23c142 100644 --- a/shared/resources/src/main/res/values-it/strings_shared.xml +++ b/shared/resources/src/main/res/values-it/strings_shared.xml @@ -299,11 +299,11 @@ Il tuo account Pro Flexi è stato disattivato a causa di un mancato pagamento oppure perché hai disattivato il tuo abbonamento. Non potrai accedere ai dati archiviati nel tuo account.\nPer effettuare un pagamento e riattivare l\’abbonamento, accedi a MEGA tramite un browser. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential I caricamenti verranno sospesi fino a quando non inizierai a caricare il dispositivo. I caricamenti rimarranno comunque in pausa se la batteria è inferiore al 20%. @@ -705,4 +705,10 @@ In order to invite friends, you must allow MEGA to access your contact list Permetti l\’accesso + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ja/strings_shared.xml b/shared/resources/src/main/res/values-ja/strings_shared.xml index 91d6b3f30e..af671ccd58 100644 --- a/shared/resources/src/main/res/values-ja/strings_shared.xml +++ b/shared/resources/src/main/res/values-ja/strings_shared.xml @@ -283,11 +283,11 @@ お支払いが失敗したか、サブスクリプションをキャンセルされたため、お客様のPro Flexiアカウントが無効化されました。そのため、アカウントに保存されているデータにアクセスできなくなります。\nお支払いを行ってサブスクリプションを再開するには、ブラウザからMEGAにログインしてください。 - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential デバイスの充電を開始するまで、アップロードは一時停止されます。バッテリー残量が20 %未満の場合も、アップロードは一時停止されたままになります。 @@ -684,4 +684,10 @@ 友人を招待するには、MEGAがあなたの連絡先リストにアクセスできるようにする必要があります アクセスを許可 + + PDF + + JPG + + チャット \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ko/strings_shared.xml b/shared/resources/src/main/res/values-ko/strings_shared.xml index f3c07a4a10..7fb699f81d 100644 --- a/shared/resources/src/main/res/values-ko/strings_shared.xml +++ b/shared/resources/src/main/res/values-ko/strings_shared.xml @@ -283,11 +283,11 @@ 당신의 Pro Flexi 계정은 결제 실패 또는 구독 취소로 인해 비활성화 되었습니다. 계정 안에 있는 데이터에 접근하지 못할 것입니다.\n결제를 하고 구독을 재활성화 하려면, 브라우저에서 MEGA에 로그인 하세요. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential 장치 충전을 시작할 때까지 업로드가 일시정지 됩니다. 배터리가 20% 이하일 경우 업로드가 일시정지 상태로 유지됩니다. @@ -333,7 +333,7 @@ MEGA를 떠날 필요 없이 연락처를 추가하고, 네트워크를 형성하고, 협업하고, 음성과 영상 통화를 하세요. - Camera uploads is an essential feature for any mobile device and we have got you covered. Sign up for an account now. + 카메라 업로드는 어떠한 모바일 기기에서든 필요한 기능이며 우리는 이 기능이 준비되어 있습니다. 지금 가입하세요. 영지식 암호화 화상 회의. @@ -576,27 +576,26 @@ .debris 폴더를 성공적으로 지웠습니다 - Found %1$s and %2$d file. - Found %1$s and %2$d files. + %1$s와/과 파일 %2$d개 발견 - No tags + 태그 없음 전송 취소 중... - 문의사항은 최소 10자 이상이어야 합니다 + 문의사항은 최소 10자이어야 합니다 문제에 대한 설명을 최소 10자 이상을 입력하세요 - Keep conversations private + 대화를 비공개로 유지 - All your messages, group chats, and calls are protected by our zero-knowledge encryption. [A]Learn more[/A] + 당신의 모든 메시지, 단체 대화, 그리고 통화는 우리의 영지식 암호화로 보호됩니다. [A]더 알아보기[/A] 친구를 초대하세요 - Invite friends with confidence + 확신을 가지고 친구 초대 - With top-notch security and verification codes, reach out without fear of scams, data mining, or information theft + 최고 수준의 보안 및 인증 코드를 통하여, 사기, 데이터 마이닝 또는 정보 도난에 대한 두려움 없이 연락하세요 초대 @@ -604,9 +603,9 @@ 1개 이상의 폴더에 숨겨진 항목이 있습니다. 폴더를 공유하는 것은 숨겨진 항목이 공유하고자 하는 사람들에게 보인다는 것입니다. 항목은 클라우드 드라이브에서 숨긴 상태로 유지됩니다. - We’re sorry to see you leave! Can you tell us why you’re cancelling your subscription? + 떠나시는 것을 보게 되어 안타깝습니다! 왜 구독을 취소하는지 알려주실 수 있나요? - Your subscription will be cancelled immediately and you will be moved to a free MEGA account when your current plan expires. Note: Cancelling your subscription won’t delete your account. + 당신의 구독은 즉시 취소되며 현재 요금제가 만료되면 무료 MEGA 계정으로 옮겨질 것입니다. 참고사항: 구독을 취소하는 것이 계정을 삭제하지는 않습니다. 구독을 취소하는 이유를 선택하세요 @@ -630,35 +629,35 @@ 기타 (자세한 이유를 알려주세요) - I allow MEGA to contact me to talk about this topic further + MEGA가 이 주제에 대하여 나에게 연락하는 것을 허락합니다 구독 취소 취소하지 마세요 - Recently watched + 최근에 본 항목 최근 활동 없음 - Remove from recently watched + 최근에 본 항목에서 제거 - Removed from recently watched + 최근에 본 항목에서 제거함 - Recently watched has been cleared + 최근에 본 항목이 비워졌습니다 - Scan incomplete + 스캔 완료되지 않음 - Your phone doesn’t meet the minimum memory requirements to complete the scan + 당신의 전화기가 스캔을 완료하는 데에 필요한 최소 메모리 요구조건을 충족하지 못합니다 - We’re having trouble scanning this document. Please try again. + 이 문서를 스캔하는 데에 문제가 있습니다. 다시 시도하세요. 닫기 - Protect your calls + 통화 보호 - Your meetings, family calls, and private conversations are protected by our zero-knowledge encryption. [A]Learn more[/A] + 당신의 회의, 가족 통화, 그리고 비공개 대화는 우리의 영지식 암호화로 보호됩니다. [A]더 알아보기[/A] - Message must be at least 10 characters + 메시지는 최소 10자이어야 합니다 자세한 정보를 입력하세요 @@ -666,23 +665,29 @@ 새로운 점 - Easy, automated sync + 쉽고, 자동화된 동기화 - Sync a folder on your device with MEGA to access the latest version of your files anywhere + 당신의 장치의 폴더를 MEGA와 동기화하고 당신의 파일의 최신 버전에 어디서든 접근하세요 - Sync folders + 폴더 동기화 - Upgrade to use sync + 동기화를 이용하려면 업그레이드 더 알아보기 취소 - Sync options updated + 동기화 옵션 업데이트됨 - Enable access to invite friends + 친구를 초대하려면 접근 허용 - In order to invite friends, you must allow MEGA to access your contact list + 친구를 초대하려면, MEGA가 당신의 연락처 목록에 접근하는 것을 허용해야 합니다 접근 허용 + + PDF + + JPG + + 대화 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-nl/strings_shared.xml b/shared/resources/src/main/res/values-nl/strings_shared.xml index c965c00a62..0592ff720e 100644 --- a/shared/resources/src/main/res/values-nl/strings_shared.xml +++ b/shared/resources/src/main/res/values-nl/strings_shared.xml @@ -291,11 +291,11 @@ Uw Pro   Flexi-account is gedeactiveerd vanwege een mislukte betaling of u heeft uw abonnement opgezegd. U hebt geen toegang tot de gegevens die zijn opgeslagen in uw account. \nOm een betaling uit te voeren en uw abonnement te her activeren, moet u via een browser bij MEGA inloggen. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Het uploaden wordt gepauzeerd totdat u begint met het opladen van uw apparaat. Het uploaden blijft gepauzeerd als uw batterij minder dan 20% is. @@ -689,11 +689,17 @@ Annuleren - Sync options updated + Synchronisatie-opties bijgewerkt Toegang inschakelen om vrienden uit te nodigen Om vrienden uit te nodigen, moet u MEGA toegang geven tot uw contactenlijst Toegang Toestaan + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pl/strings_shared.xml b/shared/resources/src/main/res/values-pl/strings_shared.xml index b81145c792..10215278ba 100644 --- a/shared/resources/src/main/res/values-pl/strings_shared.xml +++ b/shared/resources/src/main/res/values-pl/strings_shared.xml @@ -307,11 +307,11 @@ Twoje konto Pro   Flexi zostało dezaktywowane z powodu niepowodzenia płatności lub anulowania subskrypcja. Nie będziesz mieć dostępu do danych przechowywanych na Twoim konto. \nAby dokonać płatności i ponownie aktywować subskrypcja, zaloguj się do MEGA przez przeglądarkę. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Przesyłanie zostanie wstrzymane, dopóki nie zaczniesz ładować urządzenie. Przesyłanie nadal pozostanie wstrzymane, jeśli bateria jest poniżej 20%. @@ -720,4 +720,10 @@ Aby zaprosić znajomych, musisz zezwolić MEGA na dostęp do listy kontaktów Udostępnik + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-pt/strings_shared.xml b/shared/resources/src/main/res/values-pt/strings_shared.xml index 83c02fe516..e4504922b0 100644 --- a/shared/resources/src/main/res/values-pt/strings_shared.xml +++ b/shared/resources/src/main/res/values-pt/strings_shared.xml @@ -299,11 +299,11 @@ A sua conta Pro Flexi foi desativada porque o pagamento falhou ou porque você cancelou a sua assinatura. Já não será possível acessar os dados armazenados na sua conta. \nPara fazer o pagamento e assim reativar a sua assinatura, faça login no MEGA por meio de um navegador em um computador. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Os uploads permanecerão pausados até você começar a carregar o seu dispositivo, e vão continuar pausados se você tiver menos de 20% de bateria. @@ -708,4 +708,10 @@ Para convidar amigos, você precisa permitir que o MEGA acesse a sua lista de contatos Permitir acesso + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ro/strings_shared.xml b/shared/resources/src/main/res/values-ro/strings_shared.xml index 96f320bfbf..14922fbf93 100644 --- a/shared/resources/src/main/res/values-ro/strings_shared.xml +++ b/shared/resources/src/main/res/values-ro/strings_shared.xml @@ -299,11 +299,11 @@ Contul dvs. Pro Flexi a fost dezactivat din cauza neplății sau v-ați anulat abonamentul. Nu veți mai putea accesa datele stocate în contul dvs.\nPentru a efectua o plată și a vă reactiva abonamentul, conectați-vă la MEGA printr-un browser. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Încărcările vor fi întrerupte până când începeți să încărcați dispozitivul. Încărcările vor rămâne în continuare întrerupte dacă bateria este sub 20 %. @@ -708,4 +708,10 @@ Pentru a invita prieteni, trebuie să permiteți MEGA să acceseze lista dvs. de contacte Activează accesul + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-ru/strings_shared.xml b/shared/resources/src/main/res/values-ru/strings_shared.xml index bc198f86bd..de949f633a 100644 --- a/shared/resources/src/main/res/values-ru/strings_shared.xml +++ b/shared/resources/src/main/res/values-ru/strings_shared.xml @@ -307,11 +307,11 @@ Ваш аккаунт Pro Flexi был деактивирован из-за сбоя оплаты или из-за того, что вы отменили подписку. Вы не сможете получить доступ к данным, хранящимся в вашем аккаунте.\nДля оплаты и возобновления подписки войдите в MEGA через веб-браузер. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Загрузка будет приостановлена до тех пор, пока вы не начнете заряжать устройство. Загрузка по-прежнему будет приостановлена, если уровень заряда батареи ниже 20%. @@ -720,4 +720,10 @@ Чтобы приглашать друзей, нужно разрешить MEGA доступ к вашему списку контактов Открыть доступ + + PDF + + JPG + + Чат \ No newline at end of file diff --git a/shared/resources/src/main/res/values-th/strings_shared.xml b/shared/resources/src/main/res/values-th/strings_shared.xml index 764f8b6061..3a6fe0195f 100644 --- a/shared/resources/src/main/res/values-th/strings_shared.xml +++ b/shared/resources/src/main/res/values-th/strings_shared.xml @@ -283,11 +283,11 @@ บัญชี Pro Flexi ของคุณถูกปิดใช้งาน เนื่องจากการชำระเงินไม่สำเร็จหรือคุณได้ยกเลิกการสมัครใช้งานของคุณเอง คุณจะไม่สามารถเข้าถึงข้อมูลของคุณได้\nกรุณาเข้าสู่ระบบ MEGA ผ่านเบราว์เซอร์เพื่อดำเนินการชำระเงินและเปิดใช้การสมัครใช้งานของคุณอีกครั้ง - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential การอัปโหลดจะหยุดชั่วคราวจนกว่าคุณจะเริ่มชาร์จอุปกรณ์ การอัปโหลดจะถูกหยุดไว้ชั่วคราวต่อไปแม้ว่าแบตเตอรี่ของคุณจะต่ำกว่า 20% ก็ตาม @@ -684,4 +684,10 @@ In order to invite friends, you must allow MEGA to access your contact list อนุญาตให้เข้าถึง + + PDF + + JPG + + แชท \ No newline at end of file diff --git a/shared/resources/src/main/res/values-vi/strings_shared.xml b/shared/resources/src/main/res/values-vi/strings_shared.xml index 443b5a92df..05cae16164 100644 --- a/shared/resources/src/main/res/values-vi/strings_shared.xml +++ b/shared/resources/src/main/res/values-vi/strings_shared.xml @@ -283,11 +283,11 @@ Tài khoản Pro Flexi của bạn đã bị vô hiệu hóa do việc thanh toán đã không thành công hoặc bạn đã hủy gói đăng ký dịch vụ. Bạn sẽ không thể truy cập vào dữ liệu đã được lưu trữ trong tài khoản của mình. \nĐể thanh toán và kích hoạt lại gói đăng ký của bạn, hãy đăng nhập vào MEGA bằng trình duyệt web. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Cá phiên tải lên sẽ bị tạm dừng cho đến khi bạn sạc thiết bị của mình. Việc tải lên sẽ vẫn tạm dừng nếu pin của bạn dưới mức 20%. @@ -684,4 +684,10 @@ Để mời bạn bè, bạn phải cho phép MEGA truy cập sổ danh bạ của bạn. Cho phép quyền truy cập + + PDF + + JPG + + Chat \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml index 9ee2e6e1d5..11e9a1f848 100644 --- a/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rCN/strings_shared.xml @@ -283,11 +283,11 @@ 由于付款失败或您已取消订阅,您的Pro Flexi帐户已被停用。您将无法访问存储在您帐户中的数据。 \n若要付款并重新激活您的订阅,请通过浏览器登录MEGA进行。 - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential 上传将暂停,直到您开始为设备充电。如果您的电池电量低于20%,上传仍将保持暂停状态。 @@ -684,4 +684,10 @@ 为了邀请好友,您必须允许MEGA访问您的联系人列表 允许访问 + + PDF + + JPG + + 聊天 \ No newline at end of file diff --git a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml index 6e673ce48a..3221c54f32 100644 --- a/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml +++ b/shared/resources/src/main/res/values-zh-rTW/strings_shared.xml @@ -283,11 +283,11 @@ 由於付款失敗或您已取消訂閱,您的Pro Flexi帳戶已被停用。您將無法存取儲存在您帳戶中的資料。\n若要進行付款並重新啟用您的訂閱,請透過網頁瀏覽器登入MEGA操作。 - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential 上傳將暫停,直到您開始為裝置充電。如果您的電池電量低於20%,上傳仍將保持暫停狀態。 @@ -619,7 +619,7 @@ 我需要的功能MEGA沒有提供 - 我改用一個我更喜歡的提供商 + 我改用一個我更喜歡的供應商 我發現MEGA令人困惑而且難以使用 @@ -629,7 +629,7 @@ 其它(請提供詳細訊息) - 我允許MEGA聯繫我進一步討論這個主題 + 我允許MEGA就這個主題進一步聯繫我 取消訂閱 @@ -679,9 +679,15 @@ 同步選項已更新 - 啟用邀請朋友的存取權限 + 允許存取以邀請朋友 為了邀請朋友,您必須允許MEGA存取您的聯絡人列表 允許存取 + + PDF + + JPG + + 對話 \ No newline at end of file diff --git a/shared/resources/src/main/res/values/strings_shared.xml b/shared/resources/src/main/res/values/strings_shared.xml index 4232e034e6..812d451aa0 100644 --- a/shared/resources/src/main/res/values/strings_shared.xml +++ b/shared/resources/src/main/res/values/strings_shared.xml @@ -291,11 +291,11 @@ Your Pro Flexi account has been deactivated due to payment failure or you’ve cancelled your subscription. You won’t be able to access the data stored in your account. \nTo make a payment and reactivate your subscription, log in to MEGA through a browser. - Starter + MEGA Starter - Basic + MEGA Basic - Essential + MEGA Essential Uploads will be paused until you start charging your device. Uploads will still remain paused if your battery is below 20%. From b617d128ab6389171c0289233081625f87637c70 Mon Sep 17 00:00:00 2001 From: Pau Dominkovics Coll Date: Tue, 1 Oct 2024 00:29:42 +1300 Subject: [PATCH 261/261] TRAN-561: Transfer widget is not hidden when CU is cancelled (cherry picked from commit 634b12647c42af53d45653c5a764e4fbe8c876ce) 888980fb TRAN-561: Transfer widget is not hidden when CU is cancelled 8af9be59 fix and add tests 7384d32c fix and add tests e4a2fcb0 feedback added Co-authored-by: Pau Dominkovics Coll --- .../data/worker/CameraUploadsWorker.kt | 8 +++ .../data/worker/CameraUploadsWorkerTest.kt | 72 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt b/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt index e076fb9382..9cd90cc6c1 100644 --- a/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt +++ b/data/src/main/java/mega/privacy/android/data/worker/CameraUploadsWorker.kt @@ -122,6 +122,8 @@ import mega.privacy.android.domain.usecase.permisison.HasMediaPermissionUseCase import mega.privacy.android.domain.usecase.transfers.CancelTransferByTagUseCase import mega.privacy.android.domain.usecase.transfers.GetTransferByTagUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase +import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase +import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.overquota.BroadcastStorageOverQuotaUseCase import mega.privacy.android.domain.usecase.transfers.overquota.MonitorStorageOverQuotaUseCase @@ -195,6 +197,8 @@ class CameraUploadsWorker @AssistedInject constructor( private val crashReporter: CrashReporter, private val monitorTransferEventsUseCase: MonitorTransferEventsUseCase, private val handleTransferEventUseCase: HandleTransferEventUseCase, + private val clearActiveTransfersIfFinishedUseCase: ClearActiveTransfersIfFinishedUseCase, + private val correctActiveTransfersUseCase: CorrectActiveTransfersUseCase, @LoginMutex private val loginMutex: Mutex, ) : CoroutineWorker(context, workerParams) { @@ -512,6 +516,8 @@ class CameraUploadsWorker @AssistedInject constructor( * Monitors and processes only the Camera Uploads Transfers */ private fun CoroutineScope.monitorCameraUploadsTransfers() = launch { + runCatching { correctActiveTransfersUseCase(TransferType.CU_UPLOAD) } + .onFailure { Timber.e(it) } monitorTransferEventsUseCase() .filter { it.transfer.transferType == TransferType.CU_UPLOAD } .collectChunked( @@ -582,6 +588,8 @@ class CameraUploadsWorker @AssistedInject constructor( private suspend fun resetTotalUploads() { runCatching { resetTotalUploadsUseCase() } .onFailure { Timber.e(it) } + runCatching { clearActiveTransfersIfFinishedUseCase() } + .onFailure { Timber.e(it) } } /** diff --git a/data/src/test/java/mega/privacy/android/data/worker/CameraUploadsWorkerTest.kt b/data/src/test/java/mega/privacy/android/data/worker/CameraUploadsWorkerTest.kt index 52617891c9..0db24a22e5 100644 --- a/data/src/test/java/mega/privacy/android/data/worker/CameraUploadsWorkerTest.kt +++ b/data/src/test/java/mega/privacy/android/data/worker/CameraUploadsWorkerTest.kt @@ -115,6 +115,8 @@ import mega.privacy.android.domain.usecase.permisison.HasMediaPermissionUseCase import mega.privacy.android.domain.usecase.transfers.CancelTransferByTagUseCase import mega.privacy.android.domain.usecase.transfers.GetTransferByTagUseCase import mega.privacy.android.domain.usecase.transfers.MonitorTransferEventsUseCase +import mega.privacy.android.domain.usecase.transfers.active.ClearActiveTransfersIfFinishedUseCase +import mega.privacy.android.domain.usecase.transfers.active.CorrectActiveTransfersUseCase import mega.privacy.android.domain.usecase.transfers.active.HandleTransferEventUseCase import mega.privacy.android.domain.usecase.transfers.overquota.BroadcastStorageOverQuotaUseCase import mega.privacy.android.domain.usecase.transfers.overquota.MonitorStorageOverQuotaUseCase @@ -224,6 +226,8 @@ internal class CameraUploadsWorkerTest { private val crashReporter: CrashReporter = mock() private val monitorTransferEventsUseCase: MonitorTransferEventsUseCase = mock() private val handleTransferEventUseCase: HandleTransferEventUseCase = mock() + private val correctActiveTransfersUseCase = mock() + private val clearActiveTransfersIfFinishedUseCase = mock() private val foregroundInfo = ForegroundInfo(1, mock()) private val primaryNodeHandle = 1111L @@ -317,6 +321,8 @@ internal class CameraUploadsWorkerTest { crashReporter = crashReporter, monitorTransferEventsUseCase = monitorTransferEventsUseCase, handleTransferEventUseCase = handleTransferEventUseCase, + correctActiveTransfersUseCase = correctActiveTransfersUseCase, + clearActiveTransfersIfFinishedUseCase = clearActiveTransfersIfFinishedUseCase, ) ) } @@ -1693,4 +1699,70 @@ internal class CameraUploadsWorkerTest { .invoke(eq(HeartbeatStatus.UP_TO_DATE), any()) assertThat(result).isEqualTo(ListenableWorker.Result.success()) } + + @Test + fun `test that correctActiveTransfersUseCase is invoked when worker starts work`() = runTest { + setupDefaultCheckConditionMocks() + + underTest.doWork() + + verify(correctActiveTransfersUseCase).invoke(TransferType.CU_UPLOAD) + } + + @Test + fun `test that clearActiveTransfersIfFinishedUseCase is invoked when the worker complete with success`() = + runTest { + setupDefaultCheckConditionMocks() + + val result = underTest.doWork() + + verify(resetTotalUploadsUseCase).invoke() + assertThat(result).isEqualTo(ListenableWorker.Result.success()) + } + + @Test + fun `test that clearActiveTransfersIfFinishedUseCase is invoked when the worker complete with failure`() = + runTest { + setupDefaultCheckConditionMocks() + val fakeFlow = MutableStateFlow(true) + val record = mock { + on { folderType }.thenReturn(CameraUploadFolderType.Primary) + } + val list = listOf(record) + val size = 2L // in MB + val file = mock { + on { length() }.thenReturn(size * 1024 * 1024) + } + setupDefaultProcessingFilesConditionMocks(list) + whenever(fileSystemRepository.doesFileExist(record.filePath)).thenReturn(true) + whenever(getFileByPathUseCase(record.filePath)).thenReturn(file) + + val uploadTag = 100 + val transfer = mock { + on { tag }.thenReturn(uploadTag) + on { isFinished }.thenReturn(false) + } + val toUploadEvent = CameraUploadsTransferProgress.ToUpload( + record = record, + transferEvent = TransferEvent.TransferStartEvent(transfer = transfer), + ) + val flow = channelFlow { + send(toUploadEvent) + fakeFlow.emit(false) + } + whenever(monitorConnectivityUseCase()).thenReturn(fakeFlow) + whenever(getTransferByTagUseCase(uploadTag)).thenReturn(transfer) + whenever( + uploadCameraUploadsRecordsUseCase( + list, + NodeId(primaryNodeHandle), + NodeId(secondaryNodeHandle), + tempPath + ) + ).thenReturn(flow) + + underTest.doWork() + + verify(clearActiveTransfersIfFinishedUseCase).invoke() + } }