Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05a768fbf6 | ||
|
|
e9ee7ea61b | ||
|
|
c397180786 | ||
|
|
a2f1033184 | ||
|
|
fb67792cf1 | ||
|
|
089d3b3db6 | ||
|
|
5740fa2748 | ||
|
|
dff40712c5 | ||
|
|
46cd22b2e4 | ||
|
|
0687d1a7d7 | ||
|
|
c66d30af19 | ||
|
|
5d81c247aa |
55 changed files with 3623 additions and 155 deletions
BIN
.claude/.DS_Store
vendored
Normal file
BIN
.claude/.DS_Store
vendored
Normal file
Binary file not shown.
15
.claude/commands/commit-push-pr.md
Normal file
15
.claude/commands/commit-push-pr.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
||||
description: Create a git commit
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
- Current git status: !`git status`
|
||||
- Current git diff (staged and unstaged changes): !`git diff HEAD`
|
||||
- Current branch: !`git branch --show-current`
|
||||
- Recent commits: !`git log --oneline -10`
|
||||
|
||||
## Your task
|
||||
|
||||
Based on the above changes, create a single git commit. Then push it.
|
||||
15
.claude/commands/new-version.md
Normal file
15
.claude/commands/new-version.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*)
|
||||
description: Do migration tests first. Then: update changelog, update readme, update version in gradle files, create a git commit and push it
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
- Current git status: !`git status`
|
||||
- Current git diff (staged and unstaged changes): !`git diff HEAD`
|
||||
- Current branch: !`git branch --show-current`
|
||||
- Recent commits: !`git log --oneline -10`
|
||||
|
||||
## Your task
|
||||
|
||||
Do migration tests first. Then: update changelog, update readme, update version in gradle files, create a git commit and push it
|
||||
44
.github/workflows/claude-code-review.yml
vendored
Normal file
44
.github/workflows/claude-code-review.yml
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
name: Claude Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, ready_for_review, reopened]
|
||||
# Optional: Only run on specific file changes
|
||||
# paths:
|
||||
# - "src/**/*.ts"
|
||||
# - "src/**/*.tsx"
|
||||
# - "src/**/*.js"
|
||||
# - "src/**/*.jsx"
|
||||
|
||||
jobs:
|
||||
claude-review:
|
||||
# Optional: Filter by PR author
|
||||
# if: |
|
||||
# github.event.pull_request.user.login == 'external-contributor' ||
|
||||
# github.event.pull_request.user.login == 'new-developer' ||
|
||||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code Review
|
||||
id: claude-review
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
|
||||
plugins: 'code-review@claude-code-plugins'
|
||||
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
|
||||
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||
|
||||
50
.github/workflows/claude.yml
vendored
Normal file
50
.github/workflows/claude.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
name: Claude Code
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
pull_request_review_comment:
|
||||
types: [created]
|
||||
issues:
|
||||
types: [opened, assigned]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
claude:
|
||||
if: |
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
issues: read
|
||||
id-token: write
|
||||
actions: read # Required for Claude to read CI results on PRs
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Run Claude Code
|
||||
id: claude
|
||||
uses: anthropics/claude-code-action@v1
|
||||
with:
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
|
||||
# This is an optional setting that allows Claude to read CI results on PRs
|
||||
additional_permissions: |
|
||||
actions: read
|
||||
|
||||
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
||||
# prompt: 'Update the pull request description to include a summary of changes.'
|
||||
|
||||
# Optional: Add claude_args to customize behavior and configuration
|
||||
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
||||
# or https://code.claude.com/docs/en/cli-reference for available options
|
||||
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
|||
26
AGENTS.md
Normal file
26
AGENTS.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# AGENTS.md
|
||||
|
||||
## Build & Test
|
||||
|
||||
```bash
|
||||
# Build debug APK
|
||||
./gradlew assembleDebug
|
||||
|
||||
# Build release APK (with ProGuard/R8 minification)
|
||||
./gradlew assembleRelease
|
||||
|
||||
# Run unit tests
|
||||
./gradlew test
|
||||
|
||||
# Run instrumented tests (requires emulator/device)
|
||||
./gradlew connectedAndroidTest
|
||||
|
||||
# Clean build
|
||||
./gradlew clean
|
||||
```
|
||||
|
||||
APK outputs: `app/build/outputs/apk/`
|
||||
|
||||
## Development
|
||||
|
||||
TODO: Document how to run the app from Android Studio/emulator once confirmed.
|
||||
84
CLAUDE.md
Normal file
84
CLAUDE.md
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Build debug APK
|
||||
./gradlew assembleDebug
|
||||
|
||||
# Build release APK (with ProGuard/R8 minification)
|
||||
./gradlew assembleRelease
|
||||
|
||||
# Run unit tests
|
||||
./gradlew test
|
||||
|
||||
# Run instrumented tests (requires emulator/device)
|
||||
./gradlew connectedAndroidTest
|
||||
|
||||
# Clean build
|
||||
./gradlew clean
|
||||
```
|
||||
|
||||
APK outputs: `app/build/outputs/apk/`
|
||||
|
||||
## Project Configuration
|
||||
|
||||
- **SDK**: Compile/Target 34, Min 26
|
||||
- **JDK**: 17
|
||||
- **Kotlin**: 1.9.22
|
||||
- **Package**: `com.fastmask`
|
||||
|
||||
## Architecture
|
||||
|
||||
Clean Architecture with MVVM pattern. Three distinct layers:
|
||||
|
||||
### Data Layer (`data/`)
|
||||
- `api/` - JMAP protocol integration (Fastmail's native API)
|
||||
- `JmapApi.kt` - API client with session caching
|
||||
- `JmapService.kt` - Retrofit service interface
|
||||
- `JmapModels.kt` - Kotlinx Serialization models
|
||||
- `local/` - Persistence
|
||||
- `TokenStorage.kt` - EncryptedSharedPreferences (lazy-initialized for Hilt compatibility)
|
||||
- `SettingsDataStore.kt` - DataStore for language preferences
|
||||
- `repository/` - Repository implementations
|
||||
|
||||
### Domain Layer (`domain/`)
|
||||
- `model/` - Domain models (`MaskedEmail`, `Language`, `EmailState` enum)
|
||||
- `repository/` - Abstract interfaces
|
||||
- `usecase/` - Business logic (Login, Logout, CRUD for masked emails, language settings)
|
||||
|
||||
### UI Layer (`ui/`)
|
||||
- `auth/`, `list/`, `create/`, `detail/`, `settings/` - Feature screens with ViewModels
|
||||
- `components/` - Reusable composables (MaskedEmailCard, ShimmerEffect, ErrorMessage)
|
||||
- `navigation/` - Jetpack Navigation with shared element transitions
|
||||
- `theme/` - Material 3 theming with dynamic colors
|
||||
|
||||
## Key Patterns
|
||||
|
||||
**State Management**: `StateFlow<UiState>` for reactive state, `SharedFlow<Event>` for one-time events (navigation, logout)
|
||||
|
||||
**Dependency Injection**: Hilt with `NetworkModule` (Retrofit, OkHttp, Json) and `RepositoryModule` (repository bindings)
|
||||
|
||||
**API Protocol**: JMAP (JSON Mail Access Protocol) with Bearer token auth. Session (accountId, apiUrl) is cached after first call.
|
||||
|
||||
**Security**: Tokens stored in EncryptedSharedPreferences using Android Security Crypto library. TokenStorage uses lazy initialization to prevent Hilt injection issues.
|
||||
|
||||
## Localization
|
||||
|
||||
20 languages supported. String resources in `res/values-*/strings.xml`. In-app language override uses AppCompatDelegate for runtime switching without restart.
|
||||
|
||||
## ProGuard/R8
|
||||
|
||||
Release builds use minification. Key rules in `app/proguard-rules.pro`:
|
||||
- Keep Kotlinx Serialization and JMAP models
|
||||
- Keep Google Tink classes (security-crypto dependency)
|
||||
- Retrofit and OkHttp configurations
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
- `Add: new feature description`
|
||||
- `Fix: bug description`
|
||||
- `Update: what was changed`
|
||||
- `Refactor: what was refactored`
|
||||
23
README.md
23
README.md
|
|
@ -51,6 +51,8 @@ FastMask is a native Android application that lets you manage your [Fastmail](ht
|
|||
| **Delete** | Remove masks you no longer need |
|
||||
| **Search & Filter** | Find specific masks instantly |
|
||||
| **Material You** | Dynamic theming that adapts to your wallpaper |
|
||||
| **20 Languages** | Full localization with in-app language picker |
|
||||
| **Settings** | Language selection, contact/feedback, and logout |
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
|
@ -151,6 +153,7 @@ app/
|
|||
├── list/ # Masked email list
|
||||
├── create/ # Create new mask
|
||||
├── detail/ # View/edit mask details
|
||||
├── settings/ # Settings screen
|
||||
├── components/ # Reusable UI components
|
||||
├── navigation/ # Navigation setup
|
||||
└── theme/ # Material 3 theming
|
||||
|
|
@ -188,6 +191,21 @@ Contributions are welcome! Here's how you can help:
|
|||
|
||||
## Changelog
|
||||
|
||||
### v1.3 (January 2026)
|
||||
- **New**: Settings screen with language picker, contact button, and logout
|
||||
- **New**: Localization support for 20 languages (English, Chinese, Spanish, Hindi, Arabic, Portuguese, Bengali, Russian, Japanese, French, German, Korean, Italian, Turkish, Vietnamese, Polish, Ukrainian, Dutch, Thai, Indonesian)
|
||||
- **New**: In-app language override using AppCompatDelegate
|
||||
- **Improved**: All UI strings now use centralized string resources
|
||||
- **Fixed**: Choppy navigation transitions between Settings and List screens
|
||||
- **Fixed**: Language preference now persists correctly across app restarts
|
||||
- **Improved**: Navigation animations simplified (slide-only, 220ms with FastOutSlowInEasing)
|
||||
- **Improved**: Soft refresh prevents shimmer loading when returning from Settings
|
||||
|
||||
### v1.2 (January 2026)
|
||||
- **Fixed**: Login crash caused by `ParameterizedType` casting error at runtime
|
||||
- **Improved**: TokenStorage now uses lazy initialization for EncryptedSharedPreferences
|
||||
- **Stability**: Deferred crypto initialization prevents reflection errors during Hilt injection
|
||||
|
||||
### v1.1 (January 2026)
|
||||
- **Fixed**: ProGuard/R8 minification crash with `ParameterizedType` casting error
|
||||
- **Improved**: Added proper ProGuard rules for Google Tink (security-crypto dependency)
|
||||
|
|
@ -202,11 +220,10 @@ Contributions are welcome! Here's how you can help:
|
|||
## Roadmap
|
||||
|
||||
- [ ] Add screenshots to README
|
||||
- [ ] Biometric authentication option
|
||||
- [ ] Widget for quick mask creation
|
||||
- [ ] Export/import functionality
|
||||
- [ ] Dark/light mode toggle
|
||||
- [ ] Localization support
|
||||
- [x] Localization support (20 languages)
|
||||
- [x] Settings screen with language picker
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
BIN
app/.DS_Store
vendored
Normal file
BIN
app/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -14,8 +14,8 @@ android {
|
|||
applicationId = "com.fastmask"
|
||||
minSdk = 26
|
||||
targetSdk = 34
|
||||
versionCode = 2
|
||||
versionName = "1.1"
|
||||
versionCode = 4
|
||||
versionName = "1.3"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
|
@ -54,6 +54,7 @@ android {
|
|||
|
||||
buildFeatures {
|
||||
compose = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
|
|
@ -73,6 +74,7 @@ dependencies {
|
|||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
|
||||
implementation("androidx.activity:activity-compose:1.9.0")
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
|
||||
// Compose
|
||||
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,30 @@
|
|||
package com.fastmask
|
||||
|
||||
import android.app.Application
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import com.fastmask.data.local.SettingsDataStore
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class FastMaskApplication : Application()
|
||||
class FastMaskApplication : Application() {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
// Restore saved language after super.onCreate() but before any Activity starts.
|
||||
// We read directly from DataStore here since Hilt injection happens during super.onCreate().
|
||||
restoreSavedLanguage()
|
||||
}
|
||||
|
||||
private fun restoreSavedLanguage() {
|
||||
try {
|
||||
val savedLanguageCode = SettingsDataStore.getLanguageBlocking(this)
|
||||
if (savedLanguageCode != null) {
|
||||
val localeList = LocaleListCompat.forLanguageTags(savedLanguageCode)
|
||||
AppCompatDelegate.setApplicationLocales(localeList)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// If reading fails, use system default locale
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.fastmask
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
|
|
@ -18,7 +18,7 @@ import dagger.hilt.android.AndroidEntryPoint
|
|||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : ComponentActivity() {
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@Inject
|
||||
lateinit var authRepository: AuthRepository
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.fastmask.data.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
val Context.settingsDataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
|
||||
@Singleton
|
||||
class SettingsDataStore @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
private val languageKey = stringPreferencesKey("language_code")
|
||||
|
||||
val languageFlow: Flow<String?> = context.settingsDataStore.data.map { preferences ->
|
||||
preferences[languageKey]
|
||||
}
|
||||
|
||||
suspend fun setLanguage(languageCode: String?) {
|
||||
context.settingsDataStore.edit { preferences ->
|
||||
if (languageCode == null) {
|
||||
preferences.remove(languageKey)
|
||||
} else {
|
||||
preferences[languageKey] = languageCode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getLanguageBlocking(): String? {
|
||||
return runBlocking {
|
||||
context.settingsDataStore.data.first()[languageKey]
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LANGUAGE_KEY = stringPreferencesKey("language_code")
|
||||
|
||||
fun getLanguageBlocking(context: Context): String? {
|
||||
return runBlocking {
|
||||
context.settingsDataStore.data.first()[LANGUAGE_KEY]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,17 +12,19 @@ import javax.inject.Singleton
|
|||
class TokenStorage @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
private val masterKey = MasterKey.Builder(context)
|
||||
private val sharedPreferences: SharedPreferences by lazy {
|
||||
val masterKey = MasterKey.Builder(context)
|
||||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
||||
.build()
|
||||
|
||||
private val sharedPreferences: SharedPreferences = EncryptedSharedPreferences.create(
|
||||
EncryptedSharedPreferences.create(
|
||||
context,
|
||||
PREFS_FILE_NAME,
|
||||
masterKey,
|
||||
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
|
||||
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
|
||||
)
|
||||
}
|
||||
|
||||
fun saveToken(token: String) {
|
||||
sharedPreferences.edit().putString(KEY_API_TOKEN, token).apply()
|
||||
|
|
|
|||
35
app/src/main/java/com/fastmask/domain/model/Language.kt
Normal file
35
app/src/main/java/com/fastmask/domain/model/Language.kt
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package com.fastmask.domain.model
|
||||
|
||||
import com.fastmask.R
|
||||
|
||||
enum class Language(
|
||||
val code: String,
|
||||
val displayNameRes: Int
|
||||
) {
|
||||
ENGLISH("en", R.string.language_en),
|
||||
CHINESE("zh", R.string.language_zh),
|
||||
SPANISH("es", R.string.language_es),
|
||||
HINDI("hi", R.string.language_hi),
|
||||
ARABIC("ar", R.string.language_ar),
|
||||
PORTUGUESE("pt", R.string.language_pt),
|
||||
BENGALI("bn", R.string.language_bn),
|
||||
RUSSIAN("ru", R.string.language_ru),
|
||||
JAPANESE("ja", R.string.language_ja),
|
||||
FRENCH("fr", R.string.language_fr),
|
||||
GERMAN("de", R.string.language_de),
|
||||
KOREAN("ko", R.string.language_ko),
|
||||
ITALIAN("it", R.string.language_it),
|
||||
TURKISH("tr", R.string.language_tr),
|
||||
VIETNAMESE("vi", R.string.language_vi),
|
||||
POLISH("pl", R.string.language_pl),
|
||||
UKRAINIAN("uk", R.string.language_uk),
|
||||
DUTCH("nl", R.string.language_nl),
|
||||
THAI("th", R.string.language_th),
|
||||
INDONESIAN("id", R.string.language_id);
|
||||
|
||||
companion object {
|
||||
fun fromCode(code: String?): Language? {
|
||||
return entries.find { it.code == code }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,26 +15,23 @@ data class MaskedEmail(
|
|||
val url: String?,
|
||||
val emailPrefix: String?,
|
||||
val createdAt: Instant?,
|
||||
val lastMessageAt: Instant?
|
||||
val lastMessageAt: Instant?,
|
||||
val formattedCreatedAt: String? = createdAt?.let { formatInstant(it) },
|
||||
val formattedLastMessageAt: String? = lastMessageAt?.let { formatInstant(it) }
|
||||
) {
|
||||
val displayName: String
|
||||
get() = description?.takeIf { it.isNotBlank() }
|
||||
?: forDomain?.takeIf { it.isNotBlank() }
|
||||
?: email.substringBefore("@")
|
||||
|
||||
val formattedCreatedAt: String?
|
||||
get() = createdAt?.let { formatInstant(it) }
|
||||
|
||||
val formattedLastMessageAt: String?
|
||||
get() = lastMessageAt?.let { formatInstant(it) }
|
||||
|
||||
val isActive: Boolean
|
||||
get() = state == EmailState.ENABLED || state == EmailState.PENDING
|
||||
|
||||
private fun formatInstant(instant: Instant): String {
|
||||
val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
|
||||
companion object {
|
||||
private val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
|
||||
.withZone(ZoneId.systemDefault())
|
||||
return formatter.format(instant)
|
||||
|
||||
fun formatInstant(instant: Instant): String = formatter.format(instant)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.fastmask.domain.usecase
|
||||
|
||||
import com.fastmask.data.local.SettingsDataStore
|
||||
import com.fastmask.domain.model.Language
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetCurrentLanguageUseCase @Inject constructor(
|
||||
private val settingsDataStore: SettingsDataStore
|
||||
) {
|
||||
operator fun invoke(): Flow<Language?> {
|
||||
return settingsDataStore.languageFlow.map { code ->
|
||||
Language.fromCode(code)
|
||||
}
|
||||
}
|
||||
|
||||
fun getBlocking(): Language? {
|
||||
return Language.fromCode(settingsDataStore.getLanguageBlocking())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.fastmask.domain.usecase
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import com.fastmask.data.local.SettingsDataStore
|
||||
import com.fastmask.domain.model.Language
|
||||
import javax.inject.Inject
|
||||
|
||||
class SetLanguageUseCase @Inject constructor(
|
||||
private val settingsDataStore: SettingsDataStore
|
||||
) {
|
||||
suspend operator fun invoke(language: Language?) {
|
||||
val languageCode = language?.code
|
||||
settingsDataStore.setLanguage(languageCode)
|
||||
|
||||
val localeList = if (languageCode != null) {
|
||||
LocaleListCompat.forLanguageTags(languageCode)
|
||||
} else {
|
||||
LocaleListCompat.getEmptyLocaleList()
|
||||
}
|
||||
AppCompatDelegate.setApplicationLocales(localeList)
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +35,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
|
|
@ -42,6 +43,7 @@ import androidx.compose.ui.text.input.VisualTransformation
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.fastmask.R
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
@Composable
|
||||
|
|
@ -80,13 +82,13 @@ fun LoginScreen(
|
|||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(
|
||||
text = "FastMask",
|
||||
text = stringResource(R.string.app_name),
|
||||
style = MaterialTheme.typography.headlineLarge,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
|
||||
Text(
|
||||
text = "Fastmail Masked Email Manager",
|
||||
text = stringResource(R.string.login_subtitle),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
|
@ -96,8 +98,8 @@ fun LoginScreen(
|
|||
OutlinedTextField(
|
||||
value = uiState.token,
|
||||
onValueChange = viewModel::onTokenChange,
|
||||
label = { Text("API Token") },
|
||||
placeholder = { Text("Enter your Fastmail API token") },
|
||||
label = { Text(stringResource(R.string.login_api_token_label)) },
|
||||
placeholder = { Text(stringResource(R.string.login_api_token_placeholder)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
visualTransformation = if (showToken) VisualTransformation.None else PasswordVisualTransformation(),
|
||||
|
|
@ -112,7 +114,11 @@ fun LoginScreen(
|
|||
IconButton(onClick = { showToken = !showToken }) {
|
||||
Icon(
|
||||
imageVector = if (showToken) Icons.Default.VisibilityOff else Icons.Default.Visibility,
|
||||
contentDescription = if (showToken) "Hide token" else "Show token"
|
||||
contentDescription = if (showToken) {
|
||||
stringResource(R.string.login_hide_token)
|
||||
} else {
|
||||
stringResource(R.string.login_show_token)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -143,7 +149,7 @@ fun LoginScreen(
|
|||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Login")
|
||||
Text(stringResource(R.string.login_button))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,17 +165,13 @@ fun LoginScreen(
|
|||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "How to get your API token:",
|
||||
text = stringResource(R.string.login_instructions_title),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = "1. Log in to Fastmail web app\n" +
|
||||
"2. Go to Settings > Privacy & Security\n" +
|
||||
"3. Click on Integrations > API tokens\n" +
|
||||
"4. Create a new token with \"Masked Email\" scope\n" +
|
||||
"5. Copy the token and paste it above",
|
||||
text = stringResource(R.string.login_instructions_full),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = TextAlign.Start
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.fastmask.R
|
||||
|
||||
@Composable
|
||||
fun ErrorMessage(
|
||||
|
|
@ -48,7 +50,7 @@ fun ErrorMessage(
|
|||
if (onRetry != null) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
Button(onClick = onRetry) {
|
||||
Text("Retry")
|
||||
Text(stringResource(R.string.error_retry))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.stateDescription
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.fastmask.R
|
||||
import com.fastmask.domain.model.EmailState
|
||||
import com.fastmask.domain.model.MaskedEmail
|
||||
import com.fastmask.ui.theme.FastMaskStatusColors
|
||||
|
|
@ -46,26 +47,30 @@ fun MaskedEmailCard(
|
|||
onClick: () -> Unit,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedContentScope: AnimatedContentScope,
|
||||
modifier: Modifier = Modifier
|
||||
modifier: Modifier = Modifier,
|
||||
isScrolling: Boolean = false
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val statusColors = FastMaskStatusColors.current
|
||||
|
||||
val stateDescription = when (maskedEmail.state) {
|
||||
EmailState.ENABLED -> "Enabled"
|
||||
EmailState.DISABLED -> "Disabled"
|
||||
EmailState.DELETED -> "Deleted"
|
||||
EmailState.PENDING -> "Pending"
|
||||
EmailState.ENABLED -> stringResource(R.string.state_enabled)
|
||||
EmailState.DISABLED -> stringResource(R.string.state_disabled)
|
||||
EmailState.DELETED -> stringResource(R.string.state_deleted)
|
||||
EmailState.PENDING -> stringResource(R.string.state_pending)
|
||||
}
|
||||
|
||||
with(sharedTransitionScope) {
|
||||
Card(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.sharedBounds(
|
||||
.then(
|
||||
if (!isScrolling) {
|
||||
Modifier.sharedBounds(
|
||||
sharedContentState = rememberSharedContentState(key = "card-${maskedEmail.id}"),
|
||||
animatedVisibilityScope = animatedContentScope
|
||||
)
|
||||
} else Modifier
|
||||
)
|
||||
.clickable {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onClick()
|
||||
|
|
@ -86,10 +91,12 @@ fun MaskedEmailCard(
|
|||
) {
|
||||
StatusIcon(
|
||||
state = maskedEmail.state,
|
||||
modifier = Modifier.sharedElement(
|
||||
modifier = if (!isScrolling) {
|
||||
Modifier.sharedElement(
|
||||
state = rememberSharedContentState(key = "icon-${maskedEmail.id}"),
|
||||
animatedVisibilityScope = animatedContentScope
|
||||
)
|
||||
} else Modifier
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
|
|
@ -98,10 +105,12 @@ fun MaskedEmailCard(
|
|||
style = MaterialTheme.typography.titleMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.sharedElement(
|
||||
modifier = if (!isScrolling) {
|
||||
Modifier.sharedElement(
|
||||
state = rememberSharedContentState(key = "title-${maskedEmail.id}"),
|
||||
animatedVisibilityScope = animatedContentScope
|
||||
)
|
||||
} else Modifier
|
||||
)
|
||||
Text(
|
||||
text = maskedEmail.email,
|
||||
|
|
@ -109,10 +118,12 @@ fun MaskedEmailCard(
|
|||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.sharedElement(
|
||||
modifier = if (!isScrolling) {
|
||||
Modifier.sharedElement(
|
||||
state = rememberSharedContentState(key = "email-${maskedEmail.id}"),
|
||||
animatedVisibilityScope = animatedContentScope
|
||||
)
|
||||
} else Modifier
|
||||
)
|
||||
maskedEmail.forDomain?.let { domain ->
|
||||
Text(
|
||||
|
|
|
|||
131
app/src/main/java/com/fastmask/ui/components/ShimmerEffect.kt
Normal file
131
app/src/main/java/com/fastmask/ui/components/ShimmerEffect.kt
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
package com.fastmask.ui.components
|
||||
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.RepeatMode
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.infiniteRepeatable
|
||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun ShimmerEmailCard(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val shimmerColors = listOf(
|
||||
MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.6f),
|
||||
MaterialTheme.colorScheme.surfaceContainerHighest.copy(alpha = 0.2f),
|
||||
MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha = 0.6f)
|
||||
)
|
||||
|
||||
val transition = rememberInfiniteTransition(label = "shimmer")
|
||||
val translateAnim by transition.animateFloat(
|
||||
initialValue = 0f,
|
||||
targetValue = 1000f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(durationMillis = 1000, easing = LinearEasing),
|
||||
repeatMode = RepeatMode.Restart
|
||||
),
|
||||
label = "shimmer_translate"
|
||||
)
|
||||
|
||||
val brush = Brush.linearGradient(
|
||||
colors = shimmerColors,
|
||||
start = Offset(translateAnim - 500f, translateAnim - 500f),
|
||||
end = Offset(translateAnim, translateAnim)
|
||||
)
|
||||
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 1.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Status icon placeholder
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.clip(CircleShape)
|
||||
.background(brush)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
// Title placeholder
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.6f)
|
||||
.height(20.dp)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(brush)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
// Email placeholder
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.8f)
|
||||
.height(16.dp)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(brush)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
// Domain placeholder
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(0.4f)
|
||||
.height(14.dp)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(brush)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ShimmerEmailList(
|
||||
modifier: Modifier = Modifier,
|
||||
itemCount: Int = 8
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
items(itemCount) {
|
||||
ShimmerEmailCard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,19 +36,19 @@ import androidx.compose.runtime.LaunchedEffect
|
|||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.fastmask.R
|
||||
import com.fastmask.domain.model.EmailState
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
@ -59,16 +59,19 @@ fun CreateMaskedEmailScreen(
|
|||
val uiState by viewModel.uiState.collectAsState()
|
||||
val context = LocalContext.current
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
val createdMessage = stringResource(R.string.create_email_created, "%s")
|
||||
val copyAction = stringResource(R.string.create_email_copy_action)
|
||||
val navigateBackDesc = stringResource(R.string.navigate_back)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.events.collectLatest { event ->
|
||||
when (event) {
|
||||
is CreateMaskedEmailEvent.Created -> {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = "Created: ${event.email}",
|
||||
actionLabel = "Copy",
|
||||
message = createdMessage.replace("%s", event.email),
|
||||
actionLabel = copyAction,
|
||||
duration = SnackbarDuration.Long
|
||||
)
|
||||
if (result == SnackbarResult.ActionPerformed) {
|
||||
|
|
@ -85,7 +88,7 @@ fun CreateMaskedEmailScreen(
|
|||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Create Masked Email") },
|
||||
title = { Text(stringResource(R.string.create_email_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
|
@ -93,7 +96,7 @@ fun CreateMaskedEmailScreen(
|
|||
onNavigateBack()
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Navigate back"
|
||||
contentDescription = navigateBackDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
|
|
@ -122,12 +125,12 @@ fun CreateMaskedEmailScreen(
|
|||
OutlinedTextField(
|
||||
value = uiState.emailPrefix,
|
||||
onValueChange = viewModel::onPrefixChange,
|
||||
label = { Text("Email Prefix (optional)") },
|
||||
placeholder = { Text("e.g., mysite_shopping") },
|
||||
label = { Text(stringResource(R.string.create_email_prefix_label)) },
|
||||
placeholder = { Text(stringResource(R.string.create_email_prefix_placeholder)) },
|
||||
supportingText = {
|
||||
Text(
|
||||
text = uiState.prefixError
|
||||
?: "Max 64 chars: lowercase letters, numbers, underscores"
|
||||
?: stringResource(R.string.create_email_prefix_hint)
|
||||
)
|
||||
},
|
||||
isError = uiState.prefixError != null,
|
||||
|
|
@ -141,8 +144,8 @@ fun CreateMaskedEmailScreen(
|
|||
OutlinedTextField(
|
||||
value = uiState.forDomain,
|
||||
onValueChange = viewModel::onDomainChange,
|
||||
label = { Text("Associated Domain (optional)") },
|
||||
placeholder = { Text("e.g., example.com") },
|
||||
label = { Text(stringResource(R.string.create_email_domain_label)) },
|
||||
placeholder = { Text(stringResource(R.string.create_email_domain_placeholder)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isLoading
|
||||
|
|
@ -153,8 +156,8 @@ fun CreateMaskedEmailScreen(
|
|||
OutlinedTextField(
|
||||
value = uiState.description,
|
||||
onValueChange = viewModel::onDescriptionChange,
|
||||
label = { Text("Description (optional)") },
|
||||
placeholder = { Text("e.g., Shopping account") },
|
||||
label = { Text(stringResource(R.string.create_email_description_label)) },
|
||||
placeholder = { Text(stringResource(R.string.create_email_description_placeholder)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isLoading
|
||||
|
|
@ -165,8 +168,8 @@ fun CreateMaskedEmailScreen(
|
|||
OutlinedTextField(
|
||||
value = uiState.url,
|
||||
onValueChange = viewModel::onUrlChange,
|
||||
label = { Text("URL (optional)") },
|
||||
placeholder = { Text("e.g., https://example.com") },
|
||||
label = { Text(stringResource(R.string.create_email_url_label)) },
|
||||
placeholder = { Text(stringResource(R.string.create_email_url_placeholder)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isLoading
|
||||
|
|
@ -175,7 +178,7 @@ fun CreateMaskedEmailScreen(
|
|||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Text(
|
||||
text = "Initial State",
|
||||
text = stringResource(R.string.create_email_initial_state),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
|
||||
|
|
@ -195,7 +198,11 @@ fun CreateMaskedEmailScreen(
|
|||
enabled = !uiState.isLoading
|
||||
)
|
||||
Text(
|
||||
text = state.name.lowercase().replaceFirstChar { it.uppercase() },
|
||||
text = when (state) {
|
||||
EmailState.ENABLED -> stringResource(R.string.state_enabled)
|
||||
EmailState.DISABLED -> stringResource(R.string.state_disabled)
|
||||
else -> state.name.lowercase().replaceFirstChar { it.uppercase() }
|
||||
},
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
|
|
@ -227,7 +234,7 @@ fun CreateMaskedEmailScreen(
|
|||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Create Masked Email")
|
||||
Text(stringResource(R.string.create_email_button))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ import androidx.compose.material3.Scaffold
|
|||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
|
|
@ -67,11 +66,13 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.fastmask.R
|
||||
import com.fastmask.domain.model.EmailState
|
||||
import com.fastmask.ui.components.ErrorMessage
|
||||
import com.fastmask.ui.components.LoadingIndicator
|
||||
|
|
@ -94,18 +95,25 @@ fun MaskedEmailDetailScreen(
|
|||
val scope = rememberCoroutineScope()
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
val updatedMessage = stringResource(R.string.email_detail_updated)
|
||||
val deletedMessage = stringResource(R.string.email_detail_deleted)
|
||||
val copiedMessage = stringResource(R.string.email_detail_copied)
|
||||
val navigateBackDesc = stringResource(R.string.navigate_back)
|
||||
val deleteEmailDesc = stringResource(R.string.email_detail_delete)
|
||||
val copyEmailDesc = stringResource(R.string.email_detail_copy_email)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.events.collectLatest { event ->
|
||||
when (event) {
|
||||
is MaskedEmailDetailEvent.Updated -> {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Updated successfully",
|
||||
message = updatedMessage,
|
||||
duration = SnackbarDuration.Short
|
||||
)
|
||||
}
|
||||
is MaskedEmailDetailEvent.Deleted -> {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Deleted successfully",
|
||||
message = deletedMessage,
|
||||
duration = SnackbarDuration.Short
|
||||
)
|
||||
onNavigateBack()
|
||||
|
|
@ -117,8 +125,8 @@ fun MaskedEmailDetailScreen(
|
|||
if (showDeleteDialog) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDeleteDialog = false },
|
||||
title = { Text("Delete Masked Email") },
|
||||
text = { Text("Are you sure you want to delete this masked email? This action cannot be undone.") },
|
||||
title = { Text(stringResource(R.string.email_detail_delete_dialog_title)) },
|
||||
text = { Text(stringResource(R.string.email_detail_delete_dialog_message)) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
|
|
@ -129,12 +137,12 @@ fun MaskedEmailDetailScreen(
|
|||
contentColor = MaterialTheme.colorScheme.error
|
||||
)
|
||||
) {
|
||||
Text("Delete")
|
||||
Text(stringResource(R.string.email_detail_delete_confirm))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showDeleteDialog = false }) {
|
||||
Text("Cancel")
|
||||
Text(stringResource(R.string.email_detail_delete_cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -143,7 +151,7 @@ fun MaskedEmailDetailScreen(
|
|||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Email Details") },
|
||||
title = { Text(stringResource(R.string.email_detail_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
|
|
@ -151,7 +159,7 @@ fun MaskedEmailDetailScreen(
|
|||
onNavigateBack()
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Navigate back"
|
||||
contentDescription = navigateBackDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
|
|
@ -168,7 +176,7 @@ fun MaskedEmailDetailScreen(
|
|||
showDeleteDialog = true
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Delete email"
|
||||
contentDescription = deleteEmailDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
|
|
@ -225,11 +233,12 @@ fun MaskedEmailDetailScreen(
|
|||
clipboard.setPrimaryClip(clip)
|
||||
scope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = "Copied to clipboard",
|
||||
message = copiedMessage,
|
||||
duration = SnackbarDuration.Short
|
||||
)
|
||||
}
|
||||
},
|
||||
copyEmailDesc = copyEmailDesc,
|
||||
sharedTransitionScope = sharedTransitionScope,
|
||||
animatedContentScope = animatedContentScope,
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
|
|
@ -250,6 +259,7 @@ private fun EmailDetailContent(
|
|||
onToggleState: () -> Unit,
|
||||
onSaveChanges: () -> Unit,
|
||||
onCopyEmail: (String) -> Unit,
|
||||
copyEmailDesc: String,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedContentScope: AnimatedContentScope,
|
||||
modifier: Modifier = Modifier
|
||||
|
|
@ -323,7 +333,7 @@ private fun EmailDetailContent(
|
|||
onCopyEmail(email.email)
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Copy email address"
|
||||
contentDescription = copyEmailDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
|
|
@ -339,14 +349,18 @@ private fun EmailDetailContent(
|
|||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = "Status: ",
|
||||
text = stringResource(R.string.email_detail_status),
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
Text(
|
||||
text = " ",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
val statusText = when (email.state) {
|
||||
EmailState.ENABLED -> "Enabled"
|
||||
EmailState.DISABLED -> "Disabled"
|
||||
EmailState.DELETED -> "Deleted"
|
||||
EmailState.PENDING -> "Pending"
|
||||
EmailState.ENABLED -> stringResource(R.string.state_enabled)
|
||||
EmailState.DISABLED -> stringResource(R.string.state_disabled)
|
||||
EmailState.DELETED -> stringResource(R.string.state_deleted)
|
||||
EmailState.PENDING -> stringResource(R.string.state_pending)
|
||||
}
|
||||
Text(
|
||||
text = statusText,
|
||||
|
|
@ -359,7 +373,7 @@ private fun EmailDetailContent(
|
|||
email.createdBy?.let { createdBy ->
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = "Created by: $createdBy",
|
||||
text = stringResource(R.string.email_detail_created_by, createdBy),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
|
@ -368,7 +382,7 @@ private fun EmailDetailContent(
|
|||
email.formattedCreatedAt?.let { createdAt ->
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "Created: $createdAt",
|
||||
text = stringResource(R.string.email_detail_created, createdAt),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
|
@ -377,7 +391,7 @@ private fun EmailDetailContent(
|
|||
email.formattedLastMessageAt?.let { lastMessage ->
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "Last message: $lastMessage",
|
||||
text = stringResource(R.string.email_detail_last_message, lastMessage),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
|
@ -410,7 +424,7 @@ private fun EmailDetailContent(
|
|||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Enable")
|
||||
Text(stringResource(R.string.email_detail_enable))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -429,7 +443,7 @@ private fun EmailDetailContent(
|
|||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Disable")
|
||||
Text(stringResource(R.string.email_detail_disable))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -438,7 +452,7 @@ private fun EmailDetailContent(
|
|||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Text(
|
||||
text = "Edit Details",
|
||||
text = stringResource(R.string.email_detail_edit_title),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
|
||||
|
|
@ -447,7 +461,7 @@ private fun EmailDetailContent(
|
|||
OutlinedTextField(
|
||||
value = uiState.editedDescription,
|
||||
onValueChange = onDescriptionChange,
|
||||
label = { Text("Description") },
|
||||
label = { Text(stringResource(R.string.email_detail_description_label)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isUpdating
|
||||
|
|
@ -458,7 +472,7 @@ private fun EmailDetailContent(
|
|||
OutlinedTextField(
|
||||
value = uiState.editedForDomain,
|
||||
onValueChange = onForDomainChange,
|
||||
label = { Text("Associated Domain") },
|
||||
label = { Text(stringResource(R.string.email_detail_domain_label)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isUpdating
|
||||
|
|
@ -469,16 +483,16 @@ private fun EmailDetailContent(
|
|||
OutlinedTextField(
|
||||
value = uiState.editedUrl,
|
||||
onValueChange = onUrlChange,
|
||||
label = { Text("URL") },
|
||||
label = { Text(stringResource(R.string.email_detail_url_label)) },
|
||||
singleLine = true,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !uiState.isUpdating
|
||||
)
|
||||
|
||||
if (uiState.error != null) {
|
||||
uiState.error?.let { error ->
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
Text(
|
||||
text = uiState.error!!,
|
||||
text = error,
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
|
|
@ -501,7 +515,7 @@ private fun EmailDetailContent(
|
|||
strokeWidth = 2.dp
|
||||
)
|
||||
} else {
|
||||
Text("Save Changes")
|
||||
Text(stringResource(R.string.email_detail_save))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.FilterList
|
||||
import androidx.compose.material.icons.filled.Logout
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
|
|
@ -46,27 +46,31 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import kotlinx.coroutines.delay
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.fastmask.R
|
||||
import com.fastmask.domain.model.MaskedEmail
|
||||
import com.fastmask.ui.components.ErrorMessage
|
||||
import com.fastmask.ui.components.LoadingIndicator
|
||||
import com.fastmask.ui.components.MaskedEmailCard
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import com.fastmask.ui.components.ShimmerEmailList
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
fun MaskedEmailListScreen(
|
||||
onNavigateToCreate: () -> Unit,
|
||||
onNavigateToDetail: (String) -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
onNavigateToSettings: () -> Unit,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedContentScope: AnimatedContentScope,
|
||||
viewModel: MaskedEmailListViewModel = hiltViewModel()
|
||||
|
|
@ -83,18 +87,28 @@ fun MaskedEmailListScreen(
|
|||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.events.collectLatest { event ->
|
||||
when (event) {
|
||||
is MaskedEmailListEvent.LoggedOut -> onLogout()
|
||||
val isScrolling by remember {
|
||||
derivedStateOf { listState.isScrollInProgress }
|
||||
}
|
||||
|
||||
val filterEmailsDesc = stringResource(R.string.email_list_filter_emails)
|
||||
val settingsDesc = stringResource(R.string.email_list_settings)
|
||||
val createDesc = stringResource(R.string.email_list_create_description)
|
||||
|
||||
// Refresh the list when the screen resumes (e.g., after creating a new email)
|
||||
// Delay refresh to allow navigation animation to complete smoothly
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
LaunchedEffect(lifecycleOwner) {
|
||||
lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||
delay(250L)
|
||||
viewModel.refreshMaskedEmails()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Masked Emails") },
|
||||
title = { Text(stringResource(R.string.email_list_title)) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
titleContentColor = MaterialTheme.colorScheme.onSurface
|
||||
|
|
@ -107,7 +121,7 @@ fun MaskedEmailListScreen(
|
|||
showFilterMenu = true
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Filter emails"
|
||||
contentDescription = filterEmailsDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
|
|
@ -121,7 +135,16 @@ fun MaskedEmailListScreen(
|
|||
) {
|
||||
EmailFilter.entries.forEach { filter ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(filter.name.lowercase().replaceFirstChar { it.uppercase() }) },
|
||||
text = {
|
||||
Text(
|
||||
when (filter) {
|
||||
EmailFilter.ALL -> stringResource(R.string.filter_all)
|
||||
EmailFilter.ENABLED -> stringResource(R.string.filter_enabled)
|
||||
EmailFilter.DISABLED -> stringResource(R.string.filter_disabled)
|
||||
EmailFilter.DELETED -> stringResource(R.string.filter_deleted)
|
||||
}
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
viewModel.onFilterChange(filter)
|
||||
showFilterMenu = false
|
||||
|
|
@ -133,14 +156,14 @@ fun MaskedEmailListScreen(
|
|||
IconButton(
|
||||
onClick = {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
viewModel.logout()
|
||||
onNavigateToSettings()
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Logout"
|
||||
contentDescription = settingsDesc
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Logout,
|
||||
imageVector = Icons.Default.Settings,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
|
|
@ -160,11 +183,11 @@ fun MaskedEmailListScreen(
|
|||
contentDescription = null
|
||||
)
|
||||
},
|
||||
text = { Text("Create") },
|
||||
text = { Text(stringResource(R.string.email_list_create_fab)) },
|
||||
containerColor = MaterialTheme.colorScheme.tertiaryContainer,
|
||||
contentColor = MaterialTheme.colorScheme.onTertiaryContainer,
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Create new masked email"
|
||||
contentDescription = createDesc
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -196,7 +219,7 @@ fun MaskedEmailListScreen(
|
|||
|
||||
when {
|
||||
uiState.isLoading && uiState.emails.isEmpty() -> {
|
||||
LoadingIndicator()
|
||||
ShimmerEmailList()
|
||||
}
|
||||
|
||||
uiState.error != null && uiState.emails.isEmpty() -> {
|
||||
|
|
@ -214,7 +237,8 @@ fun MaskedEmailListScreen(
|
|||
onEmailClick = { email -> onNavigateToDetail(email.id) },
|
||||
listState = listState,
|
||||
sharedTransitionScope = sharedTransitionScope,
|
||||
animatedContentScope = animatedContentScope
|
||||
animatedContentScope = animatedContentScope,
|
||||
isScrolling = isScrolling
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -232,6 +256,7 @@ private fun M3SearchBar(
|
|||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
val clearSearchDesc = stringResource(R.string.email_list_clear_search)
|
||||
|
||||
SearchBar(
|
||||
inputField = {
|
||||
|
|
@ -241,7 +266,7 @@ private fun M3SearchBar(
|
|||
onSearch = { onActiveChange(false) },
|
||||
expanded = active,
|
||||
onExpandedChange = onActiveChange,
|
||||
placeholder = { Text("Search emails...") },
|
||||
placeholder = { Text(stringResource(R.string.email_list_search_placeholder)) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Search,
|
||||
|
|
@ -258,7 +283,7 @@ private fun M3SearchBar(
|
|||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = "Clear search"
|
||||
contentDescription = clearSearchDesc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -295,7 +320,16 @@ private fun FilterChips(
|
|||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onFilterSelected(filter)
|
||||
},
|
||||
label = { Text(filter.name.lowercase().replaceFirstChar { it.uppercase() }) }
|
||||
label = {
|
||||
Text(
|
||||
when (filter) {
|
||||
EmailFilter.ALL -> stringResource(R.string.filter_all)
|
||||
EmailFilter.ENABLED -> stringResource(R.string.filter_enabled)
|
||||
EmailFilter.DISABLED -> stringResource(R.string.filter_disabled)
|
||||
EmailFilter.DELETED -> stringResource(R.string.filter_deleted)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -310,7 +344,8 @@ private fun EmailList(
|
|||
onEmailClick: (MaskedEmail) -> Unit,
|
||||
listState: LazyListState,
|
||||
sharedTransitionScope: SharedTransitionScope,
|
||||
animatedContentScope: AnimatedContentScope
|
||||
animatedContentScope: AnimatedContentScope,
|
||||
isScrolling: Boolean
|
||||
) {
|
||||
PullToRefreshBox(
|
||||
isRefreshing = isRefreshing,
|
||||
|
|
@ -323,7 +358,7 @@ private fun EmailList(
|
|||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "No masked emails found",
|
||||
text = stringResource(R.string.email_list_empty),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
|
|
@ -343,7 +378,8 @@ private fun EmailList(
|
|||
onClick = { onEmailClick(email) },
|
||||
sharedTransitionScope = sharedTransitionScope,
|
||||
animatedContentScope = animatedContentScope,
|
||||
modifier = Modifier.animateItem()
|
||||
modifier = Modifier.animateItem(),
|
||||
isScrolling = isScrolling
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,44 @@ class MaskedEmailListViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun refreshMaskedEmails() {
|
||||
viewModelScope.launch {
|
||||
// Don't show loading if we already have data (soft refresh)
|
||||
if (_uiState.value.emails.isEmpty()) {
|
||||
_uiState.update { it.copy(isLoading = true, error = null) }
|
||||
}
|
||||
|
||||
getMaskedEmailsUseCase().fold(
|
||||
onSuccess = { emails ->
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
emails = emails.sortedByDescending { email -> email.createdAt },
|
||||
filteredEmails = filterEmails(
|
||||
emails,
|
||||
it.searchQuery,
|
||||
it.selectedFilter
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onFailure = { error ->
|
||||
// Only show error if we have no data
|
||||
if (_uiState.value.emails.isEmpty()) {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
isLoading = false,
|
||||
error = error.message ?: "Failed to load emails"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
_uiState.update { it.copy(isLoading = false) }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSearchQueryChange(query: String) {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.fastmask.ui.navigation
|
|||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
import androidx.compose.animation.SharedTransitionLayout
|
||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
|
|
@ -17,8 +18,9 @@ import com.fastmask.ui.auth.LoginScreen
|
|||
import com.fastmask.ui.create.CreateMaskedEmailScreen
|
||||
import com.fastmask.ui.detail.MaskedEmailDetailScreen
|
||||
import com.fastmask.ui.list.MaskedEmailListScreen
|
||||
import com.fastmask.ui.settings.SettingsScreen
|
||||
|
||||
private const val TRANSITION_DURATION_MS = 300
|
||||
private const val TRANSITION_DURATION_MS = 220
|
||||
|
||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
|
|
@ -35,26 +37,26 @@ fun FastMaskNavHost(
|
|||
enterTransition = {
|
||||
slideIntoContainer(
|
||||
towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
||||
animationSpec = tween(TRANSITION_DURATION_MS)
|
||||
) + fadeIn(animationSpec = tween(TRANSITION_DURATION_MS))
|
||||
animationSpec = tween(TRANSITION_DURATION_MS, easing = FastOutSlowInEasing)
|
||||
)
|
||||
},
|
||||
exitTransition = {
|
||||
slideOutOfContainer(
|
||||
towards = AnimatedContentTransitionScope.SlideDirection.Start,
|
||||
animationSpec = tween(TRANSITION_DURATION_MS)
|
||||
) + fadeOut(animationSpec = tween(TRANSITION_DURATION_MS))
|
||||
animationSpec = tween(TRANSITION_DURATION_MS, easing = FastOutSlowInEasing)
|
||||
)
|
||||
},
|
||||
popEnterTransition = {
|
||||
slideIntoContainer(
|
||||
towards = AnimatedContentTransitionScope.SlideDirection.End,
|
||||
animationSpec = tween(TRANSITION_DURATION_MS)
|
||||
) + fadeIn(animationSpec = tween(TRANSITION_DURATION_MS))
|
||||
animationSpec = tween(TRANSITION_DURATION_MS, easing = FastOutSlowInEasing)
|
||||
)
|
||||
},
|
||||
popExitTransition = {
|
||||
slideOutOfContainer(
|
||||
towards = AnimatedContentTransitionScope.SlideDirection.End,
|
||||
animationSpec = tween(TRANSITION_DURATION_MS)
|
||||
) + fadeOut(animationSpec = tween(TRANSITION_DURATION_MS))
|
||||
animationSpec = tween(TRANSITION_DURATION_MS, easing = FastOutSlowInEasing)
|
||||
)
|
||||
}
|
||||
) {
|
||||
composable(
|
||||
|
|
@ -79,13 +81,24 @@ fun FastMaskNavHost(
|
|||
onNavigateToDetail = { emailId ->
|
||||
navController.navigate(NavRoutes.emailDetail(emailId))
|
||||
},
|
||||
onNavigateToSettings = {
|
||||
navController.navigate(NavRoutes.SETTINGS)
|
||||
},
|
||||
sharedTransitionScope = this@SharedTransitionLayout,
|
||||
animatedContentScope = this@composable
|
||||
)
|
||||
}
|
||||
|
||||
composable(NavRoutes.SETTINGS) {
|
||||
SettingsScreen(
|
||||
onNavigateBack = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
onLogout = {
|
||||
navController.navigate(NavRoutes.LOGIN) {
|
||||
popUpTo(0) { inclusive = true }
|
||||
}
|
||||
},
|
||||
sharedTransitionScope = this@SharedTransitionLayout,
|
||||
animatedContentScope = this@composable
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ object NavRoutes {
|
|||
const val EMAIL_LIST = "email_list"
|
||||
const val CREATE_EMAIL = "create_email"
|
||||
const val EMAIL_DETAIL = "email_detail/{emailId}"
|
||||
const val SETTINGS = "settings"
|
||||
|
||||
fun emailDetail(emailId: String) = "email_detail/$emailId"
|
||||
}
|
||||
|
|
|
|||
304
app/src/main/java/com/fastmask/ui/settings/SettingsScreen.kt
Normal file
304
app/src/main/java/com/fastmask/ui/settings/SettingsScreen.kt
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
package com.fastmask.ui.settings
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.selection.selectable
|
||||
import androidx.compose.foundation.selection.selectableGroup
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.filled.Logout
|
||||
import androidx.compose.material.icons.filled.ChevronRight
|
||||
import androidx.compose.material.icons.filled.Email
|
||||
import androidx.compose.material.icons.filled.Language
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.RadioButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.fastmask.BuildConfig
|
||||
import com.fastmask.R
|
||||
import com.fastmask.domain.model.Language
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SettingsScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onLogout: () -> Unit,
|
||||
viewModel: SettingsViewModel = hiltViewModel()
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
val context = LocalContext.current
|
||||
val haptic = LocalHapticFeedback.current
|
||||
var showLanguageDialog by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.events.collectLatest { event ->
|
||||
when (event) {
|
||||
is SettingsEvent.LoggedOut -> onLogout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showLanguageDialog) {
|
||||
LanguagePickerDialog(
|
||||
selectedLanguage = uiState.selectedLanguage,
|
||||
onLanguageSelected = { language ->
|
||||
viewModel.onLanguageSelected(language)
|
||||
showLanguageDialog = false
|
||||
},
|
||||
onDismiss = { showLanguageDialog = false }
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.settings_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onNavigateBack()
|
||||
},
|
||||
modifier = Modifier.semantics {
|
||||
contentDescription = "Navigate back"
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.surface,
|
||||
titleContentColor = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
// Language Setting
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.settings_language)) },
|
||||
supportingContent = {
|
||||
val languageName = uiState.selectedLanguage?.let {
|
||||
stringResource(it.displayNameRes)
|
||||
} ?: stringResource(R.string.settings_system_default)
|
||||
Text(languageName)
|
||||
},
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Language,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ChevronRight,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
showLanguageDialog = true
|
||||
}
|
||||
)
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
// Contact & Feedback
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.settings_contact)) },
|
||||
supportingContent = { Text(stringResource(R.string.settings_contact_description)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Email,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ChevronRight,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
val emailIntent = Intent(Intent.ACTION_SENDTO).apply {
|
||||
data = Uri.parse("mailto:")
|
||||
putExtra(Intent.EXTRA_EMAIL, arrayOf("pawel@orzech.me"))
|
||||
putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.settings_feedback_subject))
|
||||
}
|
||||
if (emailIntent.resolveActivity(context.packageManager) != null) {
|
||||
context.startActivity(emailIntent)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
// Logout
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.settings_logout)) },
|
||||
supportingContent = { Text(stringResource(R.string.settings_logout_description)) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.Logout,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = MaterialTheme.colorScheme.error
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
viewModel.logout()
|
||||
}
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
// Version
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.settings_version, BuildConfig.VERSION_NAME),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LanguagePickerDialog(
|
||||
selectedLanguage: Language?,
|
||||
onLanguageSelected: (Language?) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val haptic = LocalHapticFeedback.current
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(stringResource(R.string.settings_select_language)) },
|
||||
text = {
|
||||
LazyColumn(
|
||||
modifier = Modifier.selectableGroup()
|
||||
) {
|
||||
// System Default option
|
||||
item {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = selectedLanguage == null,
|
||||
onClick = {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onLanguageSelected(null)
|
||||
},
|
||||
role = Role.RadioButton
|
||||
)
|
||||
.padding(vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
RadioButton(
|
||||
selected = selectedLanguage == null,
|
||||
onClick = null
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.settings_system_default),
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
items(Language.entries) { language ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = selectedLanguage == language,
|
||||
onClick = {
|
||||
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
onLanguageSelected(language)
|
||||
},
|
||||
role = Role.RadioButton
|
||||
)
|
||||
.padding(vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
RadioButton(
|
||||
selected = selectedLanguage == language,
|
||||
onClick = null
|
||||
)
|
||||
Text(
|
||||
text = stringResource(language.displayNameRes),
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(stringResource(R.string.email_detail_delete_cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.fastmask.ui.settings
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.fastmask.domain.model.Language
|
||||
import com.fastmask.domain.usecase.GetCurrentLanguageUseCase
|
||||
import com.fastmask.domain.usecase.LogoutUseCase
|
||||
import com.fastmask.domain.usecase.SetLanguageUseCase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class SettingsViewModel @Inject constructor(
|
||||
private val getCurrentLanguageUseCase: GetCurrentLanguageUseCase,
|
||||
private val setLanguageUseCase: SetLanguageUseCase,
|
||||
private val logoutUseCase: LogoutUseCase
|
||||
) : ViewModel() {
|
||||
|
||||
private val _uiState = MutableStateFlow(SettingsUiState())
|
||||
val uiState: StateFlow<SettingsUiState> = _uiState.asStateFlow()
|
||||
|
||||
private val _events = MutableSharedFlow<SettingsEvent>()
|
||||
val events: SharedFlow<SettingsEvent> = _events.asSharedFlow()
|
||||
|
||||
init {
|
||||
loadCurrentLanguage()
|
||||
}
|
||||
|
||||
private fun loadCurrentLanguage() {
|
||||
viewModelScope.launch {
|
||||
getCurrentLanguageUseCase().collect { language ->
|
||||
_uiState.update { it.copy(selectedLanguage = language) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onLanguageSelected(language: Language?) {
|
||||
viewModelScope.launch {
|
||||
setLanguageUseCase(language)
|
||||
_uiState.update { it.copy(selectedLanguage = language) }
|
||||
}
|
||||
}
|
||||
|
||||
fun logout() {
|
||||
logoutUseCase()
|
||||
viewModelScope.launch {
|
||||
_events.emit(SettingsEvent.LoggedOut)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class SettingsUiState(
|
||||
val selectedLanguage: Language? = null
|
||||
)
|
||||
|
||||
sealed class SettingsEvent {
|
||||
data object LoggedOut : SettingsEvent()
|
||||
}
|
||||
121
app/src/main/res/values-ar/strings.xml
Normal file
121
app/src/main/res/values-ar/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">مدير البريد المقنّع من Fastmail</string>
|
||||
<string name="login_api_token_label">رمز API</string>
|
||||
<string name="login_api_token_placeholder">أدخل رمز API الخاص بـ Fastmail</string>
|
||||
<string name="login_button">تسجيل الدخول</string>
|
||||
<string name="login_show_token">إظهار الرمز</string>
|
||||
<string name="login_hide_token">إخفاء الرمز</string>
|
||||
<string name="login_instructions_title">كيفية الحصول على رمز API:</string>
|
||||
<string name="login_instructions_step1">١. سجّل الدخول إلى تطبيق Fastmail</string>
|
||||
<string name="login_instructions_step2">٢. انتقل إلى الإعدادات > الخصوصية والأمان</string>
|
||||
<string name="login_instructions_step3">٣. انقر على التكاملات > رموز API</string>
|
||||
<string name="login_instructions_step4">٤. أنشئ رمزاً جديداً بصلاحية \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">٥. انسخ الرمز والصقه أعلاه</string>
|
||||
<string name="login_instructions_full">١. سجّل الدخول إلى تطبيق Fastmail\n٢. انتقل إلى الإعدادات > الخصوصية والأمان\n٣. انقر على التكاملات > رموز API\n٤. أنشئ رمزاً جديداً بصلاحية \"Masked Email\"\n٥. انسخ الرمز والصقه أعلاه</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">البريد المقنّع</string>
|
||||
<string name="email_list_search_placeholder">البحث في البريد…</string>
|
||||
<string name="email_list_clear_search">مسح البحث</string>
|
||||
<string name="email_list_filter_emails">تصفية البريد</string>
|
||||
<string name="email_list_create_fab">إنشاء</string>
|
||||
<string name="email_list_create_description">إنشاء بريد مقنّع جديد</string>
|
||||
<string name="email_list_empty">لم يتم العثور على بريد مقنّع</string>
|
||||
<string name="email_list_logout">تسجيل الخروج</string>
|
||||
<string name="email_list_settings">الإعدادات</string>
|
||||
<string name="filter_all">الكل</string>
|
||||
<string name="filter_enabled">مُفعّل</string>
|
||||
<string name="filter_disabled">معطّل</string>
|
||||
<string name="filter_deleted">محذوف</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">إنشاء بريد مقنّع</string>
|
||||
<string name="create_email_prefix_label">بادئة البريد (اختياري)</string>
|
||||
<string name="create_email_prefix_placeholder">مثال: mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">الحد الأقصى ٦٤ حرفاً: أحرف صغيرة، أرقام، شرطات سفلية</string>
|
||||
<string name="create_email_domain_label">النطاق المرتبط (اختياري)</string>
|
||||
<string name="create_email_domain_placeholder">مثال: example.com</string>
|
||||
<string name="create_email_description_label">الوصف (اختياري)</string>
|
||||
<string name="create_email_description_placeholder">مثال: حساب التسوق</string>
|
||||
<string name="create_email_url_label">الرابط (اختياري)</string>
|
||||
<string name="create_email_url_placeholder">مثال: https://example.com</string>
|
||||
<string name="create_email_initial_state">الحالة الأولية</string>
|
||||
<string name="create_email_button">إنشاء بريد مقنّع</string>
|
||||
<string name="create_email_created">تم الإنشاء: %s</string>
|
||||
<string name="create_email_copy_action">نسخ</string>
|
||||
<string name="navigate_back">رجوع</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">تفاصيل البريد</string>
|
||||
<string name="email_detail_copy_email">نسخ عنوان البريد</string>
|
||||
<string name="email_detail_delete">حذف البريد</string>
|
||||
<string name="email_detail_status">الحالة:</string>
|
||||
<string name="email_detail_created_by">أنشأه: %s</string>
|
||||
<string name="email_detail_created">تاريخ الإنشاء: %s</string>
|
||||
<string name="email_detail_last_message">آخر رسالة: %s</string>
|
||||
<string name="email_detail_enable">تفعيل</string>
|
||||
<string name="email_detail_disable">تعطيل</string>
|
||||
<string name="email_detail_edit_title">تعديل التفاصيل</string>
|
||||
<string name="email_detail_description_label">الوصف</string>
|
||||
<string name="email_detail_domain_label">النطاق المرتبط</string>
|
||||
<string name="email_detail_url_label">الرابط</string>
|
||||
<string name="email_detail_save">حفظ التغييرات</string>
|
||||
<string name="email_detail_updated">تم التحديث بنجاح</string>
|
||||
<string name="email_detail_deleted">تم الحذف بنجاح</string>
|
||||
<string name="email_detail_copied">تم النسخ إلى الحافظة</string>
|
||||
<string name="email_detail_delete_dialog_title">حذف البريد المقنّع</string>
|
||||
<string name="email_detail_delete_dialog_message">هل أنت متأكد أنك تريد حذف هذا البريد المقنّع؟ لا يمكن التراجع عن هذا الإجراء.</string>
|
||||
<string name="email_detail_delete_confirm">حذف</string>
|
||||
<string name="email_detail_delete_cancel">إلغاء</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">مُفعّل</string>
|
||||
<string name="state_disabled">معطّل</string>
|
||||
<string name="state_deleted">محذوف</string>
|
||||
<string name="state_pending">قيد الانتظار</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">فشل تحميل البريد</string>
|
||||
<string name="error_retry">إعادة المحاولة</string>
|
||||
<string name="error_generic">حدث خطأ</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">الإعدادات</string>
|
||||
<string name="settings_language">اللغة</string>
|
||||
<string name="settings_language_description">اختر لغة التطبيق</string>
|
||||
<string name="settings_system_default">الافتراضي للنظام</string>
|
||||
<string name="settings_contact">التواصل والملاحظات</string>
|
||||
<string name="settings_contact_description">أرسل لنا ملاحظاتك</string>
|
||||
<string name="settings_logout">تسجيل الخروج</string>
|
||||
<string name="settings_logout_description">الخروج من حسابك</string>
|
||||
<string name="settings_version">الإصدار %s</string>
|
||||
<string name="settings_select_language">اختر اللغة</string>
|
||||
<string name="settings_feedback_subject">ملاحظات FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-bn/strings.xml
Normal file
121
app/src/main/res/values-bn/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail মাস্কড ইমেইল ম্যানেজার</string>
|
||||
<string name="login_api_token_label">API টোকেন</string>
|
||||
<string name="login_api_token_placeholder">আপনার Fastmail API টোকেন দিন</string>
|
||||
<string name="login_button">লগইন</string>
|
||||
<string name="login_show_token">টোকেন দেখান</string>
|
||||
<string name="login_hide_token">টোকেন লুকান</string>
|
||||
<string name="login_instructions_title">কীভাবে আপনার API টোকেন পাবেন:</string>
|
||||
<string name="login_instructions_step1">১. Fastmail ওয়েব অ্যাপে লগইন করুন</string>
|
||||
<string name="login_instructions_step2">২. সেটিংস > প্রাইভেসি এবং সিকিউরিটিতে যান</string>
|
||||
<string name="login_instructions_step3">৩. ইন্টিগ্রেশন > API টোকেনে ক্লিক করুন</string>
|
||||
<string name="login_instructions_step4">৪. \"Masked Email\" স্কোপ সহ একটি নতুন টোকেন তৈরি করুন</string>
|
||||
<string name="login_instructions_step5">৫. টোকেন কপি করুন এবং উপরে পেস্ট করুন</string>
|
||||
<string name="login_instructions_full">১. Fastmail ওয়েব অ্যাপে লগইন করুন\n২. সেটিংস > প্রাইভেসি এবং সিকিউরিটিতে যান\n৩. ইন্টিগ্রেশন > API টোকেনে ক্লিক করুন\n৪. \"Masked Email\" স্কোপ সহ একটি নতুন টোকেন তৈরি করুন\n৫. টোকেন কপি করুন এবং উপরে পেস্ট করুন</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">মাস্কড ইমেইল</string>
|
||||
<string name="email_list_search_placeholder">ইমেইল খুঁজুন…</string>
|
||||
<string name="email_list_clear_search">সার্চ মুছুন</string>
|
||||
<string name="email_list_filter_emails">ইমেইল ফিল্টার করুন</string>
|
||||
<string name="email_list_create_fab">তৈরি করুন</string>
|
||||
<string name="email_list_create_description">নতুন মাস্কড ইমেইল তৈরি করুন</string>
|
||||
<string name="email_list_empty">কোনো মাস্কড ইমেইল পাওয়া যায়নি</string>
|
||||
<string name="email_list_logout">লগআউট</string>
|
||||
<string name="email_list_settings">সেটিংস</string>
|
||||
<string name="filter_all">সব</string>
|
||||
<string name="filter_enabled">সক্রিয়</string>
|
||||
<string name="filter_disabled">নিষ্ক্রিয়</string>
|
||||
<string name="filter_deleted">মুছে ফেলা</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">মাস্কড ইমেইল তৈরি করুন</string>
|
||||
<string name="create_email_prefix_label">ইমেইল প্রিফিক্স (ঐচ্ছিক)</string>
|
||||
<string name="create_email_prefix_placeholder">যেমন, mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">সর্বোচ্চ ৬৪ অক্ষর: ছোট হাতের অক্ষর, সংখ্যা, আন্ডারস্কোর</string>
|
||||
<string name="create_email_domain_label">সংশ্লিষ্ট ডোমেইন (ঐচ্ছিক)</string>
|
||||
<string name="create_email_domain_placeholder">যেমন, example.com</string>
|
||||
<string name="create_email_description_label">বিবরণ (ঐচ্ছিক)</string>
|
||||
<string name="create_email_description_placeholder">যেমন, শপিং অ্যাকাউন্ট</string>
|
||||
<string name="create_email_url_label">URL (ঐচ্ছিক)</string>
|
||||
<string name="create_email_url_placeholder">যেমন, https://example.com</string>
|
||||
<string name="create_email_initial_state">প্রাথমিক অবস্থা</string>
|
||||
<string name="create_email_button">মাস্কড ইমেইল তৈরি করুন</string>
|
||||
<string name="create_email_created">তৈরি হয়েছে: %s</string>
|
||||
<string name="create_email_copy_action">কপি</string>
|
||||
<string name="navigate_back">পিছনে যান</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">ইমেইল বিবরণ</string>
|
||||
<string name="email_detail_copy_email">ইমেইল ঠিকানা কপি করুন</string>
|
||||
<string name="email_detail_delete">ইমেইল মুছুন</string>
|
||||
<string name="email_detail_status">অবস্থা:</string>
|
||||
<string name="email_detail_created_by">তৈরি করেছেন: %s</string>
|
||||
<string name="email_detail_created">তৈরি: %s</string>
|
||||
<string name="email_detail_last_message">শেষ বার্তা: %s</string>
|
||||
<string name="email_detail_enable">সক্রিয় করুন</string>
|
||||
<string name="email_detail_disable">নিষ্ক্রিয় করুন</string>
|
||||
<string name="email_detail_edit_title">বিবরণ সম্পাদনা করুন</string>
|
||||
<string name="email_detail_description_label">বিবরণ</string>
|
||||
<string name="email_detail_domain_label">সংশ্লিষ্ট ডোমেইন</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">পরিবর্তন সংরক্ষণ করুন</string>
|
||||
<string name="email_detail_updated">সফলভাবে আপডেট হয়েছে</string>
|
||||
<string name="email_detail_deleted">সফলভাবে মুছে ফেলা হয়েছে</string>
|
||||
<string name="email_detail_copied">ক্লিপবোর্ডে কপি হয়েছে</string>
|
||||
<string name="email_detail_delete_dialog_title">মাস্কড ইমেইল মুছুন</string>
|
||||
<string name="email_detail_delete_dialog_message">আপনি কি নিশ্চিত যে এই মাস্কড ইমেইলটি মুছতে চান? এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না।</string>
|
||||
<string name="email_detail_delete_confirm">মুছুন</string>
|
||||
<string name="email_detail_delete_cancel">বাতিল</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">সক্রিয়</string>
|
||||
<string name="state_disabled">নিষ্ক্রিয়</string>
|
||||
<string name="state_deleted">মুছে ফেলা</string>
|
||||
<string name="state_pending">অপেক্ষমাণ</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">ইমেইল লোড করতে ব্যর্থ</string>
|
||||
<string name="error_retry">পুনরায় চেষ্টা করুন</string>
|
||||
<string name="error_generic">একটি ত্রুটি ঘটেছে</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">সেটিংস</string>
|
||||
<string name="settings_language">ভাষা</string>
|
||||
<string name="settings_language_description">অ্যাপের ভাষা নির্বাচন করুন</string>
|
||||
<string name="settings_system_default">সিস্টেম ডিফল্ট</string>
|
||||
<string name="settings_contact">যোগাযোগ এবং প্রতিক্রিয়া</string>
|
||||
<string name="settings_contact_description">আমাদের আপনার প্রতিক্রিয়া পাঠান</string>
|
||||
<string name="settings_logout">লগআউট</string>
|
||||
<string name="settings_logout_description">আপনার অ্যাকাউন্ট থেকে সাইন আউট করুন</string>
|
||||
<string name="settings_version">সংস্করণ %s</string>
|
||||
<string name="settings_select_language">ভাষা নির্বাচন করুন</string>
|
||||
<string name="settings_feedback_subject">FastMask প্রতিক্রিয়া</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-de/strings.xml
Normal file
121
app/src/main/res/values-de/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail Maskierte-E-Mail-Manager</string>
|
||||
<string name="login_api_token_label">API-Token</string>
|
||||
<string name="login_api_token_placeholder">Geben Sie Ihr Fastmail API-Token ein</string>
|
||||
<string name="login_button">Anmelden</string>
|
||||
<string name="login_show_token">Token anzeigen</string>
|
||||
<string name="login_hide_token">Token ausblenden</string>
|
||||
<string name="login_instructions_title">So erhalten Sie Ihr API-Token:</string>
|
||||
<string name="login_instructions_step1">1. Melden Sie sich bei der Fastmail Web-App an</string>
|
||||
<string name="login_instructions_step2">2. Gehen Sie zu Einstellungen > Datenschutz und Sicherheit</string>
|
||||
<string name="login_instructions_step3">3. Klicken Sie auf Integrationen > API-Token</string>
|
||||
<string name="login_instructions_step4">4. Erstellen Sie ein neues Token mit dem Bereich \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Kopieren Sie das Token und fügen Sie es oben ein</string>
|
||||
<string name="login_instructions_full">1. Melden Sie sich bei der Fastmail Web-App an\n2. Gehen Sie zu Einstellungen > Datenschutz und Sicherheit\n3. Klicken Sie auf Integrationen > API-Token\n4. Erstellen Sie ein neues Token mit dem Bereich \"Masked Email\"\n5. Kopieren Sie das Token und fügen Sie es oben ein</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Maskierte E-Mails</string>
|
||||
<string name="email_list_search_placeholder">E-Mails suchen…</string>
|
||||
<string name="email_list_clear_search">Suche löschen</string>
|
||||
<string name="email_list_filter_emails">E-Mails filtern</string>
|
||||
<string name="email_list_create_fab">Erstellen</string>
|
||||
<string name="email_list_create_description">Neue maskierte E-Mail erstellen</string>
|
||||
<string name="email_list_empty">Keine maskierten E-Mails gefunden</string>
|
||||
<string name="email_list_logout">Abmelden</string>
|
||||
<string name="email_list_settings">Einstellungen</string>
|
||||
<string name="filter_all">Alle</string>
|
||||
<string name="filter_enabled">Aktiviert</string>
|
||||
<string name="filter_disabled">Deaktiviert</string>
|
||||
<string name="filter_deleted">Gelöscht</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Maskierte E-Mail erstellen</string>
|
||||
<string name="create_email_prefix_label">E-Mail-Präfix (optional)</string>
|
||||
<string name="create_email_prefix_placeholder">z.B. meinseite_einkauf</string>
|
||||
<string name="create_email_prefix_hint">Max. 64 Zeichen: Kleinbuchstaben, Zahlen, Unterstriche</string>
|
||||
<string name="create_email_domain_label">Zugehörige Domain (optional)</string>
|
||||
<string name="create_email_domain_placeholder">z.B. beispiel.de</string>
|
||||
<string name="create_email_description_label">Beschreibung (optional)</string>
|
||||
<string name="create_email_description_placeholder">z.B. Einkaufskonto</string>
|
||||
<string name="create_email_url_label">URL (optional)</string>
|
||||
<string name="create_email_url_placeholder">z.B. https://beispiel.de</string>
|
||||
<string name="create_email_initial_state">Anfangszustand</string>
|
||||
<string name="create_email_button">Maskierte E-Mail erstellen</string>
|
||||
<string name="create_email_created">Erstellt: %s</string>
|
||||
<string name="create_email_copy_action">Kopieren</string>
|
||||
<string name="navigate_back">Zurück</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">E-Mail-Details</string>
|
||||
<string name="email_detail_copy_email">E-Mail-Adresse kopieren</string>
|
||||
<string name="email_detail_delete">E-Mail löschen</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Erstellt von: %s</string>
|
||||
<string name="email_detail_created">Erstellt: %s</string>
|
||||
<string name="email_detail_last_message">Letzte Nachricht: %s</string>
|
||||
<string name="email_detail_enable">Aktivieren</string>
|
||||
<string name="email_detail_disable">Deaktivieren</string>
|
||||
<string name="email_detail_edit_title">Details bearbeiten</string>
|
||||
<string name="email_detail_description_label">Beschreibung</string>
|
||||
<string name="email_detail_domain_label">Zugehörige Domain</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Änderungen speichern</string>
|
||||
<string name="email_detail_updated">Erfolgreich aktualisiert</string>
|
||||
<string name="email_detail_deleted">Erfolgreich gelöscht</string>
|
||||
<string name="email_detail_copied">In Zwischenablage kopiert</string>
|
||||
<string name="email_detail_delete_dialog_title">Maskierte E-Mail löschen</string>
|
||||
<string name="email_detail_delete_dialog_message">Sind Sie sicher, dass Sie diese maskierte E-Mail löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.</string>
|
||||
<string name="email_detail_delete_confirm">Löschen</string>
|
||||
<string name="email_detail_delete_cancel">Abbrechen</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Aktiviert</string>
|
||||
<string name="state_disabled">Deaktiviert</string>
|
||||
<string name="state_deleted">Gelöscht</string>
|
||||
<string name="state_pending">Ausstehend</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">E-Mails konnten nicht geladen werden</string>
|
||||
<string name="error_retry">Erneut versuchen</string>
|
||||
<string name="error_generic">Ein Fehler ist aufgetreten</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Einstellungen</string>
|
||||
<string name="settings_language">Sprache</string>
|
||||
<string name="settings_language_description">App-Sprache auswählen</string>
|
||||
<string name="settings_system_default">Systemstandard</string>
|
||||
<string name="settings_contact">Kontakt und Feedback</string>
|
||||
<string name="settings_contact_description">Senden Sie uns Ihr Feedback</string>
|
||||
<string name="settings_logout">Abmelden</string>
|
||||
<string name="settings_logout_description">Von Ihrem Konto abmelden</string>
|
||||
<string name="settings_version">Version %s</string>
|
||||
<string name="settings_select_language">Sprache auswählen</string>
|
||||
<string name="settings_feedback_subject">FastMask Feedback</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-es/strings.xml
Normal file
121
app/src/main/res/values-es/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Gestor de correos enmascarados de Fastmail</string>
|
||||
<string name="login_api_token_label">Token de API</string>
|
||||
<string name="login_api_token_placeholder">Introduce tu token de API de Fastmail</string>
|
||||
<string name="login_button">Iniciar sesión</string>
|
||||
<string name="login_show_token">Mostrar token</string>
|
||||
<string name="login_hide_token">Ocultar token</string>
|
||||
<string name="login_instructions_title">Cómo obtener tu token de API:</string>
|
||||
<string name="login_instructions_step1">1. Inicia sesión en la aplicación web de Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Ve a Configuración > Privacidad y Seguridad</string>
|
||||
<string name="login_instructions_step3">3. Haz clic en Integraciones > Tokens de API</string>
|
||||
<string name="login_instructions_step4">4. Crea un nuevo token con el alcance \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Copia el token y pégalo arriba</string>
|
||||
<string name="login_instructions_full">1. Inicia sesión en la aplicación web de Fastmail\n2. Ve a Configuración > Privacidad y Seguridad\n3. Haz clic en Integraciones > Tokens de API\n4. Crea un nuevo token con el alcance \"Masked Email\"\n5. Copia el token y pégalo arriba</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Correos enmascarados</string>
|
||||
<string name="email_list_search_placeholder">Buscar correos…</string>
|
||||
<string name="email_list_clear_search">Borrar búsqueda</string>
|
||||
<string name="email_list_filter_emails">Filtrar correos</string>
|
||||
<string name="email_list_create_fab">Crear</string>
|
||||
<string name="email_list_create_description">Crear nuevo correo enmascarado</string>
|
||||
<string name="email_list_empty">No se encontraron correos enmascarados</string>
|
||||
<string name="email_list_logout">Cerrar sesión</string>
|
||||
<string name="email_list_settings">Configuración</string>
|
||||
<string name="filter_all">Todos</string>
|
||||
<string name="filter_enabled">Habilitados</string>
|
||||
<string name="filter_disabled">Deshabilitados</string>
|
||||
<string name="filter_deleted">Eliminados</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Crear correo enmascarado</string>
|
||||
<string name="create_email_prefix_label">Prefijo de correo (opcional)</string>
|
||||
<string name="create_email_prefix_placeholder">ej., misitio_compras</string>
|
||||
<string name="create_email_prefix_hint">Máx 64 caracteres: letras minúsculas, números, guiones bajos</string>
|
||||
<string name="create_email_domain_label">Dominio asociado (opcional)</string>
|
||||
<string name="create_email_domain_placeholder">ej., ejemplo.com</string>
|
||||
<string name="create_email_description_label">Descripción (opcional)</string>
|
||||
<string name="create_email_description_placeholder">ej., Cuenta de compras</string>
|
||||
<string name="create_email_url_label">URL (opcional)</string>
|
||||
<string name="create_email_url_placeholder">ej., https://ejemplo.com</string>
|
||||
<string name="create_email_initial_state">Estado inicial</string>
|
||||
<string name="create_email_button">Crear correo enmascarado</string>
|
||||
<string name="create_email_created">Creado: %s</string>
|
||||
<string name="create_email_copy_action">Copiar</string>
|
||||
<string name="navigate_back">Volver</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Detalles del correo</string>
|
||||
<string name="email_detail_copy_email">Copiar dirección de correo</string>
|
||||
<string name="email_detail_delete">Eliminar correo</string>
|
||||
<string name="email_detail_status">Estado:</string>
|
||||
<string name="email_detail_created_by">Creado por: %s</string>
|
||||
<string name="email_detail_created">Creado: %s</string>
|
||||
<string name="email_detail_last_message">Último mensaje: %s</string>
|
||||
<string name="email_detail_enable">Habilitar</string>
|
||||
<string name="email_detail_disable">Deshabilitar</string>
|
||||
<string name="email_detail_edit_title">Editar detalles</string>
|
||||
<string name="email_detail_description_label">Descripción</string>
|
||||
<string name="email_detail_domain_label">Dominio asociado</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Guardar cambios</string>
|
||||
<string name="email_detail_updated">Actualizado correctamente</string>
|
||||
<string name="email_detail_deleted">Eliminado correctamente</string>
|
||||
<string name="email_detail_copied">Copiado al portapapeles</string>
|
||||
<string name="email_detail_delete_dialog_title">Eliminar correo enmascarado</string>
|
||||
<string name="email_detail_delete_dialog_message">¿Estás seguro de que quieres eliminar este correo enmascarado? Esta acción no se puede deshacer.</string>
|
||||
<string name="email_detail_delete_confirm">Eliminar</string>
|
||||
<string name="email_detail_delete_cancel">Cancelar</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Habilitado</string>
|
||||
<string name="state_disabled">Deshabilitado</string>
|
||||
<string name="state_deleted">Eliminado</string>
|
||||
<string name="state_pending">Pendiente</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Error al cargar los correos</string>
|
||||
<string name="error_retry">Reintentar</string>
|
||||
<string name="error_generic">Se produjo un error</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Configuración</string>
|
||||
<string name="settings_language">Idioma</string>
|
||||
<string name="settings_language_description">Seleccionar idioma de la app</string>
|
||||
<string name="settings_system_default">Predeterminado del sistema</string>
|
||||
<string name="settings_contact">Contacto y comentarios</string>
|
||||
<string name="settings_contact_description">Envíanos tus comentarios</string>
|
||||
<string name="settings_logout">Cerrar sesión</string>
|
||||
<string name="settings_logout_description">Salir de tu cuenta</string>
|
||||
<string name="settings_version">Versión %s</string>
|
||||
<string name="settings_select_language">Seleccionar idioma</string>
|
||||
<string name="settings_feedback_subject">Comentarios de FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-fr/strings.xml
Normal file
121
app/src/main/res/values-fr/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Gestionnaire d\'emails masqués Fastmail</string>
|
||||
<string name="login_api_token_label">Jeton API</string>
|
||||
<string name="login_api_token_placeholder">Entrez votre jeton API Fastmail</string>
|
||||
<string name="login_button">Connexion</string>
|
||||
<string name="login_show_token">Afficher le jeton</string>
|
||||
<string name="login_hide_token">Masquer le jeton</string>
|
||||
<string name="login_instructions_title">Comment obtenir votre jeton API :</string>
|
||||
<string name="login_instructions_step1">1. Connectez-vous à l\'application web Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Allez dans Paramètres > Confidentialité et sécurité</string>
|
||||
<string name="login_instructions_step3">3. Cliquez sur Intégrations > Jetons API</string>
|
||||
<string name="login_instructions_step4">4. Créez un nouveau jeton avec la portée \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Copiez le jeton et collez-le ci-dessus</string>
|
||||
<string name="login_instructions_full">1. Connectez-vous à l\'application web Fastmail\n2. Allez dans Paramètres > Confidentialité et sécurité\n3. Cliquez sur Intégrations > Jetons API\n4. Créez un nouveau jeton avec la portée \"Masked Email\"\n5. Copiez le jeton et collez-le ci-dessus</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Emails masqués</string>
|
||||
<string name="email_list_search_placeholder">Rechercher des emails…</string>
|
||||
<string name="email_list_clear_search">Effacer la recherche</string>
|
||||
<string name="email_list_filter_emails">Filtrer les emails</string>
|
||||
<string name="email_list_create_fab">Créer</string>
|
||||
<string name="email_list_create_description">Créer un nouvel email masqué</string>
|
||||
<string name="email_list_empty">Aucun email masqué trouvé</string>
|
||||
<string name="email_list_logout">Déconnexion</string>
|
||||
<string name="email_list_settings">Paramètres</string>
|
||||
<string name="filter_all">Tous</string>
|
||||
<string name="filter_enabled">Activés</string>
|
||||
<string name="filter_disabled">Désactivés</string>
|
||||
<string name="filter_deleted">Supprimés</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Créer un email masqué</string>
|
||||
<string name="create_email_prefix_label">Préfixe d\'email (optionnel)</string>
|
||||
<string name="create_email_prefix_placeholder">ex. : monsite_achats</string>
|
||||
<string name="create_email_prefix_hint">Max 64 caractères : lettres minuscules, chiffres, tirets bas</string>
|
||||
<string name="create_email_domain_label">Domaine associé (optionnel)</string>
|
||||
<string name="create_email_domain_placeholder">ex. : exemple.com</string>
|
||||
<string name="create_email_description_label">Description (optionnel)</string>
|
||||
<string name="create_email_description_placeholder">ex. : Compte d\'achats</string>
|
||||
<string name="create_email_url_label">URL (optionnel)</string>
|
||||
<string name="create_email_url_placeholder">ex. : https://exemple.com</string>
|
||||
<string name="create_email_initial_state">État initial</string>
|
||||
<string name="create_email_button">Créer l\'email masqué</string>
|
||||
<string name="create_email_created">Créé : %s</string>
|
||||
<string name="create_email_copy_action">Copier</string>
|
||||
<string name="navigate_back">Retour</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Détails de l\'email</string>
|
||||
<string name="email_detail_copy_email">Copier l\'adresse email</string>
|
||||
<string name="email_detail_delete">Supprimer l\'email</string>
|
||||
<string name="email_detail_status">Statut :</string>
|
||||
<string name="email_detail_created_by">Créé par : %s</string>
|
||||
<string name="email_detail_created">Créé : %s</string>
|
||||
<string name="email_detail_last_message">Dernier message : %s</string>
|
||||
<string name="email_detail_enable">Activer</string>
|
||||
<string name="email_detail_disable">Désactiver</string>
|
||||
<string name="email_detail_edit_title">Modifier les détails</string>
|
||||
<string name="email_detail_description_label">Description</string>
|
||||
<string name="email_detail_domain_label">Domaine associé</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Enregistrer les modifications</string>
|
||||
<string name="email_detail_updated">Mis à jour avec succès</string>
|
||||
<string name="email_detail_deleted">Supprimé avec succès</string>
|
||||
<string name="email_detail_copied">Copié dans le presse-papiers</string>
|
||||
<string name="email_detail_delete_dialog_title">Supprimer l\'email masqué</string>
|
||||
<string name="email_detail_delete_dialog_message">Êtes-vous sûr de vouloir supprimer cet email masqué ? Cette action est irréversible.</string>
|
||||
<string name="email_detail_delete_confirm">Supprimer</string>
|
||||
<string name="email_detail_delete_cancel">Annuler</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Activé</string>
|
||||
<string name="state_disabled">Désactivé</string>
|
||||
<string name="state_deleted">Supprimé</string>
|
||||
<string name="state_pending">En attente</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Échec du chargement des emails</string>
|
||||
<string name="error_retry">Réessayer</string>
|
||||
<string name="error_generic">Une erreur s\'est produite</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Paramètres</string>
|
||||
<string name="settings_language">Langue</string>
|
||||
<string name="settings_language_description">Sélectionner la langue de l\'app</string>
|
||||
<string name="settings_system_default">Par défaut du système</string>
|
||||
<string name="settings_contact">Contact et commentaires</string>
|
||||
<string name="settings_contact_description">Envoyez-nous vos commentaires</string>
|
||||
<string name="settings_logout">Déconnexion</string>
|
||||
<string name="settings_logout_description">Se déconnecter de votre compte</string>
|
||||
<string name="settings_version">Version %s</string>
|
||||
<string name="settings_select_language">Sélectionner la langue</string>
|
||||
<string name="settings_feedback_subject">Commentaires FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-hi/strings.xml
Normal file
121
app/src/main/res/values-hi/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail मास्क्ड ईमेल प्रबंधक</string>
|
||||
<string name="login_api_token_label">API टोकन</string>
|
||||
<string name="login_api_token_placeholder">अपना Fastmail API टोकन दर्ज करें</string>
|
||||
<string name="login_button">लॉग इन करें</string>
|
||||
<string name="login_show_token">टोकन दिखाएं</string>
|
||||
<string name="login_hide_token">टोकन छुपाएं</string>
|
||||
<string name="login_instructions_title">अपना API टोकन कैसे प्राप्त करें:</string>
|
||||
<string name="login_instructions_step1">1. Fastmail वेब ऐप में लॉग इन करें</string>
|
||||
<string name="login_instructions_step2">2. सेटिंग्स > गोपनीयता और सुरक्षा पर जाएं</string>
|
||||
<string name="login_instructions_step3">3. इंटीग्रेशन > API टोकन पर क्लिक करें</string>
|
||||
<string name="login_instructions_step4">4. \"Masked Email\" स्कोप के साथ एक नया टोकन बनाएं</string>
|
||||
<string name="login_instructions_step5">5. टोकन कॉपी करें और ऊपर पेस्ट करें</string>
|
||||
<string name="login_instructions_full">1. Fastmail वेब ऐप में लॉग इन करें\n2. सेटिंग्स > गोपनीयता और सुरक्षा पर जाएं\n3. इंटीग्रेशन > API टोकन पर क्लिक करें\n4. \"Masked Email\" स्कोप के साथ एक नया टोकन बनाएं\n5. टोकन कॉपी करें और ऊपर पेस्ट करें</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">मास्क्ड ईमेल</string>
|
||||
<string name="email_list_search_placeholder">ईमेल खोजें…</string>
|
||||
<string name="email_list_clear_search">खोज साफ़ करें</string>
|
||||
<string name="email_list_filter_emails">ईमेल फ़िल्टर करें</string>
|
||||
<string name="email_list_create_fab">बनाएं</string>
|
||||
<string name="email_list_create_description">नया मास्क्ड ईमेल बनाएं</string>
|
||||
<string name="email_list_empty">कोई मास्क्ड ईमेल नहीं मिला</string>
|
||||
<string name="email_list_logout">लॉग आउट</string>
|
||||
<string name="email_list_settings">सेटिंग्स</string>
|
||||
<string name="filter_all">सभी</string>
|
||||
<string name="filter_enabled">सक्षम</string>
|
||||
<string name="filter_disabled">अक्षम</string>
|
||||
<string name="filter_deleted">हटाए गए</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">मास्क्ड ईमेल बनाएं</string>
|
||||
<string name="create_email_prefix_label">ईमेल प्रीफ़िक्स (वैकल्पिक)</string>
|
||||
<string name="create_email_prefix_placeholder">जैसे, mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">अधिकतम 64 अक्षर: छोटे अक्षर, संख्याएं, अंडरस्कोर</string>
|
||||
<string name="create_email_domain_label">संबंधित डोमेन (वैकल्पिक)</string>
|
||||
<string name="create_email_domain_placeholder">जैसे, example.com</string>
|
||||
<string name="create_email_description_label">विवरण (वैकल्पिक)</string>
|
||||
<string name="create_email_description_placeholder">जैसे, शॉपिंग अकाउंट</string>
|
||||
<string name="create_email_url_label">URL (वैकल्पिक)</string>
|
||||
<string name="create_email_url_placeholder">जैसे, https://example.com</string>
|
||||
<string name="create_email_initial_state">प्रारंभिक स्थिति</string>
|
||||
<string name="create_email_button">मास्क्ड ईमेल बनाएं</string>
|
||||
<string name="create_email_created">बनाया गया: %s</string>
|
||||
<string name="create_email_copy_action">कॉपी करें</string>
|
||||
<string name="navigate_back">वापस जाएं</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">ईमेल विवरण</string>
|
||||
<string name="email_detail_copy_email">ईमेल पता कॉपी करें</string>
|
||||
<string name="email_detail_delete">ईमेल हटाएं</string>
|
||||
<string name="email_detail_status">स्थिति:</string>
|
||||
<string name="email_detail_created_by">बनाने वाला: %s</string>
|
||||
<string name="email_detail_created">बनाया गया: %s</string>
|
||||
<string name="email_detail_last_message">अंतिम संदेश: %s</string>
|
||||
<string name="email_detail_enable">सक्षम करें</string>
|
||||
<string name="email_detail_disable">अक्षम करें</string>
|
||||
<string name="email_detail_edit_title">विवरण संपादित करें</string>
|
||||
<string name="email_detail_description_label">विवरण</string>
|
||||
<string name="email_detail_domain_label">संबंधित डोमेन</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">परिवर्तन सहेजें</string>
|
||||
<string name="email_detail_updated">सफलतापूर्वक अपडेट किया गया</string>
|
||||
<string name="email_detail_deleted">सफलतापूर्वक हटाया गया</string>
|
||||
<string name="email_detail_copied">क्लिपबोर्ड पर कॉपी किया गया</string>
|
||||
<string name="email_detail_delete_dialog_title">मास्क्ड ईमेल हटाएं</string>
|
||||
<string name="email_detail_delete_dialog_message">क्या आप वाकई इस मास्क्ड ईमेल को हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती।</string>
|
||||
<string name="email_detail_delete_confirm">हटाएं</string>
|
||||
<string name="email_detail_delete_cancel">रद्द करें</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">सक्षम</string>
|
||||
<string name="state_disabled">अक्षम</string>
|
||||
<string name="state_deleted">हटाया गया</string>
|
||||
<string name="state_pending">लंबित</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">ईमेल लोड करने में विफल</string>
|
||||
<string name="error_retry">पुनः प्रयास करें</string>
|
||||
<string name="error_generic">एक त्रुटि हुई</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">सेटिंग्स</string>
|
||||
<string name="settings_language">भाषा</string>
|
||||
<string name="settings_language_description">ऐप की भाषा चुनें</string>
|
||||
<string name="settings_system_default">सिस्टम डिफ़ॉल्ट</string>
|
||||
<string name="settings_contact">संपर्क और फ़ीडबैक</string>
|
||||
<string name="settings_contact_description">हमें अपना फ़ीडबैक भेजें</string>
|
||||
<string name="settings_logout">लॉग आउट</string>
|
||||
<string name="settings_logout_description">अपने खाते से साइन आउट करें</string>
|
||||
<string name="settings_version">संस्करण %s</string>
|
||||
<string name="settings_select_language">भाषा चुनें</string>
|
||||
<string name="settings_feedback_subject">FastMask फ़ीडबैक</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-id/strings.xml
Normal file
121
app/src/main/res/values-id/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Pengelola Email Tersamar Fastmail</string>
|
||||
<string name="login_api_token_label">Token API</string>
|
||||
<string name="login_api_token_placeholder">Masukkan token API Fastmail Anda</string>
|
||||
<string name="login_button">Masuk</string>
|
||||
<string name="login_show_token">Tampilkan token</string>
|
||||
<string name="login_hide_token">Sembunyikan token</string>
|
||||
<string name="login_instructions_title">Cara mendapatkan token API:</string>
|
||||
<string name="login_instructions_step1">1. Masuk ke aplikasi web Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Buka Pengaturan > Privasi & Keamanan</string>
|
||||
<string name="login_instructions_step3">3. Klik Integrasi > Token API</string>
|
||||
<string name="login_instructions_step4">4. Buat token baru dengan cakupan \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Salin token dan tempel di atas</string>
|
||||
<string name="login_instructions_full">1. Masuk ke aplikasi web Fastmail\n2. Buka Pengaturan > Privasi & Keamanan\n3. Klik Integrasi > Token API\n4. Buat token baru dengan cakupan \"Masked Email\"\n5. Salin token dan tempel di atas</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Email Tersamar</string>
|
||||
<string name="email_list_search_placeholder">Cari email…</string>
|
||||
<string name="email_list_clear_search">Hapus pencarian</string>
|
||||
<string name="email_list_filter_emails">Filter email</string>
|
||||
<string name="email_list_create_fab">Buat</string>
|
||||
<string name="email_list_create_description">Buat email tersamar baru</string>
|
||||
<string name="email_list_empty">Tidak ada email tersamar ditemukan</string>
|
||||
<string name="email_list_logout">Keluar</string>
|
||||
<string name="email_list_settings">Pengaturan</string>
|
||||
<string name="filter_all">Semua</string>
|
||||
<string name="filter_enabled">Aktif</string>
|
||||
<string name="filter_disabled">Nonaktif</string>
|
||||
<string name="filter_deleted">Dihapus</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Buat Email Tersamar</string>
|
||||
<string name="create_email_prefix_label">Awalan email (opsional)</string>
|
||||
<string name="create_email_prefix_placeholder">mis., situsku_belanja</string>
|
||||
<string name="create_email_prefix_hint">Maks 64 karakter: huruf kecil, angka, garis bawah</string>
|
||||
<string name="create_email_domain_label">Domain terkait (opsional)</string>
|
||||
<string name="create_email_domain_placeholder">mis., contoh.com</string>
|
||||
<string name="create_email_description_label">Deskripsi (opsional)</string>
|
||||
<string name="create_email_description_placeholder">mis., Akun belanja</string>
|
||||
<string name="create_email_url_label">URL (opsional)</string>
|
||||
<string name="create_email_url_placeholder">mis., https://contoh.com</string>
|
||||
<string name="create_email_initial_state">Status awal</string>
|
||||
<string name="create_email_button">Buat Email Tersamar</string>
|
||||
<string name="create_email_created">Dibuat: %s</string>
|
||||
<string name="create_email_copy_action">Salin</string>
|
||||
<string name="navigate_back">Kembali</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Detail Email</string>
|
||||
<string name="email_detail_copy_email">Salin alamat email</string>
|
||||
<string name="email_detail_delete">Hapus email</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Dibuat oleh: %s</string>
|
||||
<string name="email_detail_created">Dibuat: %s</string>
|
||||
<string name="email_detail_last_message">Pesan terakhir: %s</string>
|
||||
<string name="email_detail_enable">Aktifkan</string>
|
||||
<string name="email_detail_disable">Nonaktifkan</string>
|
||||
<string name="email_detail_edit_title">Edit Detail</string>
|
||||
<string name="email_detail_description_label">Deskripsi</string>
|
||||
<string name="email_detail_domain_label">Domain terkait</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Simpan Perubahan</string>
|
||||
<string name="email_detail_updated">Berhasil diperbarui</string>
|
||||
<string name="email_detail_deleted">Berhasil dihapus</string>
|
||||
<string name="email_detail_copied">Disalin ke papan klip</string>
|
||||
<string name="email_detail_delete_dialog_title">Hapus Email Tersamar</string>
|
||||
<string name="email_detail_delete_dialog_message">Apakah Anda yakin ingin menghapus email tersamar ini? Tindakan ini tidak dapat dibatalkan.</string>
|
||||
<string name="email_detail_delete_confirm">Hapus</string>
|
||||
<string name="email_detail_delete_cancel">Batal</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Aktif</string>
|
||||
<string name="state_disabled">Nonaktif</string>
|
||||
<string name="state_deleted">Dihapus</string>
|
||||
<string name="state_pending">Tertunda</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Gagal memuat email</string>
|
||||
<string name="error_retry">Coba Lagi</string>
|
||||
<string name="error_generic">Terjadi kesalahan</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Pengaturan</string>
|
||||
<string name="settings_language">Bahasa</string>
|
||||
<string name="settings_language_description">Pilih bahasa aplikasi</string>
|
||||
<string name="settings_system_default">Default Sistem</string>
|
||||
<string name="settings_contact">Kontak & Masukan</string>
|
||||
<string name="settings_contact_description">Kirimkan masukan Anda</string>
|
||||
<string name="settings_logout">Keluar</string>
|
||||
<string name="settings_logout_description">Keluar dari akun Anda</string>
|
||||
<string name="settings_version">Versi %s</string>
|
||||
<string name="settings_select_language">Pilih Bahasa</string>
|
||||
<string name="settings_feedback_subject">Masukan FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-it/strings.xml
Normal file
121
app/src/main/res/values-it/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Gestore email mascherate di Fastmail</string>
|
||||
<string name="login_api_token_label">Token API</string>
|
||||
<string name="login_api_token_placeholder">Inserisci il tuo token API Fastmail</string>
|
||||
<string name="login_button">Accedi</string>
|
||||
<string name="login_show_token">Mostra token</string>
|
||||
<string name="login_hide_token">Nascondi token</string>
|
||||
<string name="login_instructions_title">Come ottenere il tuo token API:</string>
|
||||
<string name="login_instructions_step1">1. Accedi all\'app web di Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Vai su Impostazioni > Privacy e Sicurezza</string>
|
||||
<string name="login_instructions_step3">3. Clicca su Integrazioni > Token API</string>
|
||||
<string name="login_instructions_step4">4. Crea un nuovo token con ambito \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Copia il token e incollalo sopra</string>
|
||||
<string name="login_instructions_full">1. Accedi all\'app web di Fastmail\n2. Vai su Impostazioni > Privacy e Sicurezza\n3. Clicca su Integrazioni > Token API\n4. Crea un nuovo token con ambito \"Masked Email\"\n5. Copia il token e incollalo sopra</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Email mascherate</string>
|
||||
<string name="email_list_search_placeholder">Cerca email…</string>
|
||||
<string name="email_list_clear_search">Cancella ricerca</string>
|
||||
<string name="email_list_filter_emails">Filtra email</string>
|
||||
<string name="email_list_create_fab">Crea</string>
|
||||
<string name="email_list_create_description">Crea nuova email mascherata</string>
|
||||
<string name="email_list_empty">Nessuna email mascherata trovata</string>
|
||||
<string name="email_list_logout">Esci</string>
|
||||
<string name="email_list_settings">Impostazioni</string>
|
||||
<string name="filter_all">Tutte</string>
|
||||
<string name="filter_enabled">Attive</string>
|
||||
<string name="filter_disabled">Disattivate</string>
|
||||
<string name="filter_deleted">Eliminate</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Crea email mascherata</string>
|
||||
<string name="create_email_prefix_label">Prefisso email (opzionale)</string>
|
||||
<string name="create_email_prefix_placeholder">es. miosito_acquisti</string>
|
||||
<string name="create_email_prefix_hint">Max 64 caratteri: lettere minuscole, numeri, trattini bassi</string>
|
||||
<string name="create_email_domain_label">Dominio associato (opzionale)</string>
|
||||
<string name="create_email_domain_placeholder">es. esempio.it</string>
|
||||
<string name="create_email_description_label">Descrizione (opzionale)</string>
|
||||
<string name="create_email_description_placeholder">es. Account acquisti</string>
|
||||
<string name="create_email_url_label">URL (opzionale)</string>
|
||||
<string name="create_email_url_placeholder">es. https://esempio.it</string>
|
||||
<string name="create_email_initial_state">Stato iniziale</string>
|
||||
<string name="create_email_button">Crea email mascherata</string>
|
||||
<string name="create_email_created">Creata: %s</string>
|
||||
<string name="create_email_copy_action">Copia</string>
|
||||
<string name="navigate_back">Indietro</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Dettagli email</string>
|
||||
<string name="email_detail_copy_email">Copia indirizzo email</string>
|
||||
<string name="email_detail_delete">Elimina email</string>
|
||||
<string name="email_detail_status">Stato:</string>
|
||||
<string name="email_detail_created_by">Creata da: %s</string>
|
||||
<string name="email_detail_created">Creata: %s</string>
|
||||
<string name="email_detail_last_message">Ultimo messaggio: %s</string>
|
||||
<string name="email_detail_enable">Attiva</string>
|
||||
<string name="email_detail_disable">Disattiva</string>
|
||||
<string name="email_detail_edit_title">Modifica dettagli</string>
|
||||
<string name="email_detail_description_label">Descrizione</string>
|
||||
<string name="email_detail_domain_label">Dominio associato</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Salva modifiche</string>
|
||||
<string name="email_detail_updated">Aggiornato con successo</string>
|
||||
<string name="email_detail_deleted">Eliminato con successo</string>
|
||||
<string name="email_detail_copied">Copiato negli appunti</string>
|
||||
<string name="email_detail_delete_dialog_title">Elimina email mascherata</string>
|
||||
<string name="email_detail_delete_dialog_message">Sei sicuro di voler eliminare questa email mascherata? Questa azione non può essere annullata.</string>
|
||||
<string name="email_detail_delete_confirm">Elimina</string>
|
||||
<string name="email_detail_delete_cancel">Annulla</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Attiva</string>
|
||||
<string name="state_disabled">Disattivata</string>
|
||||
<string name="state_deleted">Eliminata</string>
|
||||
<string name="state_pending">In attesa</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Impossibile caricare le email</string>
|
||||
<string name="error_retry">Riprova</string>
|
||||
<string name="error_generic">Si è verificato un errore</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Impostazioni</string>
|
||||
<string name="settings_language">Lingua</string>
|
||||
<string name="settings_language_description">Seleziona la lingua dell\'app</string>
|
||||
<string name="settings_system_default">Predefinito di sistema</string>
|
||||
<string name="settings_contact">Contatto e feedback</string>
|
||||
<string name="settings_contact_description">Inviaci il tuo feedback</string>
|
||||
<string name="settings_logout">Esci</string>
|
||||
<string name="settings_logout_description">Disconnettiti dal tuo account</string>
|
||||
<string name="settings_version">Versione %s</string>
|
||||
<string name="settings_select_language">Seleziona lingua</string>
|
||||
<string name="settings_feedback_subject">Feedback FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-ja/strings.xml
Normal file
121
app/src/main/res/values-ja/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail マスクメール管理</string>
|
||||
<string name="login_api_token_label">APIトークン</string>
|
||||
<string name="login_api_token_placeholder">Fastmail APIトークンを入力</string>
|
||||
<string name="login_button">ログイン</string>
|
||||
<string name="login_show_token">トークンを表示</string>
|
||||
<string name="login_hide_token">トークンを非表示</string>
|
||||
<string name="login_instructions_title">APIトークンの取得方法:</string>
|
||||
<string name="login_instructions_step1">1. Fastmail Webアプリにログイン</string>
|
||||
<string name="login_instructions_step2">2. 設定 > プライバシーとセキュリティに移動</string>
|
||||
<string name="login_instructions_step3">3. 連携 > APIトークンをクリック</string>
|
||||
<string name="login_instructions_step4">4. 「Masked Email」スコープで新しいトークンを作成</string>
|
||||
<string name="login_instructions_step5">5. トークンをコピーして上に貼り付け</string>
|
||||
<string name="login_instructions_full">1. Fastmail Webアプリにログイン\n2. 設定 > プライバシーとセキュリティに移動\n3. 連携 > APIトークンをクリック\n4. 「Masked Email」スコープで新しいトークンを作成\n5. トークンをコピーして上に貼り付け</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">マスクメール</string>
|
||||
<string name="email_list_search_placeholder">メールを検索…</string>
|
||||
<string name="email_list_clear_search">検索をクリア</string>
|
||||
<string name="email_list_filter_emails">メールをフィルター</string>
|
||||
<string name="email_list_create_fab">作成</string>
|
||||
<string name="email_list_create_description">新しいマスクメールを作成</string>
|
||||
<string name="email_list_empty">マスクメールが見つかりません</string>
|
||||
<string name="email_list_logout">ログアウト</string>
|
||||
<string name="email_list_settings">設定</string>
|
||||
<string name="filter_all">すべて</string>
|
||||
<string name="filter_enabled">有効</string>
|
||||
<string name="filter_disabled">無効</string>
|
||||
<string name="filter_deleted">削除済み</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">マスクメールを作成</string>
|
||||
<string name="create_email_prefix_label">メールプレフィックス(任意)</string>
|
||||
<string name="create_email_prefix_placeholder">例:mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">最大64文字:小文字、数字、アンダースコア</string>
|
||||
<string name="create_email_domain_label">関連ドメイン(任意)</string>
|
||||
<string name="create_email_domain_placeholder">例:example.com</string>
|
||||
<string name="create_email_description_label">説明(任意)</string>
|
||||
<string name="create_email_description_placeholder">例:ショッピングアカウント</string>
|
||||
<string name="create_email_url_label">URL(任意)</string>
|
||||
<string name="create_email_url_placeholder">例:https://example.com</string>
|
||||
<string name="create_email_initial_state">初期状態</string>
|
||||
<string name="create_email_button">マスクメールを作成</string>
|
||||
<string name="create_email_created">作成完了:%s</string>
|
||||
<string name="create_email_copy_action">コピー</string>
|
||||
<string name="navigate_back">戻る</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">メール詳細</string>
|
||||
<string name="email_detail_copy_email">メールアドレスをコピー</string>
|
||||
<string name="email_detail_delete">メールを削除</string>
|
||||
<string name="email_detail_status">状態:</string>
|
||||
<string name="email_detail_created_by">作成者:%s</string>
|
||||
<string name="email_detail_created">作成日:%s</string>
|
||||
<string name="email_detail_last_message">最後のメッセージ:%s</string>
|
||||
<string name="email_detail_enable">有効にする</string>
|
||||
<string name="email_detail_disable">無効にする</string>
|
||||
<string name="email_detail_edit_title">詳細を編集</string>
|
||||
<string name="email_detail_description_label">説明</string>
|
||||
<string name="email_detail_domain_label">関連ドメイン</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">変更を保存</string>
|
||||
<string name="email_detail_updated">更新しました</string>
|
||||
<string name="email_detail_deleted">削除しました</string>
|
||||
<string name="email_detail_copied">クリップボードにコピーしました</string>
|
||||
<string name="email_detail_delete_dialog_title">マスクメールを削除</string>
|
||||
<string name="email_detail_delete_dialog_message">このマスクメールを削除してもよろしいですか?この操作は元に戻せません。</string>
|
||||
<string name="email_detail_delete_confirm">削除</string>
|
||||
<string name="email_detail_delete_cancel">キャンセル</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">有効</string>
|
||||
<string name="state_disabled">無効</string>
|
||||
<string name="state_deleted">削除済み</string>
|
||||
<string name="state_pending">保留中</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">メールの読み込みに失敗しました</string>
|
||||
<string name="error_retry">再試行</string>
|
||||
<string name="error_generic">エラーが発生しました</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">設定</string>
|
||||
<string name="settings_language">言語</string>
|
||||
<string name="settings_language_description">アプリの言語を選択</string>
|
||||
<string name="settings_system_default">システムの既定</string>
|
||||
<string name="settings_contact">お問い合わせとフィードバック</string>
|
||||
<string name="settings_contact_description">フィードバックを送信</string>
|
||||
<string name="settings_logout">ログアウト</string>
|
||||
<string name="settings_logout_description">アカウントからサインアウト</string>
|
||||
<string name="settings_version">バージョン %s</string>
|
||||
<string name="settings_select_language">言語を選択</string>
|
||||
<string name="settings_feedback_subject">FastMask フィードバック</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-ko/strings.xml
Normal file
121
app/src/main/res/values-ko/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail 마스크 이메일 관리자</string>
|
||||
<string name="login_api_token_label">API 토큰</string>
|
||||
<string name="login_api_token_placeholder">Fastmail API 토큰을 입력하세요</string>
|
||||
<string name="login_button">로그인</string>
|
||||
<string name="login_show_token">토큰 표시</string>
|
||||
<string name="login_hide_token">토큰 숨기기</string>
|
||||
<string name="login_instructions_title">API 토큰 얻는 방법:</string>
|
||||
<string name="login_instructions_step1">1. Fastmail 웹 앱에 로그인</string>
|
||||
<string name="login_instructions_step2">2. 설정 > 개인정보 및 보안으로 이동</string>
|
||||
<string name="login_instructions_step3">3. 통합 > API 토큰 클릭</string>
|
||||
<string name="login_instructions_step4">4. \"Masked Email\" 범위로 새 토큰 생성</string>
|
||||
<string name="login_instructions_step5">5. 토큰을 복사하여 위에 붙여넣기</string>
|
||||
<string name="login_instructions_full">1. Fastmail 웹 앱에 로그인\n2. 설정 > 개인정보 및 보안으로 이동\n3. 통합 > API 토큰 클릭\n4. \"Masked Email\" 범위로 새 토큰 생성\n5. 토큰을 복사하여 위에 붙여넣기</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">마스크 이메일</string>
|
||||
<string name="email_list_search_placeholder">이메일 검색…</string>
|
||||
<string name="email_list_clear_search">검색 지우기</string>
|
||||
<string name="email_list_filter_emails">이메일 필터</string>
|
||||
<string name="email_list_create_fab">생성</string>
|
||||
<string name="email_list_create_description">새 마스크 이메일 생성</string>
|
||||
<string name="email_list_empty">마스크 이메일을 찾을 수 없습니다</string>
|
||||
<string name="email_list_logout">로그아웃</string>
|
||||
<string name="email_list_settings">설정</string>
|
||||
<string name="filter_all">전체</string>
|
||||
<string name="filter_enabled">활성화됨</string>
|
||||
<string name="filter_disabled">비활성화됨</string>
|
||||
<string name="filter_deleted">삭제됨</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">마스크 이메일 생성</string>
|
||||
<string name="create_email_prefix_label">이메일 접두사 (선택)</string>
|
||||
<string name="create_email_prefix_placeholder">예: mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">최대 64자: 소문자, 숫자, 밑줄</string>
|
||||
<string name="create_email_domain_label">연결된 도메인 (선택)</string>
|
||||
<string name="create_email_domain_placeholder">예: example.com</string>
|
||||
<string name="create_email_description_label">설명 (선택)</string>
|
||||
<string name="create_email_description_placeholder">예: 쇼핑 계정</string>
|
||||
<string name="create_email_url_label">URL (선택)</string>
|
||||
<string name="create_email_url_placeholder">예: https://example.com</string>
|
||||
<string name="create_email_initial_state">초기 상태</string>
|
||||
<string name="create_email_button">마스크 이메일 생성</string>
|
||||
<string name="create_email_created">생성됨: %s</string>
|
||||
<string name="create_email_copy_action">복사</string>
|
||||
<string name="navigate_back">뒤로</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">이메일 상세</string>
|
||||
<string name="email_detail_copy_email">이메일 주소 복사</string>
|
||||
<string name="email_detail_delete">이메일 삭제</string>
|
||||
<string name="email_detail_status">상태:</string>
|
||||
<string name="email_detail_created_by">생성자: %s</string>
|
||||
<string name="email_detail_created">생성일: %s</string>
|
||||
<string name="email_detail_last_message">마지막 메시지: %s</string>
|
||||
<string name="email_detail_enable">활성화</string>
|
||||
<string name="email_detail_disable">비활성화</string>
|
||||
<string name="email_detail_edit_title">상세 정보 편집</string>
|
||||
<string name="email_detail_description_label">설명</string>
|
||||
<string name="email_detail_domain_label">연결된 도메인</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">변경 사항 저장</string>
|
||||
<string name="email_detail_updated">업데이트 완료</string>
|
||||
<string name="email_detail_deleted">삭제 완료</string>
|
||||
<string name="email_detail_copied">클립보드에 복사됨</string>
|
||||
<string name="email_detail_delete_dialog_title">마스크 이메일 삭제</string>
|
||||
<string name="email_detail_delete_dialog_message">이 마스크 이메일을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.</string>
|
||||
<string name="email_detail_delete_confirm">삭제</string>
|
||||
<string name="email_detail_delete_cancel">취소</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">활성화됨</string>
|
||||
<string name="state_disabled">비활성화됨</string>
|
||||
<string name="state_deleted">삭제됨</string>
|
||||
<string name="state_pending">대기 중</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">이메일 로드 실패</string>
|
||||
<string name="error_retry">다시 시도</string>
|
||||
<string name="error_generic">오류가 발생했습니다</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">설정</string>
|
||||
<string name="settings_language">언어</string>
|
||||
<string name="settings_language_description">앱 언어 선택</string>
|
||||
<string name="settings_system_default">시스템 기본값</string>
|
||||
<string name="settings_contact">연락처 및 피드백</string>
|
||||
<string name="settings_contact_description">피드백을 보내주세요</string>
|
||||
<string name="settings_logout">로그아웃</string>
|
||||
<string name="settings_logout_description">계정에서 로그아웃</string>
|
||||
<string name="settings_version">버전 %s</string>
|
||||
<string name="settings_select_language">언어 선택</string>
|
||||
<string name="settings_feedback_subject">FastMask 피드백</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-nl/strings.xml
Normal file
121
app/src/main/res/values-nl/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail Gemaskeerde E-mail Beheerder</string>
|
||||
<string name="login_api_token_label">API-token</string>
|
||||
<string name="login_api_token_placeholder">Voer uw Fastmail API-token in</string>
|
||||
<string name="login_button">Inloggen</string>
|
||||
<string name="login_show_token">Token tonen</string>
|
||||
<string name="login_hide_token">Token verbergen</string>
|
||||
<string name="login_instructions_title">Hoe u uw API-token krijgt:</string>
|
||||
<string name="login_instructions_step1">1. Log in op de Fastmail web-app</string>
|
||||
<string name="login_instructions_step2">2. Ga naar Instellingen > Privacy en Beveiliging</string>
|
||||
<string name="login_instructions_step3">3. Klik op Integraties > API-tokens</string>
|
||||
<string name="login_instructions_step4">4. Maak een nieuw token met \"Masked Email\" scope</string>
|
||||
<string name="login_instructions_step5">5. Kopieer het token en plak het hierboven</string>
|
||||
<string name="login_instructions_full">1. Log in op de Fastmail web-app\n2. Ga naar Instellingen > Privacy en Beveiliging\n3. Klik op Integraties > API-tokens\n4. Maak een nieuw token met \"Masked Email\" scope\n5. Kopieer het token en plak het hierboven</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Gemaskeerde e-mails</string>
|
||||
<string name="email_list_search_placeholder">E-mails zoeken…</string>
|
||||
<string name="email_list_clear_search">Zoekopdracht wissen</string>
|
||||
<string name="email_list_filter_emails">E-mails filteren</string>
|
||||
<string name="email_list_create_fab">Aanmaken</string>
|
||||
<string name="email_list_create_description">Nieuwe gemaskeerde e-mail aanmaken</string>
|
||||
<string name="email_list_empty">Geen gemaskeerde e-mails gevonden</string>
|
||||
<string name="email_list_logout">Uitloggen</string>
|
||||
<string name="email_list_settings">Instellingen</string>
|
||||
<string name="filter_all">Alle</string>
|
||||
<string name="filter_enabled">Ingeschakeld</string>
|
||||
<string name="filter_disabled">Uitgeschakeld</string>
|
||||
<string name="filter_deleted">Verwijderd</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Gemaskeerde e-mail aanmaken</string>
|
||||
<string name="create_email_prefix_label">E-mail prefix (optioneel)</string>
|
||||
<string name="create_email_prefix_placeholder">bijv. mijnsite_winkelen</string>
|
||||
<string name="create_email_prefix_hint">Max 64 tekens: kleine letters, cijfers, underscores</string>
|
||||
<string name="create_email_domain_label">Gekoppeld domein (optioneel)</string>
|
||||
<string name="create_email_domain_placeholder">bijv. voorbeeld.nl</string>
|
||||
<string name="create_email_description_label">Beschrijving (optioneel)</string>
|
||||
<string name="create_email_description_placeholder">bijv. Winkelaccount</string>
|
||||
<string name="create_email_url_label">URL (optioneel)</string>
|
||||
<string name="create_email_url_placeholder">bijv. https://voorbeeld.nl</string>
|
||||
<string name="create_email_initial_state">Beginstatus</string>
|
||||
<string name="create_email_button">Gemaskeerde e-mail aanmaken</string>
|
||||
<string name="create_email_created">Aangemaakt: %s</string>
|
||||
<string name="create_email_copy_action">Kopiëren</string>
|
||||
<string name="navigate_back">Terug</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">E-maildetails</string>
|
||||
<string name="email_detail_copy_email">E-mailadres kopiëren</string>
|
||||
<string name="email_detail_delete">E-mail verwijderen</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Aangemaakt door: %s</string>
|
||||
<string name="email_detail_created">Aangemaakt: %s</string>
|
||||
<string name="email_detail_last_message">Laatste bericht: %s</string>
|
||||
<string name="email_detail_enable">Inschakelen</string>
|
||||
<string name="email_detail_disable">Uitschakelen</string>
|
||||
<string name="email_detail_edit_title">Details bewerken</string>
|
||||
<string name="email_detail_description_label">Beschrijving</string>
|
||||
<string name="email_detail_domain_label">Gekoppeld domein</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Wijzigingen opslaan</string>
|
||||
<string name="email_detail_updated">Succesvol bijgewerkt</string>
|
||||
<string name="email_detail_deleted">Succesvol verwijderd</string>
|
||||
<string name="email_detail_copied">Gekopieerd naar klembord</string>
|
||||
<string name="email_detail_delete_dialog_title">Gemaskeerde e-mail verwijderen</string>
|
||||
<string name="email_detail_delete_dialog_message">Weet u zeker dat u deze gemaskeerde e-mail wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.</string>
|
||||
<string name="email_detail_delete_confirm">Verwijderen</string>
|
||||
<string name="email_detail_delete_cancel">Annuleren</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Ingeschakeld</string>
|
||||
<string name="state_disabled">Uitgeschakeld</string>
|
||||
<string name="state_deleted">Verwijderd</string>
|
||||
<string name="state_pending">In afwachting</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Kon e-mails niet laden</string>
|
||||
<string name="error_retry">Opnieuw proberen</string>
|
||||
<string name="error_generic">Er is een fout opgetreden</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Instellingen</string>
|
||||
<string name="settings_language">Taal</string>
|
||||
<string name="settings_language_description">App-taal selecteren</string>
|
||||
<string name="settings_system_default">Systeemstandaard</string>
|
||||
<string name="settings_contact">Contact en feedback</string>
|
||||
<string name="settings_contact_description">Stuur ons uw feedback</string>
|
||||
<string name="settings_logout">Uitloggen</string>
|
||||
<string name="settings_logout_description">Afmelden bij uw account</string>
|
||||
<string name="settings_version">Versie %s</string>
|
||||
<string name="settings_select_language">Taal selecteren</string>
|
||||
<string name="settings_feedback_subject">FastMask Feedback</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-pl/strings.xml
Normal file
121
app/src/main/res/values-pl/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Menedżer ukrytych adresów Fastmail</string>
|
||||
<string name="login_api_token_label">Token API</string>
|
||||
<string name="login_api_token_placeholder">Wprowadź token API Fastmail</string>
|
||||
<string name="login_button">Zaloguj się</string>
|
||||
<string name="login_show_token">Pokaż token</string>
|
||||
<string name="login_hide_token">Ukryj token</string>
|
||||
<string name="login_instructions_title">Jak uzyskać token API:</string>
|
||||
<string name="login_instructions_step1">1. Zaloguj się do aplikacji webowej Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Przejdź do Ustawienia > Prywatność i bezpieczeństwo</string>
|
||||
<string name="login_instructions_step3">3. Kliknij Integracje > Tokeny API</string>
|
||||
<string name="login_instructions_step4">4. Utwórz nowy token z zakresem \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Skopiuj token i wklej go powyżej</string>
|
||||
<string name="login_instructions_full">1. Zaloguj się do aplikacji webowej Fastmail\n2. Przejdź do Ustawienia > Prywatność i bezpieczeństwo\n3. Kliknij Integracje > Tokeny API\n4. Utwórz nowy token z zakresem \"Masked Email\"\n5. Skopiuj token i wklej go powyżej</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Ukryte adresy</string>
|
||||
<string name="email_list_search_placeholder">Szukaj adresów…</string>
|
||||
<string name="email_list_clear_search">Wyczyść wyszukiwanie</string>
|
||||
<string name="email_list_filter_emails">Filtruj adresy</string>
|
||||
<string name="email_list_create_fab">Utwórz</string>
|
||||
<string name="email_list_create_description">Utwórz nowy ukryty adres</string>
|
||||
<string name="email_list_empty">Nie znaleziono ukrytych adresów</string>
|
||||
<string name="email_list_logout">Wyloguj</string>
|
||||
<string name="email_list_settings">Ustawienia</string>
|
||||
<string name="filter_all">Wszystkie</string>
|
||||
<string name="filter_enabled">Aktywne</string>
|
||||
<string name="filter_disabled">Wyłączone</string>
|
||||
<string name="filter_deleted">Usunięte</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Utwórz ukryty adres</string>
|
||||
<string name="create_email_prefix_label">Prefiks adresu (opcjonalnie)</string>
|
||||
<string name="create_email_prefix_placeholder">np. mojastrona_zakupy</string>
|
||||
<string name="create_email_prefix_hint">Maks. 64 znaki: małe litery, cyfry, podkreślenia</string>
|
||||
<string name="create_email_domain_label">Powiązana domena (opcjonalnie)</string>
|
||||
<string name="create_email_domain_placeholder">np. przyklad.pl</string>
|
||||
<string name="create_email_description_label">Opis (opcjonalnie)</string>
|
||||
<string name="create_email_description_placeholder">np. Konto zakupowe</string>
|
||||
<string name="create_email_url_label">URL (opcjonalnie)</string>
|
||||
<string name="create_email_url_placeholder">np. https://przyklad.pl</string>
|
||||
<string name="create_email_initial_state">Stan początkowy</string>
|
||||
<string name="create_email_button">Utwórz ukryty adres</string>
|
||||
<string name="create_email_created">Utworzono: %s</string>
|
||||
<string name="create_email_copy_action">Kopiuj</string>
|
||||
<string name="navigate_back">Wstecz</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Szczegóły adresu</string>
|
||||
<string name="email_detail_copy_email">Kopiuj adres e-mail</string>
|
||||
<string name="email_detail_delete">Usuń adres</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Utworzony przez: %s</string>
|
||||
<string name="email_detail_created">Utworzono: %s</string>
|
||||
<string name="email_detail_last_message">Ostatnia wiadomość: %s</string>
|
||||
<string name="email_detail_enable">Włącz</string>
|
||||
<string name="email_detail_disable">Wyłącz</string>
|
||||
<string name="email_detail_edit_title">Edytuj szczegóły</string>
|
||||
<string name="email_detail_description_label">Opis</string>
|
||||
<string name="email_detail_domain_label">Powiązana domena</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Zapisz zmiany</string>
|
||||
<string name="email_detail_updated">Zaktualizowano pomyślnie</string>
|
||||
<string name="email_detail_deleted">Usunięto pomyślnie</string>
|
||||
<string name="email_detail_copied">Skopiowano do schowka</string>
|
||||
<string name="email_detail_delete_dialog_title">Usuń ukryty adres</string>
|
||||
<string name="email_detail_delete_dialog_message">Czy na pewno chcesz usunąć ten ukryty adres? Tej operacji nie można cofnąć.</string>
|
||||
<string name="email_detail_delete_confirm">Usuń</string>
|
||||
<string name="email_detail_delete_cancel">Anuluj</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Aktywny</string>
|
||||
<string name="state_disabled">Wyłączony</string>
|
||||
<string name="state_deleted">Usunięty</string>
|
||||
<string name="state_pending">Oczekujący</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Nie udało się załadować adresów</string>
|
||||
<string name="error_retry">Ponów próbę</string>
|
||||
<string name="error_generic">Wystąpił błąd</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Ustawienia</string>
|
||||
<string name="settings_language">Język</string>
|
||||
<string name="settings_language_description">Wybierz język aplikacji</string>
|
||||
<string name="settings_system_default">Domyślny systemowy</string>
|
||||
<string name="settings_contact">Kontakt i opinie</string>
|
||||
<string name="settings_contact_description">Wyślij nam swoją opinię</string>
|
||||
<string name="settings_logout">Wyloguj</string>
|
||||
<string name="settings_logout_description">Wyloguj się z konta</string>
|
||||
<string name="settings_version">Wersja %s</string>
|
||||
<string name="settings_select_language">Wybierz język</string>
|
||||
<string name="settings_feedback_subject">Opinia o FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-pt/strings.xml
Normal file
121
app/src/main/res/values-pt/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Gerenciador de emails mascarados do Fastmail</string>
|
||||
<string name="login_api_token_label">Token de API</string>
|
||||
<string name="login_api_token_placeholder">Digite seu token de API do Fastmail</string>
|
||||
<string name="login_button">Entrar</string>
|
||||
<string name="login_show_token">Mostrar token</string>
|
||||
<string name="login_hide_token">Ocultar token</string>
|
||||
<string name="login_instructions_title">Como obter seu token de API:</string>
|
||||
<string name="login_instructions_step1">1. Faça login no aplicativo web do Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Vá para Configurações > Privacidade e Segurança</string>
|
||||
<string name="login_instructions_step3">3. Clique em Integrações > Tokens de API</string>
|
||||
<string name="login_instructions_step4">4. Crie um novo token com o escopo \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Copie o token e cole acima</string>
|
||||
<string name="login_instructions_full">1. Faça login no aplicativo web do Fastmail\n2. Vá para Configurações > Privacidade e Segurança\n3. Clique em Integrações > Tokens de API\n4. Crie um novo token com o escopo \"Masked Email\"\n5. Copie o token e cole acima</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Emails mascarados</string>
|
||||
<string name="email_list_search_placeholder">Pesquisar emails…</string>
|
||||
<string name="email_list_clear_search">Limpar pesquisa</string>
|
||||
<string name="email_list_filter_emails">Filtrar emails</string>
|
||||
<string name="email_list_create_fab">Criar</string>
|
||||
<string name="email_list_create_description">Criar novo email mascarado</string>
|
||||
<string name="email_list_empty">Nenhum email mascarado encontrado</string>
|
||||
<string name="email_list_logout">Sair</string>
|
||||
<string name="email_list_settings">Configurações</string>
|
||||
<string name="filter_all">Todos</string>
|
||||
<string name="filter_enabled">Ativados</string>
|
||||
<string name="filter_disabled">Desativados</string>
|
||||
<string name="filter_deleted">Excluídos</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Criar email mascarado</string>
|
||||
<string name="create_email_prefix_label">Prefixo do email (opcional)</string>
|
||||
<string name="create_email_prefix_placeholder">ex.: meusite_compras</string>
|
||||
<string name="create_email_prefix_hint">Máx. 64 caracteres: letras minúsculas, números, sublinhados</string>
|
||||
<string name="create_email_domain_label">Domínio associado (opcional)</string>
|
||||
<string name="create_email_domain_placeholder">ex.: exemplo.com</string>
|
||||
<string name="create_email_description_label">Descrição (opcional)</string>
|
||||
<string name="create_email_description_placeholder">ex.: Conta de compras</string>
|
||||
<string name="create_email_url_label">URL (opcional)</string>
|
||||
<string name="create_email_url_placeholder">ex.: https://exemplo.com</string>
|
||||
<string name="create_email_initial_state">Estado inicial</string>
|
||||
<string name="create_email_button">Criar email mascarado</string>
|
||||
<string name="create_email_created">Criado: %s</string>
|
||||
<string name="create_email_copy_action">Copiar</string>
|
||||
<string name="navigate_back">Voltar</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Detalhes do email</string>
|
||||
<string name="email_detail_copy_email">Copiar endereço de email</string>
|
||||
<string name="email_detail_delete">Excluir email</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Criado por: %s</string>
|
||||
<string name="email_detail_created">Criado: %s</string>
|
||||
<string name="email_detail_last_message">Última mensagem: %s</string>
|
||||
<string name="email_detail_enable">Ativar</string>
|
||||
<string name="email_detail_disable">Desativar</string>
|
||||
<string name="email_detail_edit_title">Editar detalhes</string>
|
||||
<string name="email_detail_description_label">Descrição</string>
|
||||
<string name="email_detail_domain_label">Domínio associado</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Salvar alterações</string>
|
||||
<string name="email_detail_updated">Atualizado com sucesso</string>
|
||||
<string name="email_detail_deleted">Excluído com sucesso</string>
|
||||
<string name="email_detail_copied">Copiado para a área de transferência</string>
|
||||
<string name="email_detail_delete_dialog_title">Excluir email mascarado</string>
|
||||
<string name="email_detail_delete_dialog_message">Tem certeza de que deseja excluir este email mascarado? Esta ação não pode ser desfeita.</string>
|
||||
<string name="email_detail_delete_confirm">Excluir</string>
|
||||
<string name="email_detail_delete_cancel">Cancelar</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Ativado</string>
|
||||
<string name="state_disabled">Desativado</string>
|
||||
<string name="state_deleted">Excluído</string>
|
||||
<string name="state_pending">Pendente</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Falha ao carregar emails</string>
|
||||
<string name="error_retry">Tentar novamente</string>
|
||||
<string name="error_generic">Ocorreu um erro</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Configurações</string>
|
||||
<string name="settings_language">Idioma</string>
|
||||
<string name="settings_language_description">Selecionar idioma do app</string>
|
||||
<string name="settings_system_default">Padrão do sistema</string>
|
||||
<string name="settings_contact">Contato e feedback</string>
|
||||
<string name="settings_contact_description">Envie-nos seu feedback</string>
|
||||
<string name="settings_logout">Sair</string>
|
||||
<string name="settings_logout_description">Sair da sua conta</string>
|
||||
<string name="settings_version">Versão %s</string>
|
||||
<string name="settings_select_language">Selecionar idioma</string>
|
||||
<string name="settings_feedback_subject">Feedback do FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-ru/strings.xml
Normal file
121
app/src/main/res/values-ru/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Менеджер масок email для Fastmail</string>
|
||||
<string name="login_api_token_label">API токен</string>
|
||||
<string name="login_api_token_placeholder">Введите ваш API токен Fastmail</string>
|
||||
<string name="login_button">Войти</string>
|
||||
<string name="login_show_token">Показать токен</string>
|
||||
<string name="login_hide_token">Скрыть токен</string>
|
||||
<string name="login_instructions_title">Как получить API токен:</string>
|
||||
<string name="login_instructions_step1">1. Войдите в веб-приложение Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Перейдите в Настройки > Конфиденциальность и безопасность</string>
|
||||
<string name="login_instructions_step3">3. Нажмите Интеграции > API токены</string>
|
||||
<string name="login_instructions_step4">4. Создайте новый токен с правами \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Скопируйте токен и вставьте выше</string>
|
||||
<string name="login_instructions_full">1. Войдите в веб-приложение Fastmail\n2. Перейдите в Настройки > Конфиденциальность и безопасность\n3. Нажмите Интеграции > API токены\n4. Создайте новый токен с правами \"Masked Email\"\n5. Скопируйте токен и вставьте выше</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Маски email</string>
|
||||
<string name="email_list_search_placeholder">Поиск email…</string>
|
||||
<string name="email_list_clear_search">Очистить поиск</string>
|
||||
<string name="email_list_filter_emails">Фильтровать email</string>
|
||||
<string name="email_list_create_fab">Создать</string>
|
||||
<string name="email_list_create_description">Создать новую маску email</string>
|
||||
<string name="email_list_empty">Маски email не найдены</string>
|
||||
<string name="email_list_logout">Выйти</string>
|
||||
<string name="email_list_settings">Настройки</string>
|
||||
<string name="filter_all">Все</string>
|
||||
<string name="filter_enabled">Активные</string>
|
||||
<string name="filter_disabled">Отключённые</string>
|
||||
<string name="filter_deleted">Удалённые</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Создать маску email</string>
|
||||
<string name="create_email_prefix_label">Префикс email (необязательно)</string>
|
||||
<string name="create_email_prefix_placeholder">напр., mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">Макс. 64 символа: строчные буквы, цифры, подчёркивания</string>
|
||||
<string name="create_email_domain_label">Связанный домен (необязательно)</string>
|
||||
<string name="create_email_domain_placeholder">напр., example.com</string>
|
||||
<string name="create_email_description_label">Описание (необязательно)</string>
|
||||
<string name="create_email_description_placeholder">напр., Аккаунт для покупок</string>
|
||||
<string name="create_email_url_label">URL (необязательно)</string>
|
||||
<string name="create_email_url_placeholder">напр., https://example.com</string>
|
||||
<string name="create_email_initial_state">Начальное состояние</string>
|
||||
<string name="create_email_button">Создать маску email</string>
|
||||
<string name="create_email_created">Создано: %s</string>
|
||||
<string name="create_email_copy_action">Копировать</string>
|
||||
<string name="navigate_back">Назад</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Детали email</string>
|
||||
<string name="email_detail_copy_email">Копировать адрес email</string>
|
||||
<string name="email_detail_delete">Удалить email</string>
|
||||
<string name="email_detail_status">Статус:</string>
|
||||
<string name="email_detail_created_by">Создано: %s</string>
|
||||
<string name="email_detail_created">Создано: %s</string>
|
||||
<string name="email_detail_last_message">Последнее сообщение: %s</string>
|
||||
<string name="email_detail_enable">Включить</string>
|
||||
<string name="email_detail_disable">Отключить</string>
|
||||
<string name="email_detail_edit_title">Редактировать</string>
|
||||
<string name="email_detail_description_label">Описание</string>
|
||||
<string name="email_detail_domain_label">Связанный домен</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Сохранить изменения</string>
|
||||
<string name="email_detail_updated">Успешно обновлено</string>
|
||||
<string name="email_detail_deleted">Успешно удалено</string>
|
||||
<string name="email_detail_copied">Скопировано в буфер обмена</string>
|
||||
<string name="email_detail_delete_dialog_title">Удалить маску email</string>
|
||||
<string name="email_detail_delete_dialog_message">Вы уверены, что хотите удалить эту маску email? Это действие нельзя отменить.</string>
|
||||
<string name="email_detail_delete_confirm">Удалить</string>
|
||||
<string name="email_detail_delete_cancel">Отмена</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Активна</string>
|
||||
<string name="state_disabled">Отключена</string>
|
||||
<string name="state_deleted">Удалена</string>
|
||||
<string name="state_pending">Ожидание</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Не удалось загрузить email</string>
|
||||
<string name="error_retry">Повторить</string>
|
||||
<string name="error_generic">Произошла ошибка</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Настройки</string>
|
||||
<string name="settings_language">Язык</string>
|
||||
<string name="settings_language_description">Выбрать язык приложения</string>
|
||||
<string name="settings_system_default">Системный по умолчанию</string>
|
||||
<string name="settings_contact">Связаться и оставить отзыв</string>
|
||||
<string name="settings_contact_description">Отправьте нам отзыв</string>
|
||||
<string name="settings_logout">Выйти</string>
|
||||
<string name="settings_logout_description">Выйти из аккаунта</string>
|
||||
<string name="settings_version">Версия %s</string>
|
||||
<string name="settings_select_language">Выбрать язык</string>
|
||||
<string name="settings_feedback_subject">Отзыв о FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-th/strings.xml
Normal file
121
app/src/main/res/values-th/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">ตัวจัดการอีเมลซ่อน Fastmail</string>
|
||||
<string name="login_api_token_label">โทเค็น API</string>
|
||||
<string name="login_api_token_placeholder">ใส่โทเค็น API ของ Fastmail</string>
|
||||
<string name="login_button">เข้าสู่ระบบ</string>
|
||||
<string name="login_show_token">แสดงโทเค็น</string>
|
||||
<string name="login_hide_token">ซ่อนโทเค็น</string>
|
||||
<string name="login_instructions_title">วิธีรับโทเค็น API:</string>
|
||||
<string name="login_instructions_step1">1. เข้าสู่ระบบแอป Fastmail บนเว็บ</string>
|
||||
<string name="login_instructions_step2">2. ไปที่ ตั้งค่า > ความเป็นส่วนตัวและความปลอดภัย</string>
|
||||
<string name="login_instructions_step3">3. คลิก การเชื่อมต่อ > โทเค็น API</string>
|
||||
<string name="login_instructions_step4">4. สร้างโทเค็นใหม่ที่มีขอบเขต \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. คัดลอกโทเค็นและวางด้านบน</string>
|
||||
<string name="login_instructions_full">1. เข้าสู่ระบบแอป Fastmail บนเว็บ\n2. ไปที่ ตั้งค่า > ความเป็นส่วนตัวและความปลอดภัย\n3. คลิก การเชื่อมต่อ > โทเค็น API\n4. สร้างโทเค็นใหม่ที่มีขอบเขต \"Masked Email\"\n5. คัดลอกโทเค็นและวางด้านบน</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">อีเมลซ่อน</string>
|
||||
<string name="email_list_search_placeholder">ค้นหาอีเมล…</string>
|
||||
<string name="email_list_clear_search">ล้างการค้นหา</string>
|
||||
<string name="email_list_filter_emails">กรองอีเมล</string>
|
||||
<string name="email_list_create_fab">สร้าง</string>
|
||||
<string name="email_list_create_description">สร้างอีเมลซ่อนใหม่</string>
|
||||
<string name="email_list_empty">ไม่พบอีเมลซ่อน</string>
|
||||
<string name="email_list_logout">ออกจากระบบ</string>
|
||||
<string name="email_list_settings">การตั้งค่า</string>
|
||||
<string name="filter_all">ทั้งหมด</string>
|
||||
<string name="filter_enabled">เปิดใช้งาน</string>
|
||||
<string name="filter_disabled">ปิดใช้งาน</string>
|
||||
<string name="filter_deleted">ลบแล้ว</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">สร้างอีเมลซ่อน</string>
|
||||
<string name="create_email_prefix_label">คำนำหน้าอีเมล (ไม่บังคับ)</string>
|
||||
<string name="create_email_prefix_placeholder">เช่น mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">สูงสุด 64 ตัวอักษร: ตัวพิมพ์เล็ก, ตัวเลข, ขีดล่าง</string>
|
||||
<string name="create_email_domain_label">โดเมนที่เกี่ยวข้อง (ไม่บังคับ)</string>
|
||||
<string name="create_email_domain_placeholder">เช่น example.com</string>
|
||||
<string name="create_email_description_label">คำอธิบาย (ไม่บังคับ)</string>
|
||||
<string name="create_email_description_placeholder">เช่น บัญชีช้อปปิ้ง</string>
|
||||
<string name="create_email_url_label">URL (ไม่บังคับ)</string>
|
||||
<string name="create_email_url_placeholder">เช่น https://example.com</string>
|
||||
<string name="create_email_initial_state">สถานะเริ่มต้น</string>
|
||||
<string name="create_email_button">สร้างอีเมลซ่อน</string>
|
||||
<string name="create_email_created">สร้างแล้ว: %s</string>
|
||||
<string name="create_email_copy_action">คัดลอก</string>
|
||||
<string name="navigate_back">กลับ</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">รายละเอียดอีเมล</string>
|
||||
<string name="email_detail_copy_email">คัดลอกที่อยู่อีเมล</string>
|
||||
<string name="email_detail_delete">ลบอีเมล</string>
|
||||
<string name="email_detail_status">สถานะ:</string>
|
||||
<string name="email_detail_created_by">สร้างโดย: %s</string>
|
||||
<string name="email_detail_created">สร้างเมื่อ: %s</string>
|
||||
<string name="email_detail_last_message">ข้อความล่าสุด: %s</string>
|
||||
<string name="email_detail_enable">เปิดใช้งาน</string>
|
||||
<string name="email_detail_disable">ปิดใช้งาน</string>
|
||||
<string name="email_detail_edit_title">แก้ไขรายละเอียด</string>
|
||||
<string name="email_detail_description_label">คำอธิบาย</string>
|
||||
<string name="email_detail_domain_label">โดเมนที่เกี่ยวข้อง</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">บันทึกการเปลี่ยนแปลง</string>
|
||||
<string name="email_detail_updated">อัปเดตสำเร็จ</string>
|
||||
<string name="email_detail_deleted">ลบสำเร็จ</string>
|
||||
<string name="email_detail_copied">คัดลอกไปยังคลิปบอร์ดแล้ว</string>
|
||||
<string name="email_detail_delete_dialog_title">ลบอีเมลซ่อน</string>
|
||||
<string name="email_detail_delete_dialog_message">คุณแน่ใจหรือไม่ว่าต้องการลบอีเมลซ่อนนี้? การกระทำนี้ไม่สามารถย้อนกลับได้</string>
|
||||
<string name="email_detail_delete_confirm">ลบ</string>
|
||||
<string name="email_detail_delete_cancel">ยกเลิก</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">เปิดใช้งาน</string>
|
||||
<string name="state_disabled">ปิดใช้งาน</string>
|
||||
<string name="state_deleted">ลบแล้ว</string>
|
||||
<string name="state_pending">รอดำเนินการ</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">ไม่สามารถโหลดอีเมลได้</string>
|
||||
<string name="error_retry">ลองอีกครั้ง</string>
|
||||
<string name="error_generic">เกิดข้อผิดพลาด</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">การตั้งค่า</string>
|
||||
<string name="settings_language">ภาษา</string>
|
||||
<string name="settings_language_description">เลือกภาษาแอป</string>
|
||||
<string name="settings_system_default">ค่าเริ่มต้นของระบบ</string>
|
||||
<string name="settings_contact">ติดต่อและความคิดเห็น</string>
|
||||
<string name="settings_contact_description">ส่งความคิดเห็นให้เรา</string>
|
||||
<string name="settings_logout">ออกจากระบบ</string>
|
||||
<string name="settings_logout_description">ออกจากบัญชีของคุณ</string>
|
||||
<string name="settings_version">เวอร์ชัน %s</string>
|
||||
<string name="settings_select_language">เลือกภาษา</string>
|
||||
<string name="settings_feedback_subject">ความคิดเห็น FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-tr/strings.xml
Normal file
121
app/src/main/res/values-tr/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail Maskeli E-posta Yöneticisi</string>
|
||||
<string name="login_api_token_label">API Jetonu</string>
|
||||
<string name="login_api_token_placeholder">Fastmail API jetonunuzu girin</string>
|
||||
<string name="login_button">Giriş Yap</string>
|
||||
<string name="login_show_token">Jetonu göster</string>
|
||||
<string name="login_hide_token">Jetonu gizle</string>
|
||||
<string name="login_instructions_title">API jetonunuzu nasıl alırsınız:</string>
|
||||
<string name="login_instructions_step1">1. Fastmail web uygulamasına giriş yapın</string>
|
||||
<string name="login_instructions_step2">2. Ayarlar > Gizlilik ve Güvenlik\'e gidin</string>
|
||||
<string name="login_instructions_step3">3. Entegrasyonlar > API Jetonları\'na tıklayın</string>
|
||||
<string name="login_instructions_step4">4. \"Masked Email\" kapsamında yeni bir jeton oluşturun</string>
|
||||
<string name="login_instructions_step5">5. Jetonu kopyalayın ve yukarıya yapıştırın</string>
|
||||
<string name="login_instructions_full">1. Fastmail web uygulamasına giriş yapın\n2. Ayarlar > Gizlilik ve Güvenlik\'e gidin\n3. Entegrasyonlar > API Jetonları\'na tıklayın\n4. \"Masked Email\" kapsamında yeni bir jeton oluşturun\n5. Jetonu kopyalayın ve yukarıya yapıştırın</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Maskeli E-postalar</string>
|
||||
<string name="email_list_search_placeholder">E-posta ara…</string>
|
||||
<string name="email_list_clear_search">Aramayı temizle</string>
|
||||
<string name="email_list_filter_emails">E-postaları filtrele</string>
|
||||
<string name="email_list_create_fab">Oluştur</string>
|
||||
<string name="email_list_create_description">Yeni maskeli e-posta oluştur</string>
|
||||
<string name="email_list_empty">Maskeli e-posta bulunamadı</string>
|
||||
<string name="email_list_logout">Çıkış Yap</string>
|
||||
<string name="email_list_settings">Ayarlar</string>
|
||||
<string name="filter_all">Tümü</string>
|
||||
<string name="filter_enabled">Etkin</string>
|
||||
<string name="filter_disabled">Devre Dışı</string>
|
||||
<string name="filter_deleted">Silinmiş</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Maskeli E-posta Oluştur</string>
|
||||
<string name="create_email_prefix_label">E-posta öneki (isteğe bağlı)</string>
|
||||
<string name="create_email_prefix_placeholder">örn. sitem_alisveris</string>
|
||||
<string name="create_email_prefix_hint">Maks 64 karakter: küçük harfler, rakamlar, alt çizgiler</string>
|
||||
<string name="create_email_domain_label">İlişkili alan adı (isteğe bağlı)</string>
|
||||
<string name="create_email_domain_placeholder">örn. ornek.com</string>
|
||||
<string name="create_email_description_label">Açıklama (isteğe bağlı)</string>
|
||||
<string name="create_email_description_placeholder">örn. Alışveriş hesabı</string>
|
||||
<string name="create_email_url_label">URL (isteğe bağlı)</string>
|
||||
<string name="create_email_url_placeholder">örn. https://ornek.com</string>
|
||||
<string name="create_email_initial_state">Başlangıç durumu</string>
|
||||
<string name="create_email_button">Maskeli E-posta Oluştur</string>
|
||||
<string name="create_email_created">Oluşturuldu: %s</string>
|
||||
<string name="create_email_copy_action">Kopyala</string>
|
||||
<string name="navigate_back">Geri</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">E-posta Detayları</string>
|
||||
<string name="email_detail_copy_email">E-posta adresini kopyala</string>
|
||||
<string name="email_detail_delete">E-postayı sil</string>
|
||||
<string name="email_detail_status">Durum:</string>
|
||||
<string name="email_detail_created_by">Oluşturan: %s</string>
|
||||
<string name="email_detail_created">Oluşturulma: %s</string>
|
||||
<string name="email_detail_last_message">Son mesaj: %s</string>
|
||||
<string name="email_detail_enable">Etkinleştir</string>
|
||||
<string name="email_detail_disable">Devre dışı bırak</string>
|
||||
<string name="email_detail_edit_title">Detayları Düzenle</string>
|
||||
<string name="email_detail_description_label">Açıklama</string>
|
||||
<string name="email_detail_domain_label">İlişkili alan adı</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Değişiklikleri Kaydet</string>
|
||||
<string name="email_detail_updated">Başarıyla güncellendi</string>
|
||||
<string name="email_detail_deleted">Başarıyla silindi</string>
|
||||
<string name="email_detail_copied">Panoya kopyalandı</string>
|
||||
<string name="email_detail_delete_dialog_title">Maskeli E-postayı Sil</string>
|
||||
<string name="email_detail_delete_dialog_message">Bu maskeli e-postayı silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.</string>
|
||||
<string name="email_detail_delete_confirm">Sil</string>
|
||||
<string name="email_detail_delete_cancel">İptal</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Etkin</string>
|
||||
<string name="state_disabled">Devre Dışı</string>
|
||||
<string name="state_deleted">Silinmiş</string>
|
||||
<string name="state_pending">Beklemede</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">E-postalar yüklenemedi</string>
|
||||
<string name="error_retry">Tekrar Dene</string>
|
||||
<string name="error_generic">Bir hata oluştu</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Ayarlar</string>
|
||||
<string name="settings_language">Dil</string>
|
||||
<string name="settings_language_description">Uygulama dilini seçin</string>
|
||||
<string name="settings_system_default">Sistem Varsayılanı</string>
|
||||
<string name="settings_contact">İletişim ve Geri Bildirim</string>
|
||||
<string name="settings_contact_description">Geri bildiriminizi gönderin</string>
|
||||
<string name="settings_logout">Çıkış Yap</string>
|
||||
<string name="settings_logout_description">Hesabınızdan çıkış yapın</string>
|
||||
<string name="settings_version">Sürüm %s</string>
|
||||
<string name="settings_select_language">Dil Seçin</string>
|
||||
<string name="settings_feedback_subject">FastMask Geri Bildirimi</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-uk/strings.xml
Normal file
121
app/src/main/res/values-uk/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Менеджер масок email для Fastmail</string>
|
||||
<string name="login_api_token_label">API токен</string>
|
||||
<string name="login_api_token_placeholder">Введіть ваш API токен Fastmail</string>
|
||||
<string name="login_button">Увійти</string>
|
||||
<string name="login_show_token">Показати токен</string>
|
||||
<string name="login_hide_token">Приховати токен</string>
|
||||
<string name="login_instructions_title">Як отримати API токен:</string>
|
||||
<string name="login_instructions_step1">1. Увійдіть у веб-застосунок Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Перейдіть до Налаштування > Конфіденційність і безпека</string>
|
||||
<string name="login_instructions_step3">3. Натисніть Інтеграції > API токени</string>
|
||||
<string name="login_instructions_step4">4. Створіть новий токен з правами \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Скопіюйте токен і вставте вище</string>
|
||||
<string name="login_instructions_full">1. Увійдіть у веб-застосунок Fastmail\n2. Перейдіть до Налаштування > Конфіденційність і безпека\n3. Натисніть Інтеграції > API токени\n4. Створіть новий токен з правами \"Masked Email\"\n5. Скопіюйте токен і вставте вище</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Маски email</string>
|
||||
<string name="email_list_search_placeholder">Пошук email…</string>
|
||||
<string name="email_list_clear_search">Очистити пошук</string>
|
||||
<string name="email_list_filter_emails">Фільтрувати email</string>
|
||||
<string name="email_list_create_fab">Створити</string>
|
||||
<string name="email_list_create_description">Створити нову маску email</string>
|
||||
<string name="email_list_empty">Маски email не знайдено</string>
|
||||
<string name="email_list_logout">Вийти</string>
|
||||
<string name="email_list_settings">Налаштування</string>
|
||||
<string name="filter_all">Усі</string>
|
||||
<string name="filter_enabled">Активні</string>
|
||||
<string name="filter_disabled">Вимкнені</string>
|
||||
<string name="filter_deleted">Видалені</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Створити маску email</string>
|
||||
<string name="create_email_prefix_label">Префікс email (необов\'язково)</string>
|
||||
<string name="create_email_prefix_placeholder">напр., mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">Макс. 64 символи: малі літери, цифри, підкреслення</string>
|
||||
<string name="create_email_domain_label">Пов\'язаний домен (необов\'язково)</string>
|
||||
<string name="create_email_domain_placeholder">напр., example.com</string>
|
||||
<string name="create_email_description_label">Опис (необов\'язково)</string>
|
||||
<string name="create_email_description_placeholder">напр., Акаунт для покупок</string>
|
||||
<string name="create_email_url_label">URL (необов\'язково)</string>
|
||||
<string name="create_email_url_placeholder">напр., https://example.com</string>
|
||||
<string name="create_email_initial_state">Початковий стан</string>
|
||||
<string name="create_email_button">Створити маску email</string>
|
||||
<string name="create_email_created">Створено: %s</string>
|
||||
<string name="create_email_copy_action">Копіювати</string>
|
||||
<string name="navigate_back">Назад</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Деталі email</string>
|
||||
<string name="email_detail_copy_email">Копіювати адресу email</string>
|
||||
<string name="email_detail_delete">Видалити email</string>
|
||||
<string name="email_detail_status">Статус:</string>
|
||||
<string name="email_detail_created_by">Створено: %s</string>
|
||||
<string name="email_detail_created">Створено: %s</string>
|
||||
<string name="email_detail_last_message">Останнє повідомлення: %s</string>
|
||||
<string name="email_detail_enable">Увімкнути</string>
|
||||
<string name="email_detail_disable">Вимкнути</string>
|
||||
<string name="email_detail_edit_title">Редагувати</string>
|
||||
<string name="email_detail_description_label">Опис</string>
|
||||
<string name="email_detail_domain_label">Пов\'язаний домен</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Зберегти зміни</string>
|
||||
<string name="email_detail_updated">Успішно оновлено</string>
|
||||
<string name="email_detail_deleted">Успішно видалено</string>
|
||||
<string name="email_detail_copied">Скопійовано до буфера обміну</string>
|
||||
<string name="email_detail_delete_dialog_title">Видалити маску email</string>
|
||||
<string name="email_detail_delete_dialog_message">Ви впевнені, що хочете видалити цю маску email? Цю дію не можна скасувати.</string>
|
||||
<string name="email_detail_delete_confirm">Видалити</string>
|
||||
<string name="email_detail_delete_cancel">Скасувати</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Активна</string>
|
||||
<string name="state_disabled">Вимкнена</string>
|
||||
<string name="state_deleted">Видалена</string>
|
||||
<string name="state_pending">Очікування</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Не вдалося завантажити email</string>
|
||||
<string name="error_retry">Повторити</string>
|
||||
<string name="error_generic">Сталася помилка</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Налаштування</string>
|
||||
<string name="settings_language">Мова</string>
|
||||
<string name="settings_language_description">Вибрати мову застосунку</string>
|
||||
<string name="settings_system_default">Системна за замовчуванням</string>
|
||||
<string name="settings_contact">Зв\'язок та відгуки</string>
|
||||
<string name="settings_contact_description">Надішліть нам відгук</string>
|
||||
<string name="settings_logout">Вийти</string>
|
||||
<string name="settings_logout_description">Вийти з акаунту</string>
|
||||
<string name="settings_version">Версія %s</string>
|
||||
<string name="settings_select_language">Вибрати мову</string>
|
||||
<string name="settings_feedback_subject">Відгук про FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.FastMask" parent="android:Theme.Material.Light.NoActionBar">
|
||||
<style name="Theme.FastMask" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
|
|
|
|||
121
app/src/main/res/values-vi/strings.xml
Normal file
121
app/src/main/res/values-vi/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Quản lý Email ẩn danh Fastmail</string>
|
||||
<string name="login_api_token_label">Mã API</string>
|
||||
<string name="login_api_token_placeholder">Nhập mã API Fastmail của bạn</string>
|
||||
<string name="login_button">Đăng nhập</string>
|
||||
<string name="login_show_token">Hiện mã</string>
|
||||
<string name="login_hide_token">Ẩn mã</string>
|
||||
<string name="login_instructions_title">Cách lấy mã API:</string>
|
||||
<string name="login_instructions_step1">1. Đăng nhập vào ứng dụng web Fastmail</string>
|
||||
<string name="login_instructions_step2">2. Vào Cài đặt > Quyền riêng tư & Bảo mật</string>
|
||||
<string name="login_instructions_step3">3. Nhấp vào Tích hợp > Mã API</string>
|
||||
<string name="login_instructions_step4">4. Tạo mã mới với phạm vi \"Masked Email\"</string>
|
||||
<string name="login_instructions_step5">5. Sao chép mã và dán ở trên</string>
|
||||
<string name="login_instructions_full">1. Đăng nhập vào ứng dụng web Fastmail\n2. Vào Cài đặt > Quyền riêng tư & Bảo mật\n3. Nhấp vào Tích hợp > Mã API\n4. Tạo mã mới với phạm vi \"Masked Email\"\n5. Sao chép mã và dán ở trên</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Email ẩn danh</string>
|
||||
<string name="email_list_search_placeholder">Tìm kiếm email…</string>
|
||||
<string name="email_list_clear_search">Xóa tìm kiếm</string>
|
||||
<string name="email_list_filter_emails">Lọc email</string>
|
||||
<string name="email_list_create_fab">Tạo mới</string>
|
||||
<string name="email_list_create_description">Tạo email ẩn danh mới</string>
|
||||
<string name="email_list_empty">Không tìm thấy email ẩn danh</string>
|
||||
<string name="email_list_logout">Đăng xuất</string>
|
||||
<string name="email_list_settings">Cài đặt</string>
|
||||
<string name="filter_all">Tất cả</string>
|
||||
<string name="filter_enabled">Đang hoạt động</string>
|
||||
<string name="filter_disabled">Đã tắt</string>
|
||||
<string name="filter_deleted">Đã xóa</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Tạo email ẩn danh</string>
|
||||
<string name="create_email_prefix_label">Tiền tố email (tùy chọn)</string>
|
||||
<string name="create_email_prefix_placeholder">vd: trangweb_muasam</string>
|
||||
<string name="create_email_prefix_hint">Tối đa 64 ký tự: chữ thường, số, gạch dưới</string>
|
||||
<string name="create_email_domain_label">Tên miền liên kết (tùy chọn)</string>
|
||||
<string name="create_email_domain_placeholder">vd: example.com</string>
|
||||
<string name="create_email_description_label">Mô tả (tùy chọn)</string>
|
||||
<string name="create_email_description_placeholder">vd: Tài khoản mua sắm</string>
|
||||
<string name="create_email_url_label">URL (tùy chọn)</string>
|
||||
<string name="create_email_url_placeholder">vd: https://example.com</string>
|
||||
<string name="create_email_initial_state">Trạng thái ban đầu</string>
|
||||
<string name="create_email_button">Tạo email ẩn danh</string>
|
||||
<string name="create_email_created">Đã tạo: %s</string>
|
||||
<string name="create_email_copy_action">Sao chép</string>
|
||||
<string name="navigate_back">Quay lại</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Chi tiết email</string>
|
||||
<string name="email_detail_copy_email">Sao chép địa chỉ email</string>
|
||||
<string name="email_detail_delete">Xóa email</string>
|
||||
<string name="email_detail_status">Trạng thái:</string>
|
||||
<string name="email_detail_created_by">Tạo bởi: %s</string>
|
||||
<string name="email_detail_created">Ngày tạo: %s</string>
|
||||
<string name="email_detail_last_message">Tin nhắn cuối: %s</string>
|
||||
<string name="email_detail_enable">Bật</string>
|
||||
<string name="email_detail_disable">Tắt</string>
|
||||
<string name="email_detail_edit_title">Chỉnh sửa chi tiết</string>
|
||||
<string name="email_detail_description_label">Mô tả</string>
|
||||
<string name="email_detail_domain_label">Tên miền liên kết</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Lưu thay đổi</string>
|
||||
<string name="email_detail_updated">Cập nhật thành công</string>
|
||||
<string name="email_detail_deleted">Xóa thành công</string>
|
||||
<string name="email_detail_copied">Đã sao chép vào clipboard</string>
|
||||
<string name="email_detail_delete_dialog_title">Xóa email ẩn danh</string>
|
||||
<string name="email_detail_delete_dialog_message">Bạn có chắc muốn xóa email ẩn danh này? Hành động này không thể hoàn tác.</string>
|
||||
<string name="email_detail_delete_confirm">Xóa</string>
|
||||
<string name="email_detail_delete_cancel">Hủy</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Đang hoạt động</string>
|
||||
<string name="state_disabled">Đã tắt</string>
|
||||
<string name="state_deleted">Đã xóa</string>
|
||||
<string name="state_pending">Đang chờ</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Không thể tải email</string>
|
||||
<string name="error_retry">Thử lại</string>
|
||||
<string name="error_generic">Đã xảy ra lỗi</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Cài đặt</string>
|
||||
<string name="settings_language">Ngôn ngữ</string>
|
||||
<string name="settings_language_description">Chọn ngôn ngữ ứng dụng</string>
|
||||
<string name="settings_system_default">Mặc định hệ thống</string>
|
||||
<string name="settings_contact">Liên hệ & Phản hồi</string>
|
||||
<string name="settings_contact_description">Gửi phản hồi cho chúng tôi</string>
|
||||
<string name="settings_logout">Đăng xuất</string>
|
||||
<string name="settings_logout_description">Đăng xuất khỏi tài khoản</string>
|
||||
<string name="settings_version">Phiên bản %s</string>
|
||||
<string name="settings_select_language">Chọn ngôn ngữ</string>
|
||||
<string name="settings_feedback_subject">Phản hồi FastMask</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
121
app/src/main/res/values-zh-rCN/strings.xml
Normal file
121
app/src/main/res/values-zh-rCN/strings.xml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail 隐藏邮箱管理器</string>
|
||||
<string name="login_api_token_label">API 令牌</string>
|
||||
<string name="login_api_token_placeholder">输入您的 Fastmail API 令牌</string>
|
||||
<string name="login_button">登录</string>
|
||||
<string name="login_show_token">显示令牌</string>
|
||||
<string name="login_hide_token">隐藏令牌</string>
|
||||
<string name="login_instructions_title">如何获取您的 API 令牌:</string>
|
||||
<string name="login_instructions_step1">1. 登录 Fastmail 网页版</string>
|
||||
<string name="login_instructions_step2">2. 前往 设置 > 隐私与安全</string>
|
||||
<string name="login_instructions_step3">3. 点击 集成 > API 令牌</string>
|
||||
<string name="login_instructions_step4">4. 创建一个具有"隐藏邮箱"权限的新令牌</string>
|
||||
<string name="login_instructions_step5">5. 复制令牌并粘贴到上方</string>
|
||||
<string name="login_instructions_full">1. 登录 Fastmail 网页版\n2. 前往 设置 > 隐私与安全\n3. 点击 集成 > API 令牌\n4. 创建一个具有"隐藏邮箱"权限的新令牌\n5. 复制令牌并粘贴到上方</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">隐藏邮箱</string>
|
||||
<string name="email_list_search_placeholder">搜索邮箱…</string>
|
||||
<string name="email_list_clear_search">清除搜索</string>
|
||||
<string name="email_list_filter_emails">筛选邮箱</string>
|
||||
<string name="email_list_create_fab">创建</string>
|
||||
<string name="email_list_create_description">创建新的隐藏邮箱</string>
|
||||
<string name="email_list_empty">未找到隐藏邮箱</string>
|
||||
<string name="email_list_logout">退出登录</string>
|
||||
<string name="email_list_settings">设置</string>
|
||||
<string name="filter_all">全部</string>
|
||||
<string name="filter_enabled">已启用</string>
|
||||
<string name="filter_disabled">已禁用</string>
|
||||
<string name="filter_deleted">已删除</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">创建隐藏邮箱</string>
|
||||
<string name="create_email_prefix_label">邮箱前缀(可选)</string>
|
||||
<string name="create_email_prefix_placeholder">例如:mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">最多64个字符:小写字母、数字、下划线</string>
|
||||
<string name="create_email_domain_label">关联域名(可选)</string>
|
||||
<string name="create_email_domain_placeholder">例如:example.com</string>
|
||||
<string name="create_email_description_label">描述(可选)</string>
|
||||
<string name="create_email_description_placeholder">例如:购物账户</string>
|
||||
<string name="create_email_url_label">网址(可选)</string>
|
||||
<string name="create_email_url_placeholder">例如:https://example.com</string>
|
||||
<string name="create_email_initial_state">初始状态</string>
|
||||
<string name="create_email_button">创建隐藏邮箱</string>
|
||||
<string name="create_email_created">已创建:%s</string>
|
||||
<string name="create_email_copy_action">复制</string>
|
||||
<string name="navigate_back">返回</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">邮箱详情</string>
|
||||
<string name="email_detail_copy_email">复制邮箱地址</string>
|
||||
<string name="email_detail_delete">删除邮箱</string>
|
||||
<string name="email_detail_status">状态:</string>
|
||||
<string name="email_detail_created_by">创建者:%s</string>
|
||||
<string name="email_detail_created">创建时间:%s</string>
|
||||
<string name="email_detail_last_message">最后消息:%s</string>
|
||||
<string name="email_detail_enable">启用</string>
|
||||
<string name="email_detail_disable">禁用</string>
|
||||
<string name="email_detail_edit_title">编辑详情</string>
|
||||
<string name="email_detail_description_label">描述</string>
|
||||
<string name="email_detail_domain_label">关联域名</string>
|
||||
<string name="email_detail_url_label">网址</string>
|
||||
<string name="email_detail_save">保存更改</string>
|
||||
<string name="email_detail_updated">更新成功</string>
|
||||
<string name="email_detail_deleted">删除成功</string>
|
||||
<string name="email_detail_copied">已复制到剪贴板</string>
|
||||
<string name="email_detail_delete_dialog_title">删除隐藏邮箱</string>
|
||||
<string name="email_detail_delete_dialog_message">您确定要删除此隐藏邮箱吗?此操作无法撤销。</string>
|
||||
<string name="email_detail_delete_confirm">删除</string>
|
||||
<string name="email_detail_delete_cancel">取消</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">已启用</string>
|
||||
<string name="state_disabled">已禁用</string>
|
||||
<string name="state_deleted">已删除</string>
|
||||
<string name="state_pending">待处理</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">加载邮箱失败</string>
|
||||
<string name="error_retry">重试</string>
|
||||
<string name="error_generic">发生错误</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">设置</string>
|
||||
<string name="settings_language">语言</string>
|
||||
<string name="settings_language_description">选择应用语言</string>
|
||||
<string name="settings_system_default">跟随系统</string>
|
||||
<string name="settings_contact">联系与反馈</string>
|
||||
<string name="settings_contact_description">向我们发送反馈</string>
|
||||
<string name="settings_logout">退出登录</string>
|
||||
<string name="settings_logout_description">退出您的账户</string>
|
||||
<string name="settings_version">版本 %s</string>
|
||||
<string name="settings_select_language">选择语言</string>
|
||||
<string name="settings_feedback_subject">FastMask 反馈</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
|
|
@ -1,4 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">FastMask</string>
|
||||
|
||||
<!-- Login Screen -->
|
||||
<string name="login_subtitle">Fastmail Masked Email Manager</string>
|
||||
<string name="login_api_token_label">API Token</string>
|
||||
<string name="login_api_token_placeholder">Enter your Fastmail API token</string>
|
||||
<string name="login_button">Login</string>
|
||||
<string name="login_show_token">Show token</string>
|
||||
<string name="login_hide_token">Hide token</string>
|
||||
<string name="login_instructions_title">How to get your API token:</string>
|
||||
<string name="login_instructions_step1">1. Log in to Fastmail web app</string>
|
||||
<string name="login_instructions_step2">2. Go to Settings > Privacy & Security</string>
|
||||
<string name="login_instructions_step3">3. Click on Integrations > API tokens</string>
|
||||
<string name="login_instructions_step4">4. Create a new token with \"Masked Email\" scope</string>
|
||||
<string name="login_instructions_step5">5. Copy the token and paste it above</string>
|
||||
<string name="login_instructions_full">1. Log in to Fastmail web app\n2. Go to Settings > Privacy & Security\n3. Click on Integrations > API tokens\n4. Create a new token with \"Masked Email\" scope\n5. Copy the token and paste it above</string>
|
||||
|
||||
<!-- Email List Screen -->
|
||||
<string name="email_list_title">Masked Emails</string>
|
||||
<string name="email_list_search_placeholder">Search emails…</string>
|
||||
<string name="email_list_clear_search">Clear search</string>
|
||||
<string name="email_list_filter_emails">Filter emails</string>
|
||||
<string name="email_list_create_fab">Create</string>
|
||||
<string name="email_list_create_description">Create new masked email</string>
|
||||
<string name="email_list_empty">No masked emails found</string>
|
||||
<string name="email_list_logout">Logout</string>
|
||||
<string name="email_list_settings">Settings</string>
|
||||
<string name="filter_all">All</string>
|
||||
<string name="filter_enabled">Enabled</string>
|
||||
<string name="filter_disabled">Disabled</string>
|
||||
<string name="filter_deleted">Deleted</string>
|
||||
|
||||
<!-- Create Email Screen -->
|
||||
<string name="create_email_title">Create Masked Email</string>
|
||||
<string name="create_email_prefix_label">Email Prefix (optional)</string>
|
||||
<string name="create_email_prefix_placeholder">e.g., mysite_shopping</string>
|
||||
<string name="create_email_prefix_hint">Max 64 chars: lowercase letters, numbers, underscores</string>
|
||||
<string name="create_email_domain_label">Associated Domain (optional)</string>
|
||||
<string name="create_email_domain_placeholder">e.g., example.com</string>
|
||||
<string name="create_email_description_label">Description (optional)</string>
|
||||
<string name="create_email_description_placeholder">e.g., Shopping account</string>
|
||||
<string name="create_email_url_label">URL (optional)</string>
|
||||
<string name="create_email_url_placeholder">e.g., https://example.com</string>
|
||||
<string name="create_email_initial_state">Initial State</string>
|
||||
<string name="create_email_button">Create Masked Email</string>
|
||||
<string name="create_email_created">Created: %s</string>
|
||||
<string name="create_email_copy_action">Copy</string>
|
||||
<string name="navigate_back">Navigate back</string>
|
||||
|
||||
<!-- Email Detail Screen -->
|
||||
<string name="email_detail_title">Email Details</string>
|
||||
<string name="email_detail_copy_email">Copy email address</string>
|
||||
<string name="email_detail_delete">Delete email</string>
|
||||
<string name="email_detail_status">Status:</string>
|
||||
<string name="email_detail_created_by">Created by: %s</string>
|
||||
<string name="email_detail_created">Created: %s</string>
|
||||
<string name="email_detail_last_message">Last message: %s</string>
|
||||
<string name="email_detail_enable">Enable</string>
|
||||
<string name="email_detail_disable">Disable</string>
|
||||
<string name="email_detail_edit_title">Edit Details</string>
|
||||
<string name="email_detail_description_label">Description</string>
|
||||
<string name="email_detail_domain_label">Associated Domain</string>
|
||||
<string name="email_detail_url_label">URL</string>
|
||||
<string name="email_detail_save">Save Changes</string>
|
||||
<string name="email_detail_updated">Updated successfully</string>
|
||||
<string name="email_detail_deleted">Deleted successfully</string>
|
||||
<string name="email_detail_copied">Copied to clipboard</string>
|
||||
<string name="email_detail_delete_dialog_title">Delete Masked Email</string>
|
||||
<string name="email_detail_delete_dialog_message">Are you sure you want to delete this masked email? This action cannot be undone.</string>
|
||||
<string name="email_detail_delete_confirm">Delete</string>
|
||||
<string name="email_detail_delete_cancel">Cancel</string>
|
||||
|
||||
<!-- Email States -->
|
||||
<string name="state_enabled">Enabled</string>
|
||||
<string name="state_disabled">Disabled</string>
|
||||
<string name="state_deleted">Deleted</string>
|
||||
<string name="state_pending">Pending</string>
|
||||
|
||||
<!-- Error Messages -->
|
||||
<string name="error_load_emails">Failed to load emails</string>
|
||||
<string name="error_retry">Retry</string>
|
||||
<string name="error_generic">An error occurred</string>
|
||||
|
||||
<!-- Settings Screen -->
|
||||
<string name="settings_title">Settings</string>
|
||||
<string name="settings_language">Language</string>
|
||||
<string name="settings_language_description">Select app language</string>
|
||||
<string name="settings_system_default">System Default</string>
|
||||
<string name="settings_contact">Contact & Feedback</string>
|
||||
<string name="settings_contact_description">Send us your feedback</string>
|
||||
<string name="settings_logout">Logout</string>
|
||||
<string name="settings_logout_description">Sign out of your account</string>
|
||||
<string name="settings_version">Version %s</string>
|
||||
<string name="settings_select_language">Select Language</string>
|
||||
<string name="settings_feedback_subject">FastMask Feedback</string>
|
||||
|
||||
<!-- Language Names (Native) -->
|
||||
<string name="language_en">English</string>
|
||||
<string name="language_zh">中文</string>
|
||||
<string name="language_es">Español</string>
|
||||
<string name="language_hi">हिन्दी</string>
|
||||
<string name="language_ar">العربية</string>
|
||||
<string name="language_pt">Português</string>
|
||||
<string name="language_bn">বাংলা</string>
|
||||
<string name="language_ru">Русский</string>
|
||||
<string name="language_ja">日本語</string>
|
||||
<string name="language_fr">Français</string>
|
||||
<string name="language_de">Deutsch</string>
|
||||
<string name="language_ko">한국어</string>
|
||||
<string name="language_it">Italiano</string>
|
||||
<string name="language_tr">Türkçe</string>
|
||||
<string name="language_vi">Tiếng Việt</string>
|
||||
<string name="language_pl">Polski</string>
|
||||
<string name="language_uk">Українська</string>
|
||||
<string name="language_nl">Nederlands</string>
|
||||
<string name="language_th">ไทย</string>
|
||||
<string name="language_id">Bahasa Indonesia</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.FastMask" parent="android:Theme.Material.Light.NoActionBar">
|
||||
<style name="Theme.FastMask" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowLightStatusBar">true</item>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<locale android:name="en" />
|
||||
<locale android:name="zh-Hans" />
|
||||
<locale android:name="es" />
|
||||
<locale android:name="hi" />
|
||||
<locale android:name="ar" />
|
||||
<locale android:name="pt" />
|
||||
<locale android:name="bn" />
|
||||
<locale android:name="ru" />
|
||||
<locale android:name="ja" />
|
||||
<locale android:name="fr" />
|
||||
<locale android:name="de" />
|
||||
<locale android:name="ko" />
|
||||
<locale android:name="it" />
|
||||
<locale android:name="tr" />
|
||||
<locale android:name="vi" />
|
||||
<locale android:name="pl" />
|
||||
<locale android:name="uk" />
|
||||
<locale android:name="nl" />
|
||||
<locale android:name="th" />
|
||||
<locale android:name="id" />
|
||||
</locale-config>
|
||||
|
|
|
|||
Loading…
Reference in a new issue