Attachment changes

* Add attachment table to map attachment to file
* Convert TaskAttachment to immutable data class
* Copy attachments when duplicating tasks
pull/1967/head
Alex Baker 2 years ago
parent 226687fee8
commit 2ac6c2413b

File diff suppressed because it is too large Load Diff

@ -76,6 +76,7 @@ open class BaseTaskEditViewModelTest : InjectingTestCase() {
MutableSharedFlow(),
MutableSharedFlow(),
userActivityDao = userActivityDao,
taskAttachmentDao = db.taskAttachmentDao,
)
}

@ -30,12 +30,13 @@ import org.tasks.notifications.NotificationDao
CaldavAccount::class,
GoogleTaskAccount::class,
Principal::class,
PrincipalAccess::class
PrincipalAccess::class,
Attachment::class,
],
autoMigrations = [
AutoMigration(from = 83, to = 84, spec = Migrations.AutoMigrate83to84::class),
],
version = 85
version = 86
)
abstract class Database : RoomDatabase() {
abstract fun notificationDao(): NotificationDao

@ -15,16 +15,15 @@ import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.lifecycleScope
import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
import org.tasks.Strings
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.compose.edit.AttachmentRow
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao
import org.tasks.dialogs.AddAttachmentDialog
import org.tasks.dialogs.DialogBuilder
import org.tasks.files.FileHelper
import org.tasks.preferences.Preferences
import org.tasks.ui.TaskEditControlFragment
@ -33,7 +32,6 @@ import javax.inject.Inject
@AndroidEntryPoint
class FilesControlSet : TaskEditControlFragment() {
@Inject lateinit var taskAttachmentDao: TaskAttachmentDao
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var preferences: Preferences
override fun createView(savedInstanceState: Bundle?) {
@ -52,10 +50,12 @@ class FilesControlSet : TaskEditControlFragment() {
setContent {
MdcTheme {
AttachmentRow(
attachments = taskAttachmentDao.watchAttachments(viewModel.task.uuid)
.collectAsStateLifecycleAware(initial = emptyList()).value,
attachments = viewModel.selectedAttachments.collectAsStateLifecycleAware().value,
openAttachment = {
FileHelper.startActionView(requireActivity(), it.parseUri())
FileHelper.startActionView(
requireActivity(),
if (Strings.isNullOrEmpty(it.uri)) null else Uri.parse(it.uri)
)
},
deleteAttachment = this@FilesControlSet::deleteAttachment,
addAttachment = {
@ -94,18 +94,9 @@ class FilesControlSet : TaskEditControlFragment() {
}
private fun deleteAttachment(attachment: TaskAttachment) {
dialogBuilder
.newDialog(R.string.premium_remove_file_confirm)
.setPositiveButton(R.string.ok) { _, _ ->
lifecycleScope.launch {
withContext(NonCancellable) {
taskAttachmentDao.delete(attachment)
FileHelper.delete(context, attachment.parseUri())
}
}
}
.setNegativeButton(R.string.cancel, null)
.show()
viewModel.selectedAttachments.update {
it.minus(attachment)
}
}
private fun copyToAttachmentDirectory(input: Uri?) {
@ -114,11 +105,16 @@ class FilesControlSet : TaskEditControlFragment() {
private fun newAttachment(output: Uri) {
val attachment = TaskAttachment(
viewModel.task.uuid,
output,
FileHelper.getFilename(requireContext(), output)!!)
uri = output.toString(),
name = FileHelper.getFilename(requireContext(), output)!!,
)
lifecycleScope.launch {
taskAttachmentDao.createNew(attachment)
taskAttachmentDao.insert(attachment)
viewModel.selectedAttachments.update {
it.plus(
taskAttachmentDao.getAttachment(attachment.remoteId) ?: return@launch
)
}
}
}

@ -20,7 +20,9 @@ class TaskDuplicator @Inject constructor(
private val caldavDao: CaldavDao,
private val locationDao: LocationDao,
private val alarmDao: AlarmDao,
private val preferences: Preferences) {
private val preferences: Preferences,
private val taskAttachmentDao: TaskAttachmentDao,
) {
suspend fun duplicate(taskIds: List<Long>): List<Task> {
val result: MutableList<Task> = ArrayList()
@ -79,6 +81,16 @@ class TaskDuplicator @Inject constructor(
}
gcalHelper.createTaskEventIfEnabled(clone)
taskDao.save(clone, null) // TODO: delete me
taskAttachmentDao
.getAttachmentsForTask(originalId)
.map {
Attachment(
task = clone.id,
fileId = it.fileId,
attachmentUid = it.attachmentUid
)
}
.let { taskAttachmentDao.insert(it) }
getDirectChildren(originalId).forEach { subtask ->
clone(subtask, newId)
}

@ -1,6 +1,7 @@
package com.todoroo.astrid.service
import android.content.Context
import android.net.Uri
import androidx.annotation.ColorRes
import com.google.common.collect.ImmutableListMultimap
import com.google.common.collect.ListMultimap
@ -266,8 +267,11 @@ class Upgrader @Inject constructor(
userActivityDao.update(userActivity)
}
for (attachment in taskAttachmentDao.getAttachments()) {
attachment.convertPathUri()
taskAttachmentDao.update(attachment)
taskAttachmentDao.update(
attachment.copy(
uri = Uri.fromFile(File(attachment.uri)).toString()
)
)
}
}

@ -2,21 +2,7 @@ package org.tasks.backup
import com.todoroo.astrid.data.Task
import org.tasks.backup.TasksJsonImporter.LegacyLocation
import org.tasks.data.Alarm
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavTask
import org.tasks.data.Filter
import org.tasks.data.Geofence
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskList
import org.tasks.data.Place
import org.tasks.data.Tag
import org.tasks.data.TagData
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskListMetadata
import org.tasks.data.UserActivity
import org.tasks.data.*
class BackupContainer(
val tasks: List<TaskBackup>?,
@ -28,6 +14,7 @@ class BackupContainer(
val caldavAccounts: List<CaldavAccount>?,
val caldavCalendars: List<CaldavCalendar>?,
val taskListMetadata: List<TaskListMetadata>?,
val taskAttachments: List<TaskAttachment>,
val intPrefs: Map<String, Integer>?,
val longPrefs: Map<String, java.lang.Long>?,
val stringPrefs: Map<String, String>?,
@ -41,7 +28,7 @@ class BackupContainer(
val tags: List<Tag>,
val google: List<GoogleTask>,
val comments: List<UserActivity>,
val attachments: List<TaskAttachment>?,
val attachments: List<Attachment>?,
val caldavTasks: List<CaldavTask>?,
val vtodo: String?,
) {

@ -15,18 +15,7 @@ import org.tasks.BuildConfig
import org.tasks.R
import org.tasks.backup.BackupContainer.TaskBackup
import org.tasks.caldav.VtodoCache
import org.tasks.data.AlarmDao
import org.tasks.data.CaldavDao
import org.tasks.data.FilterDao
import org.tasks.data.GoogleTaskDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.LocationDao
import org.tasks.data.TagDao
import org.tasks.data.TagDataDao
import org.tasks.data.TaskAttachmentDao
import org.tasks.data.TaskDao
import org.tasks.data.TaskListMetadataDao
import org.tasks.data.UserActivityDao
import org.tasks.data.*
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.extensions.Context.toast
import org.tasks.files.FileHelper
@ -130,7 +119,7 @@ class TasksJsonExporter @Inject constructor(
tagDao.getTagsForTask(taskId),
googleTaskDao.getAllByTaskId(taskId),
userActivityDao.getComments(taskId),
taskAttachmentDao.getAttachments(task.uuid),
taskAttachmentDao.getAttachmentsForTask(taskId),
caldavTasks,
vtodoCache.getVtodo( caldavTasks.firstOrNull { !it.isDeleted() })
))
@ -148,6 +137,7 @@ class TasksJsonExporter @Inject constructor(
caldavDao.getAccounts(),
caldavDao.getCalendars(),
taskListMetadataDao.getAll(),
taskAttachmentDao.getAttachments(),
preferences.getPrefs(Integer::class.java),
preferences.getPrefs(java.lang.Long::class.java),
preferences.getPrefs(String::class.java),

@ -119,6 +119,11 @@ class TasksJsonImporter @Inject constructor(
taskListMetadataDao.insert(tlm)
}
}
backupContainer.taskAttachments.forEach { attachment ->
if (taskAttachmentDao.getAttachment(attachment.remoteId) == null) {
taskAttachmentDao.insert(attachment)
}
}
backupContainer.tasks?.forEach { backup ->
result.taskCount++
setProgressMessage(
@ -198,13 +203,16 @@ class TasksJsonImporter @Inject constructor(
geofence.task = taskId
locationDao.insert(geofence)
}
backup.attachments?.forEach { attachment ->
attachment.taskId = taskUuid
if (version < V6_4) {
attachment.convertPathUri()
backup.attachments
?.mapNotNull { taskAttachmentDao.getAttachment(it.attachmentUid) }
?.map {
Attachment(
task = taskId,
fileId = it.id!!,
attachmentUid = it.remoteId,
)
}
taskAttachmentDao.insert(attachment)
}
?.let { taskAttachmentDao.insert(it) }
backup.caldavTasks?.forEach { caldavTask ->
caldavTask.task = taskId
caldavDao.insert(caldavTask)

@ -11,7 +11,7 @@ import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Clear
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -19,7 +19,6 @@ import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.net.toUri
import com.google.android.material.composethemeadapter.MdcTheme
import org.tasks.R
import org.tasks.compose.DisabledText
@ -46,12 +45,12 @@ fun AttachmentRow(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = it.name!!,
text = it.name,
modifier = Modifier.weight(1f),
)
IconButton(onClick = { deleteAttachment(it) }) {
Icon(
imageVector = Icons.Outlined.Delete,
imageVector = Icons.Outlined.Clear,
contentDescription = stringResource(
id = R.string.delete
),
@ -96,7 +95,10 @@ fun AttachmentPreview() {
MdcTheme {
AttachmentRow(
attachments = listOf(
TaskAttachment("", "file://attachment.txt".toUri(), "attachment.txt")
TaskAttachment(
uri = "file://attachment.txt",
name = "attachment.txt",
)
),
openAttachment = {},
deleteAttachment = {},

@ -0,0 +1,37 @@
package org.tasks.data
import androidx.room.*
import com.todoroo.astrid.data.Task
@Entity(
tableName = "attachment",
foreignKeys = [
ForeignKey(
entity = Task::class,
parentColumns = ["_id"],
childColumns = ["task"],
onDelete = ForeignKey.CASCADE,
),
ForeignKey(
entity = TaskAttachment::class,
parentColumns = ["file_id"],
childColumns = ["file"],
onDelete = ForeignKey.CASCADE,
)
],
indices = [Index(value = ["task", "file"], unique = true)],
)
data class Attachment(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "attachment_id")
@Transient
val id: Long? = null,
@ColumnInfo(name = "task", index = true)
@Transient
val task: Long,
@ColumnInfo(name = "file", index = true)
@Transient
val fileId: Long,
@ColumnInfo(name = "file_uuid")
val attachmentUid: String,
)

@ -1,61 +1,50 @@
package org.tasks.data
import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.todoroo.astrid.data.Task
import org.tasks.Strings
import java.io.File
import com.todoroo.astrid.helper.UUIDHelper
@Entity(tableName = "task_attachments")
class TaskAttachment {
@Entity(tableName = "attachment_file")
data class TaskAttachment(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_id")
@ColumnInfo(name = "file_id")
@Transient
var id: Long? = null
@ColumnInfo(name = "remoteId")
var remoteId: String? = Task.NO_UUID
// -- Constants
@ColumnInfo(name = "task_id")
var taskId: String? = Task.NO_UUID
@ColumnInfo(name = "name")
var name: String? = ""
@ColumnInfo(name = "path")
var uri: String? = ""
private set
@ColumnInfo(name = "content_type")
var contentType: String? = ""
constructor()
val id: Long? = null,
@ColumnInfo(name = "file_uuid")
val remoteId: String = UUIDHelper.newUUID(),
@ColumnInfo(name = "filename")
val name: String,
@ColumnInfo(name = "uri")
val uri: String,
) : Parcelable {
@Ignore
constructor(taskUuid: String, uri: Uri?, fileName: String) {
taskId = taskUuid
name = fileName
setUri(uri?.toString())
constructor(parcel: Parcel) : this(
remoteId = parcel.readString()!!,
name = parcel.readString()!!,
uri = parcel.readString()!!,
)
override fun describeContents() = 0
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(remoteId)
parcel.writeString(name)
parcel.writeString(uri)
}
fun setUri(uri: String?) {
this.uri = uri
}
fun convertPathUri() {
setUri(Uri.fromFile(File(uri!!)).toString())
}
fun parseUri(): Uri? = if (Strings.isNullOrEmpty(uri)) null else Uri.parse(uri)
companion object {
const val KEY = "attachment"
const val FILES_DIRECTORY_DEFAULT = "attachments"
@JvmField
val CREATOR = object : Parcelable.Creator<TaskAttachment> {
override fun createFromParcel(parcel: Parcel) = TaskAttachment(parcel)
/** default directory for files on external storage */
const val FILES_DIRECTORY_DEFAULT = "attachments" // $NON-NLS-1$
override fun newArray(size: Int): Array<TaskAttachment?> = arrayOfNulls(size)
}
}
}

@ -1,37 +1,36 @@
package org.tasks.data
import androidx.room.*
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.helper.UUIDHelper
import kotlinx.coroutines.flow.Flow
@Dao
abstract class TaskAttachmentDao {
@Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid")
abstract suspend fun getAttachments(taskUuid: String): List<TaskAttachment>
interface TaskAttachmentDao {
@Query("SELECT * FROM attachment WHERE task = :task")
suspend fun getAttachmentsForTask(task: Long): List<Attachment>
@Query("SELECT task_attachments.* FROM task_attachments INNER JOIN tasks ON tasks._id = :task WHERE task_id = tasks.remoteId")
abstract suspend fun getAttachments(task: Long): List<TaskAttachment>
@Query("SELECT attachment_file.* FROM attachment_file INNER JOIN attachment ON attachment_file.file_uuid = attachment.file_uuid WHERE task = :task")
suspend fun getAttachments(task: Long): List<TaskAttachment>
@Query("SELECT * FROM task_attachments")
abstract suspend fun getAttachments(): List<TaskAttachment>
@Query("SELECT * FROM attachment_file")
suspend fun getAttachments(): List<TaskAttachment>
@Query("SELECT * FROM task_attachments WHERE task_id = :taskUuid")
abstract fun watchAttachments(taskUuid: String): Flow<List<TaskAttachment>>
@Query("SELECT * FROM attachment_file WHERE file_uuid = :remoteId")
suspend fun getAttachment(remoteId: String): TaskAttachment?
@Delete
abstract suspend fun delete(taskAttachment: TaskAttachment)
@Query("DELETE FROM attachment WHERE task = :taskId AND file_uuid = :attachment")
suspend fun delete(taskId: Long, attachment: String)
@Query("DELETE FROM attachment WHERE task = :taskId AND file_uuid IN (:attachments)")
suspend fun delete(taskId: Long, attachments: List<String>)
@Insert
suspend fun insert(attachments: List<Attachment>)
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract suspend fun insert(attachment: TaskAttachment)
suspend fun insert(attachment: TaskAttachment)
@Update
abstract suspend fun update(attachment: TaskAttachment)
suspend fun createNew(attachment: TaskAttachment) {
if (Task.isUuidEmpty(attachment.remoteId)) {
attachment.remoteId = UUIDHelper.newUUID()
}
insert(attachment)
}
suspend fun update(attachment: TaskAttachment)
@Delete
fun delete(value: List<TaskAttachment>)
}

@ -562,6 +562,24 @@ object Migrations {
}
}
private val MIGRATION_85_86 = object : Migration(85, 86) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `attachment_file` (`file_id` INTEGER PRIMARY KEY AUTOINCREMENT, `file_uuid` TEXT NOT NULL, `filename` TEXT NOT NULL, `uri` TEXT NOT NULL)")
database.execSQL("INSERT INTO `attachment_file` (`file_id`, `uri`,`filename`,`file_id`,`file_uuid`) SELECT `_id`, `path`,`name`,`_id`,`remoteId` FROM `task_attachments`")
database.execSQL("CREATE TABLE IF NOT EXISTS `attachment` (`attachment_id` INTEGER PRIMARY KEY AUTOINCREMENT, `task` INTEGER NOT NULL, `file` INTEGER NOT NULL, `file_uuid` TEXT NOT NULL, FOREIGN KEY(`task`) REFERENCES `tasks`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`file`) REFERENCES `attachment_file`(`file_id`) ON UPDATE NO ACTION ON DELETE CASCADE)")
database.execSQL("CREATE INDEX IF NOT EXISTS `index_attachment_task` ON `attachment` (`task`)")
database.execSQL("CREATE INDEX IF NOT EXISTS `index_attachment_file` ON `attachment` (`file`)")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_attachment_task_file` ON `attachment` (`task`, `file`)")
database.execSQL(
"INSERT INTO `attachment` (`task`, `file`, `file_uuid`) SELECT `tasks`.`_id`, `task_attachments`.`_id`, `task_attachments`.`remoteId` FROM `task_attachments` JOIN `tasks` ON `tasks`.`remoteId` = `task_attachments`.`task_id`"
)
database.execSQL("DROP TABLE `task_attachments`")
}
}
fun migrations(fileStorage: FileStorage) = arrayOf(
MIGRATION_35_36,
MIGRATION_36_37,
@ -603,6 +621,7 @@ object Migrations {
migration_81_82(fileStorage),
MIGRATION_82_83,
MIGRATION_84_85,
MIGRATION_85_86,
)
private fun noop(from: Int, to: Int): Migration = object : Migration(from, to) {

@ -11,7 +11,6 @@ import kotlinx.coroutines.runBlocking
import org.tasks.analytics.Firebase
import org.tasks.data.DeletionDao
import org.tasks.data.LocationDao
import org.tasks.data.TaskAttachmentDao
import org.tasks.data.UserActivityDao
import org.tasks.files.FileHelper
import org.tasks.injection.BaseWorker
@ -28,7 +27,6 @@ class CleanupWork @AssistedInject constructor(
private val geofenceApi: GeofenceApi,
private val timerPlugin: TimerPlugin,
private val alarmService: AlarmService,
private val taskAttachmentDao: TaskAttachmentDao,
private val userActivityDao: UserActivityDao,
private val locationDao: LocationDao,
private val deletionDao: DeletionDao) : BaseWorker(context, workerParams, firebase) {
@ -48,10 +46,6 @@ class CleanupWork @AssistedInject constructor(
locationDao.delete(it)
geofenceApi.update(it.place!!)
}
taskAttachmentDao.getAttachments(task).forEach {
FileHelper.delete(context, it.parseUri())
taskAttachmentDao.delete(it)
}
userActivityDao.getComments(task).forEach {
FileHelper.delete(context, it.pictureUri)
userActivityDao.delete(it)

@ -3,6 +3,7 @@ package org.tasks.ui
import android.content.Context
import android.net.Uri
import androidx.annotation.MainThread
import androidx.core.net.toUri
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -75,6 +76,7 @@ class TaskEditViewModel @Inject constructor(
private val firebase: Firebase? = null,
private val userActivityDao: UserActivityDao,
private val alarmDao: AlarmDao,
private val taskAttachmentDao: TaskAttachmentDao,
) : ViewModel() {
private val resources = context.resources
private var cleared = false
@ -136,6 +138,9 @@ class TaskEditViewModel @Inject constructor(
savedStateHandle.get<ArrayList<TagData>>(TaskEditFragment.EXTRA_TAGS) ?: emptyList()
val selectedTags = MutableStateFlow(ArrayList(originalTags))
private lateinit var originalAttachments: List<TaskAttachment>
val selectedAttachments = MutableStateFlow(emptyList<TaskAttachment>())
private val originalAlarms: List<Alarm> = if (isNew) {
ArrayList<Alarm>().apply {
if (task.isNotifyAtStart) {
@ -201,6 +206,7 @@ class TaskEditViewModel @Inject constructor(
originalList != selectedList.value ||
originalLocation != selectedLocation.value ||
originalTags.toHashSet() != selectedTags.value.toHashSet() ||
originalAttachments.toHashSet() != selectedAttachments.value.toHashSet() ||
newSubtasks.value.isNotEmpty() ||
getRingFlags() != when {
task.isNotifyModeFive -> NOTIFY_MODE_FIVE
@ -318,6 +324,23 @@ class TaskEditViewModel @Inject constructor(
task.modificationDate = now()
}
if (selectedAttachments.value.toHashSet() != originalAttachments.toHashSet()) {
originalAttachments
.minus(selectedAttachments.value.toSet())
.map { it.remoteId }
.let { taskAttachmentDao.delete(task.id, it) }
selectedAttachments.value
.minus(originalAttachments.toSet())
.map {
Attachment(
task = task.id,
fileId = it.id!!,
attachmentUid = it.remoteId,
)
}
.let { taskAttachmentDao.insert(it) }
}
if (task.isCompleted != completed) {
taskCompleter.setComplete(task, completed)
}
@ -366,6 +389,9 @@ class TaskEditViewModel @Inject constructor(
suspend fun discard(remove: Boolean = true) {
if (isNew) {
timerPlugin.stopTimer(task)
originalAttachments.plus(selectedAttachments.value).toSet().takeIf { it.isNotEmpty() }
?.onEach { FileHelper.delete(context, it.uri.toUri()) }
?.let { taskAttachmentDao.delete(it.toList()) }
}
clear(remove)
}
@ -417,6 +443,13 @@ class TaskEditViewModel @Inject constructor(
}
}
init {
viewModelScope.launch {
originalAttachments = taskAttachmentDao.getAttachments(task.id)
selectedAttachments.update { originalAttachments }
}
}
companion object {
fun String?.stripCarriageReturns(): String? = this?.replace("\\r\\n?".toRegex(), "\n")
}

@ -69,7 +69,6 @@
<string name="gtasks_GLA_errorIOAuth">عذرا، لم نتمكن من الاتصال مع مزود الخدمة جوجل. أعد المحاولة مرة أخرى لاحقًًا.</string>
<string name="gtasks_GPr_header">مهام قوقل</string>
<string name="premium_record_audio">تسجيل ملاحظة</string>
<string name="premium_remove_file_confirm">هل أنت متأكد؟ لا يمكن التراجع</string>
<string name="rmd_NoA_done">أكمل</string>
<string name="rmd_NoA_snooze">غفوة</string>
<string name="rmd_EPr_quiet_hours_start_title">ابتداء ساعات الهدوء</string>

@ -130,7 +130,6 @@
<string name="gtasks_GLA_errorIOAuth">Има проблем с връзката до сървърите на Google. Опитайте отново по-късно.</string>
<string name="gtasks_error_accountNotFound">Профилът %s не е намерен. Излезте и влезте отново от настройките на Google Tasks.</string>
<string name="premium_record_audio">Записване на бележка</string>
<string name="premium_remove_file_confirm">Сигурни ли сте? Не може да бъде отменено</string>
<string name="ring_once">Звънене веднъж</string>
<string name="ring_five_times">Звънене пет пъти</string>
<string name="ring_nonstop">Звънене без прекъсване</string>

@ -172,7 +172,6 @@
<string name="repeat_option_every_day">Cada dia</string>
<string name="filter_any_start_date">Qualsevol data d\'inici</string>
<string name="CFC_tag_name">Etiqueta…</string>
<string name="premium_remove_file_confirm">Estàs segur\? No pot ser desfet</string>
<string name="default_random_reminder_hourly">Cada hora</string>
<string name="repeat_option_every_month">Mensualment</string>
<string name="default_random_reminder_disabled">Deshabilitada</string>

@ -105,7 +105,6 @@
<string name="gtasks_GPr_header">Google Úkoly</string>
<string name="gtasks_error_accountNotFound">Účet %s nebyl nalezen — přes nastavení Google Tasks se odhlaste a znovu přihlaste.</string>
<string name="premium_record_audio">Nahrát poznámku</string>
<string name="premium_remove_file_confirm">Opravdu\? Nelze vrátit zpět</string>
<string name="rmd_NoA_done">Dokončeno</string>
<string name="rmd_NoA_snooze">Odložit</string>
<string name="rmd_EPr_quiet_hours_start_title">Nerušit od</string>

@ -482,7 +482,6 @@
<string name="ring_five_times">Ring fem gange</string>
<string name="ring_once">Ring én gang</string>
<string name="premium_record_audio">Optag en note</string>
<string name="premium_remove_file_confirm">Er du sikker\? Det kan ikke fortrydes</string>
<string name="gtasks_GLA_errorIOAuth">Beklager, noget gik galt i kommunikationen med Googles servere. Prøv igen senere.</string>
<string name="gtasks_GLA_authenticating">Godkender…</string>
<string name="gtasks_GTA_clear_completed">Ryd udførte</string>

@ -124,7 +124,6 @@
<string name="gtasks_GLA_errorIOAuth">Leider ist während der Kommunikation mit den Google-Servern ein Problem aufgetreten. Bitte versuchen Sie es später noch einmal.</string>
<string name="gtasks_error_accountNotFound">Konto %s nicht gefunden. Bitte abmelden und erneut über die Einstellungen von Google Tasks anmelden.</string>
<string name="premium_record_audio">Notiz aufzeichnen</string>
<string name="premium_remove_file_confirm">Sind Sie sicher? Das kann nicht rückgängig gemacht werden</string>
<string name="ring_once">Einmal klingeln</string>
<string name="ring_five_times">Fünfmal klingeln</string>
<string name="ring_nonstop">Ununterbrochen klingeln</string>

@ -99,7 +99,6 @@
<string name="gtasks_GPr_header">Εργασίες Google</string>
<string name="gtasks_error_accountNotFound">Λογαριασμός %s δεν βρέθηκε - παρακαλώ αποσυνδεθείτε και συνδεθείτε πάλι απο τις ρυθμίσεις του Google Tasks.</string>
<string name="premium_record_audio">Ηχογράφηση σημείωσης</string>
<string name="premium_remove_file_confirm">Είστε σίγουρος; Δεν μπορεί να ακυρωθεί</string>
<string name="rmd_NoA_done">Ολοκληρωμένο</string>
<string name="rmd_NoA_snooze">Αναβολή</string>
<string name="rmd_EPr_quiet_hours_start_title">Ξεκίνησε η ώρα ησυχίας </string>

@ -146,7 +146,6 @@
<string name="default_random_reminder_disabled">Malŝaltitaj</string>
<string name="rmd_EPr_defaultRemind_title">Hazardaj memorigiloj</string>
<string name="rmd_EPr_rmd_time_title">Defaŭlta memorigilo</string>
<string name="premium_remove_file_confirm">Ĉu vi certas\? Ne povos malfari</string>
<string name="CFC_list_name">En listo…</string>
<string name="CFC_gtasks_list_name">En GTasks Listo…</string>
<string name="CFC_gtasks_list_text">En Listo: \?</string>

@ -124,7 +124,6 @@
<string name="gtasks_GLA_errorIOAuth">Perdón, hubo un problema al comunicarse con los servidores de Google. Por favor inténtalo mas tarde.</string>
<string name="gtasks_error_accountNotFound">No se ha encontrado la cuenta %s — por favor, cierra sesión y vuelve a iniciarla desde la configuración de Google Tasks.</string>
<string name="premium_record_audio">Grabar una nota</string>
<string name="premium_remove_file_confirm">Está seguro? No se puede deshacer</string>
<string name="ring_once">Sonar una vez</string>
<string name="ring_five_times">Sonar cinco veces</string>
<string name="ring_nonstop">Sonar sin parar</string>

@ -98,7 +98,6 @@
<string name="gtasks_GTA_clear_completed">Eemalda lõpetatud</string>
<string name="gtasks_GLA_authenticating">Autentimine…</string>
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="premium_remove_file_confirm">Oled sa kindel\? Seda ei saa tühistada</string>
<string name="ring_once">Helista üks kord</string>
<string name="ring_five_times">Helista 5 korda</string>
<string name="ring_nonstop">Helista lõputult</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Ez da %s kontua aurkitu, amaitu saioa eta hasi saioa berriro Google Tasks ezarpenetatik.</string>
<string name="premium_record_audio">Grabatu ohar bat</string>
<string name="premium_remove_file_confirm">Ziur al zaude\? Hau ezin da desegin</string>
<string name="ring_once">Doinua behin</string>
<string name="ring_five_times">Doinua bost aldiz</string>
<string name="ring_nonstop">Doinua etengabe</string>

@ -85,7 +85,6 @@
<string name="gtasks_GLA_errorIOAuth">پوزش، ارتباط با سرورهای گوگل میسر نشد. لطفا دوباره تلاش نمایید.</string>
<string name="gtasks_GPr_header">وظایف گوگل</string>
<string name="premium_record_audio">ذخیره یادداشت</string>
<string name="premium_remove_file_confirm">آیا مطمن هستید؟ قادر به برگرداندن نخواهید بود</string>
<string name="ring_once">یک بار زنگ بزن</string>
<string name="ring_five_times">پنج بار زنگ بزن</string>
<string name="ring_nonstop">بدون توقف زنگ بزن</string>

@ -116,7 +116,6 @@
<string name="gtasks_GPr_header">Google tehtävät</string>
<string name="gtasks_error_accountNotFound">Tiliä %s ei löydy kirjaudu ulos ja kirjaudu uudelleen Google Tehtävien asetuksiin.</string>
<string name="premium_record_audio">Tallenna muistiinpano</string>
<string name="premium_remove_file_confirm">Oletko varma? Ei voi peruuttaa</string>
<string name="ring_once">Soi kerran</string>
<string name="ring_five_times">Soi viisi kertaa</string>
<string name="ring_nonstop">Soi jatkuvasti</string>

@ -117,7 +117,6 @@
<string name="gtasks_GLA_errorIOAuth">Erreur de communication avec les serveurs Google. Veuillez essayer plus tard.</string>
<string name="gtasks_error_accountNotFound">Le compte %s est introuvable veuillez vous déconnecter puis vous reconnecter depuis les préférences Google Tasks.</string>
<string name="premium_record_audio">Enregistrer un commentaire</string>
<string name="premium_remove_file_confirm">Êtes-vous sûr(e) \? Cette opération est irréversible</string>
<string name="ring_once">Sonner une fois</string>
<string name="ring_five_times">Sonner cinq fois</string>
<string name="ring_nonstop">Sonner en continu</string>

@ -121,7 +121,6 @@
<string name="gtasks_GLA_errorIOAuth">Houbo un problema ao comunicarse cos servidores de Google. Inténtao máis tarde.</string>
<string name="gtasks_error_accountNotFound">Non se atopou a conta %s — pecha a sesión e iníciaa de novo desde a configuración de Google Tasks.</string>
<string name="premium_record_audio">Gravar unha nota</string>
<string name="premium_remove_file_confirm">Está seguro/a\? Non se pode desfacer</string>
<string name="ring_once">Soar unha vez</string>
<string name="ring_five_times">Soar cinco veces</string>
<string name="ring_nonstop">Soar sen parar</string>

@ -484,7 +484,6 @@
<string name="ring_nonstop">Zvoni neprekidno</string>
<string name="ring_five_times">Zvoni pet puta</string>
<string name="ring_once">Zvoni jednom</string>
<string name="premium_remove_file_confirm">Sigurno\? Ne može se poništiti</string>
<string name="premium_record_audio">Snimi bilješku</string>
<string name="gtasks_error_accountNotFound">Račun %s nije pronađen odjavi se i ponovo se prijavi putem Google Tasks postavki.</string>
<string name="gtasks_GPr_header">Google Tasks</string>

@ -123,7 +123,6 @@
<string name="gtasks_GLA_errorIOAuth">Sajnáljuk, de hiba történt a Google szervereivel való kommunikálás során. Próbáld újra később.</string>
<string name="gtasks_error_accountNotFound">%s fiók nem található — kérlek, jelentkezz ki, és vissza a Google Tasks beállításokban.</string>
<string name="premium_record_audio">Jegyzet rögzítése</string>
<string name="premium_remove_file_confirm">Biztos benne? A művelet nem visszavonható</string>
<string name="ring_once">Egy csengés</string>
<string name="ring_five_times">Öt csengés</string>
<string name="ring_nonstop">Folyamatos csengés</string>

@ -88,7 +88,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Akun %s tidak ditemukan—silakan keluar dan masuk kembali dari pengaturan Google Tasks.</string>
<string name="premium_record_audio">Rekam catatan</string>
<string name="premium_remove_file_confirm">Apakah anda yakin\? Ini tidak dapat dibatalkan</string>
<string name="ring_once">Dering sekali</string>
<string name="ring_five_times">Dering lima kali</string>
<string name="ring_nonstop">Dering nonstop</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Account %s non trovato—esci ed accedi nuovamente dalle impostazioni di Google Tasks.</string>
<string name="premium_record_audio">Registra una nota</string>
<string name="premium_remove_file_confirm">Sei sicuro/a\? L\'azione non può essere annullata</string>
<string name="ring_once">Suona una volta</string>
<string name="ring_five_times">Suona cinque volte</string>
<string name="ring_nonstop">Suona ininterrottamente</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">״משימות גוגל״</string>
<string name="gtasks_error_accountNotFound">החשבון %s לא נמצא. אנא התנתק והתחבר שוב במסך הגדרות של ״משימות גוגל״.</string>
<string name="premium_record_audio">הקלד הערה</string>
<string name="premium_remove_file_confirm">בטוח? לא ניתן לבטל את הפעולה</string>
<string name="ring_once">צלצל פעם אחת</string>
<string name="ring_five_times">צלצל חמש פעמים</string>
<string name="ring_nonstop">צלצל ללא הפסקה</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">アカウント %s が見つかりません—ログアウトして再度 Google Tasks 設定からログインしてください.</string>
<string name="premium_record_audio">注釈を記録</string>
<string name="premium_remove_file_confirm">よろしいですか? 取り消しできません</string>
<string name="ring_once">1回通知音を鳴らす</string>
<string name="ring_five_times">5回通知音を鳴らす</string>
<string name="ring_nonstop">通知音を鳴らし続ける</string>

@ -124,7 +124,6 @@
<string name="gtasks_GPr_header">구글 할일 목록 (Google Tasks)</string>
<string name="gtasks_error_accountNotFound">%s 계정을 찾을 수 없습니다 - 로그아웃하고 구글 할일목록 (Google Tasks) 설정에서 다시 로그인해 보세요.</string>
<string name="premium_record_audio">노트 기록</string>
<string name="premium_remove_file_confirm">정말입니까? 되돌릴 수 없습니다</string>
<string name="ring_once">한번 울림</string>
<string name="ring_five_times">다섯번 울림</string>
<string name="ring_nonstop">계속 울림</string>

@ -130,7 +130,6 @@
<string name="gtasks_GLA_errorIOAuth">Atsiprašome, turime bėdų susisiekiant su Google serveriais. Prašome pabandyti vėliau.</string>
<string name="gtasks_error_accountNotFound">Paskyra %s nerasta - prašome atsijungti ir prisijungti iš Google Tasks nustatymų.</string>
<string name="premium_record_audio">Įrašyti pastabą</string>
<string name="premium_remove_file_confirm">Ar tikrai? Nebegalės būti atstatyta</string>
<string name="ring_once">Suskambėti vieną kartą</string>
<string name="ring_five_times">Suskambėti penkis kartus</string>
<string name="ring_nonstop">Skambėti nepaliaujant</string>

@ -218,7 +218,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Kontoen %s ble ikke funnet. Logg ut og inn igjen fra Google Tasks-innstillingene.</string>
<string name="premium_record_audio">Spill inn en anmerkning</string>
<string name="premium_remove_file_confirm">Er du sikker\? Dette kan ikke reverseres</string>
<string name="ring_once">Ring én gang</string>
<string name="ring_five_times">Ring fem ganger</string>
<string name="ring_nonstop">Ring konstant</string>

@ -125,7 +125,6 @@
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Account %s niet gevonden—probeer opnieuw in te loggen via de instellingen van Google Tasks.</string>
<string name="premium_record_audio">Notitie opnemen</string>
<string name="premium_remove_file_confirm">Doorgaan\? Kan niet teruggezet worden</string>
<string name="ring_once">Een keer bellen</string>
<string name="ring_five_times">Vijf keer bellen</string>
<string name="ring_nonstop">Blijven bellen</string>

@ -120,7 +120,6 @@
<string name="gtasks_GPr_header">Zadania Google</string>
<string name="gtasks_error_accountNotFound">Nie znaleziono konta %s —proszę wyloguj się i zaloguj ponownie w ustawieniach Google Zadań.</string>
<string name="premium_record_audio">Nagraj notatkę</string>
<string name="premium_remove_file_confirm">Jesteś pewny\? Tych zmian nie można cofnąć</string>
<string name="ring_once">Dzwoń raz</string>
<string name="ring_five_times">Dzwoń pięć razy</string>
<string name="ring_nonstop">Dzwoń nonstop</string>

@ -121,7 +121,6 @@
<string name="gtasks_GPr_header">Google Tarefas</string>
<string name="gtasks_error_accountNotFound">Conta %s não encontrada—Desconecte e conecte-se novamente pelo painel Google Tasks.</string>
<string name="premium_record_audio">Gravar uma nota</string>
<string name="premium_remove_file_confirm">Tem certeza\? Não pode ser desfeito</string>
<string name="ring_once">Tocar uma vez</string>
<string name="ring_five_times">Tocar cinco vezes</string>
<string name="ring_nonstop">Tocar continuamente</string>

@ -116,7 +116,6 @@
<string name="gtasks_GPr_header">Tarefas Google</string>
<string name="gtasks_error_accountNotFound">Não foi encontrada a conta %s. Termine a sessão e inicie-a novamente nas definições das tarefas Google.</string>
<string name="premium_record_audio">Gravar uma nota áudio</string>
<string name="premium_remove_file_confirm">Tem certeza\? A ação não pode ser anulada</string>
<string name="ring_once">Tocar uma vez</string>
<string name="ring_five_times">Tocar 5 vezes</string>
<string name="ring_nonstop">Tocar sem parar</string>

@ -399,7 +399,6 @@
<string name="ring_nonstop">Sună non-stop</string>
<string name="ring_five_times">Sună de cinci ori</string>
<string name="ring_once">Sună o dată</string>
<string name="premium_remove_file_confirm">Ești sigur\? Nu poate fi anulat</string>
<string name="premium_record_audio">Înregistrați o notă</string>
<string name="gtasks_error_accountNotFound">Contul %s nu a fost găsit - vă rugăm să vă deconectați și să vă conectați din nou din setările Google Tasks.</string>
<string name="gtasks_GPr_header">Sarcini Google</string>

@ -125,7 +125,6 @@
<string name="gtasks_GLA_errorIOAuth">При обращении к серверам Google возникли проблемы. Пожалуйста, попробуйте позже.</string>
<string name="gtasks_error_accountNotFound">Учетная запись %s не найдена — пожалуйста, выйдите и войдите снова через настройки Google Tasks.</string>
<string name="premium_record_audio">Записать заметку</string>
<string name="premium_remove_file_confirm">Вы уверены? Действие нельзя отменить</string>
<string name="ring_once">1 раз</string>
<string name="ring_five_times">5 раз</string>
<string name="ring_nonstop">Звучать безостановочно</string>

@ -363,7 +363,6 @@
<string name="SSD_sort_modified">අවසන් වරට වෙනස් කරන ලද දිනය අනුව</string>
<string name="astrid_sort_order">Astrid අතින් වර්ග කිරීම</string>
<string name="TVA_add_comment">අදහස දක්වන්න…</string>
<string name="premium_remove_file_confirm">ඔබට විශ්වාසද\? අහෝසි කළ නොහැක</string>
<string name="premium_record_audio">සටහනක් පටිගත කරන්න</string>
<string name="gtasks_error_accountNotFound">%s ගිණුම සොයාගත නොහැකිවිය - කරුණාකර Log out වී Google Tasks සැකසුම් වලින් නැවත ලොග් වන්න.</string>
<string name="gtasks_GPr_header">Google කාර්යයන්</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">Úlohy Google</string>
<string name="gtasks_error_accountNotFound">Účet %s sa nenašiel—prosím, odhlás sa a znovu prihlás v nastaveniach Úlohy Google.</string>
<string name="premium_record_audio">Nahrať poznámku</string>
<string name="premium_remove_file_confirm">Naozaj? Nedá sa vrátiť</string>
<string name="ring_once">Zvoniť raz</string>
<string name="ring_five_times">Zvoniť päť krát</string>
<string name="ring_nonstop">Zvoniť neustále</string>

@ -99,7 +99,6 @@
<string name="gtasks_GPr_header">Google Naloge</string>
<string name="gtasks_error_accountNotFound">Račun %s ni najden—prosimo odjavite se, nato pa ponovno prijavite skozi nastavitve Google Nalog.</string>
<string name="premium_record_audio">Posnemi opombo</string>
<string name="premium_remove_file_confirm">Ste prepričani? Tega ni mogoče razveljaviti</string>
<string name="rmd_NoA_done">Končano</string>
<string name="rmd_NoA_snooze">Dremež</string>
<string name="rmd_EPr_quiet_hours_start_title">Tihe ure se začnejo ob</string>

@ -116,7 +116,6 @@
<string name="gtasks_GPr_header">Google Uppgifter</string>
<string name="gtasks_error_accountNotFound">Kontot %s hittades inte— vänligen logga ut och in igen från inställningarna för Google Tasks.</string>
<string name="premium_record_audio">Spela in en anteckning</string>
<string name="premium_remove_file_confirm">Är du säker? Detta kan inte ångras</string>
<string name="ring_once">Ring en gång</string>
<string name="ring_five_times">Ring fem gånger</string>
<string name="ring_nonstop">Ring konstant</string>

@ -111,7 +111,6 @@
<string name="snooze_all">அனைத்தையும் உறக்கநிலையில் வைக்கவும்</string>
<string name="rmd_NoA_snooze">உறக்கநிலை</string>
<string name="rmd_NoA_done">முழுமை</string>
<string name="premium_remove_file_confirm">நீ சொல்வது உறுதியா\? செயல்தவிர்க்க முடியாது</string>
<string name="premium_record_audio">ஒரு குறிப்பைப் பதிவுசெய்க</string>
<string name="gtasks_error_accountNotFound">கணக்கு %s காணப்படவில்லை - தயவுசெய்து வெளியேறி, Google பணிகள் அமைப்புகளிலிருந்து மீண்டும் உள்நுழைக.</string>
<string name="gtasks_GPr_header">Google பணிகள்</string>

@ -508,7 +508,6 @@
<string name="ring_nonstop">แหวนไม่หยุดนิ่ง</string>
<string name="ring_five_times">แหวนห้าครั้ง</string>
<string name="ring_once">เรียกหนึ่งครั้ง</string>
<string name="premium_remove_file_confirm">เธอแน่ใจหรือ ไม่สามารถเลิกทําได้</string>
<string name="premium_record_audio">การบันทึกบันทึกย่อ</string>
<string name="gtasks_GPr_header">งานของ Google</string>
<string name="gtasks_GLA_authenticating">กําลังรับรองความถูกต้อง…</string>

@ -126,7 +126,6 @@
<string name="gtasks_GPr_header">Google Görevler</string>
<string name="gtasks_error_accountNotFound">%s hesabı bulunamadı—lütfen çıkış yapıp Google Görevler ayarlarından yeniden oturum açın.</string>
<string name="premium_record_audio">Bir not kaydet</string>
<string name="premium_remove_file_confirm">Emin misiniz? Geri döndürülemez</string>
<string name="ring_once">Bir kez çal</string>
<string name="ring_five_times">Beş kez çal</string>
<string name="ring_nonstop">Durmadan çal</string>

@ -125,7 +125,6 @@
<string name="gtasks_GLA_errorIOAuth">Вибачте, виникли проблеми звернення до серверів Google. Будь ласка, спробуйте пізніше.</string>
<string name="gtasks_error_accountNotFound">Обліковий запис %s не знайдено — будь ласка, вийдіть і увійдіть знову через налаштування Google Tasks.</string>
<string name="premium_record_audio">Записати голосову замітку</string>
<string name="premium_remove_file_confirm">Ви впевнені\? Це не можна буде скасувати</string>
<string name="ring_once">Звучати один раз</string>
<string name="ring_five_times">Звучати п’ять разів</string>
<string name="ring_nonstop">Звучати безперервно</string>

@ -159,7 +159,6 @@
<string name="ring_nonstop">بغیر رکے رنگ بجنا</string>
<string name="ring_five_times">پانچ بار رنگ بجنا</string>
<string name="ring_once">ایک بار رنگ بجنا</string>
<string name="premium_remove_file_confirm">کیا آپ تیار ہیں؟ یہ واپس نہیں ہو گا</string>
<string name="premium_record_audio">ایک نوٹ ریکارڈ کریں</string>
<string name="repeat_weekly">ہفتہ وار دہرانا</string>
<string name="repeat_daily">روزانہ دہرانا</string>

@ -590,7 +590,6 @@
<string name="ring_nonstop">Đổ chuông không ngừng</string>
<string name="ring_five_times">Đổ chuông năm lần</string>
<string name="ring_once">Đổ chuông một lần</string>
<string name="premium_remove_file_confirm">Bạn có chắc không\? Không thể hoàn tác</string>
<string name="premium_record_audio">Ghi lại một bản ghi chú</string>
<string name="gtasks_error_accountNotFound">Không tìm thấy tài khoản %s—vui lòng đăng xuất và đăng nhập lại trong cài đặt của Google Tasks.</string>
<string name="gtasks_GPr_header">Google Tasks</string>

@ -114,7 +114,6 @@
<string name="gtasks_GLA_errorIOAuth">对不起,我们在与 Google 服务器通讯时遇到了问题。请稍后再尝试。</string>
<string name="gtasks_error_accountNotFound">找不到帐户 %s —请先退出,再从 Google Tasks 设置中重新登录。</string>
<string name="premium_record_audio">录制一条便笺</string>
<string name="premium_remove_file_confirm">您确定吗?此操作无法恢复喔</string>
<string name="ring_once">响铃一次</string>
<string name="ring_five_times">响铃五次</string>
<string name="ring_nonstop">响个不停</string>

@ -95,7 +95,6 @@
<string name="gtasks_GPr_header">Google Tasks (測試中!)</string>
<string name="gtasks_error_accountNotFound">找不到帳戶%s——請退出然後從Google 工作表設置中重新登錄。</string>
<string name="premium_record_audio">錄製一條便箋</string>
<string name="premium_remove_file_confirm">您確定嗎?無法恢復的喔</string>
<string name="ring_once">響鈴一次</string>
<string name="ring_five_times">響鈴五次</string>
<string name="ring_nonstop">不斷響鈴</string>

@ -147,7 +147,6 @@ File %1$s contained %2$s.\n\n
<string name="gtasks_GPr_header">Google Tasks</string>
<string name="gtasks_error_accountNotFound">Account %s not found—please log out and log back in from the Google Tasks settings.</string>
<string name="premium_record_audio">Record a note</string>
<string name="premium_remove_file_confirm">Are you sure? Cannot be undone</string>
<string name="ring_once">Ring once</string>
<string name="ring_five_times">Ring five times</string>
<string name="ring_nonstop">Ring nonstop</string>

Loading…
Cancel
Save