mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de1eedc63f | |||
| ec4db3e58f | |||
| 0d2175b641 | |||
| 97620b8a3c | |||
| 24317b38bf | |||
| 6b28ed15e3 | |||
| b8b203e517 | |||
| e5c1e477f0 | |||
| 64752d3bae | |||
| 6145e0d2df | |||
| b365284743 | |||
| af62041c14 | |||
| 910dbf56fd | |||
| 4eca0dea4a | |||
| a76c17fd45 | |||
| b00aeec03a | |||
| ffe147fde8 | |||
| 02a5bb06a9 | |||
| a8997738bf | |||
| 202690d02e | |||
| 6d14bbdbc7 | |||
| 03a0b53eee | |||
| a044181a75 | |||
| e9ae9dc5bf | |||
| cbfa3b7e58 | |||
| bf57d3bd73 | |||
| 6200f354ca | |||
| c8dfb08dcb | |||
| 543e9d91e4 | |||
| dec5879919 | |||
| a1d21d8562 | |||
| 253ed877e5 | |||
| b809d24ab1 | |||
| 78aee0a487 | |||
| d16254c146 | |||
| 7ab3ef8453 | |||
| 4b695a3293 | |||
| da4c382c9a | |||
| 80973960f5 | |||
| 7be75f7008 | |||
| 6fa114c6c0 | |||
| 767b5f2bae | |||
| ed3a21b992 | |||
| 899c2b5647 | |||
| 61e616a53b | |||
| 3bf4504de9 | |||
| cd0740d895 | |||
| 9f99edc159 | |||
| 60568f23f5 | |||
| 6dc8bd7ba8 | |||
| ff4ecb3bda | |||
| c71e71359a | |||
| d5a09fa25e | |||
| f52c2be2c2 | |||
| 2233b93108 | |||
| d76eb3239a | |||
| a982bd2bbb | |||
| 9ef3edcc0e | |||
| de7c54b886 | |||
| 9c9f966597 | |||
| 12e77789d3 | |||
| bd640072ab | |||
| 0a9c46fbfc | |||
| 1cc4f11484 | |||
| 9386f2f9cb | |||
| 45d73d4604 | |||
| a5892330dd | |||
| 8a0e2d72a4 | |||
| 2629c65564 | |||
| 10694a6809 | |||
| aa3d177243 | |||
| 4d35d4edeb | |||
| bbaba3cd33 | |||
| d1f002a132 | |||
| 9ce9a91c95 | |||
| 7844e146b1 | |||
| 30124de2a8 | |||
| 1dcf7e4860 | |||
| 9ffc904ae5 | |||
| 2704749b44 | |||
| 1c174b5b70 | |||
| f022316ad7 | |||
| 3386f5c5f7 | |||
| 57eead3a34 | |||
| 82118db71b | |||
| cebfa12142 | |||
| 2889266522 | |||
| 5e6fccf143 | |||
| 71ed333468 | |||
| b66bc1f863 | |||
| aebd5c66f7 | |||
| f319ba2b83 | |||
| 93f12e7367 | |||
| 10acb07f82 | |||
| 13374df709 | |||
| 1ff4e069ea | |||
| 34be7aab17 | |||
| 59139ed242 | |||
| 11f3964bdc | |||
| 7683408d18 | |||
| b74e793654 | |||
| 4bd74324d2 | |||
| 9a121b3039 | |||
| a9832c9c53 |
@@ -8,7 +8,7 @@ ArcaneChat is a Delta Chat Android client built on top of the official Delta Cha
|
||||
- **Language:** Java (Java 8 compatibility)
|
||||
- **Build System:** Gradle with Android Gradle Plugin 8.11.1
|
||||
- **Min SDK:** 21 (Android 5.0)
|
||||
- **Target SDK:** 35 (Android 15)
|
||||
- **Target SDK:** 36 (Android 16)
|
||||
- **NDK Version:** 27.0.12077973
|
||||
- **Native Components:** Rust (deltachat-core-rust submodule)
|
||||
- **UI Framework:** Android SDK, Material Design Components
|
||||
@@ -17,13 +17,23 @@ ArcaneChat is a Delta Chat Android client built on top of the official Delta Cha
|
||||
## Repository Structure
|
||||
|
||||
- `src/main/` - Main application source code
|
||||
- `src/main/java/org/thoughtcrime/securesms/` - Main UI components
|
||||
- `src/main/java/com/b44t/messenger/` - Delta Chat core integration
|
||||
- `src/main/java/chat/delta/rpc/` - JSON-RPC bindings (generated, don't edit manually)
|
||||
- `src/main/res/` - Android resources (layouts, strings, drawables)
|
||||
- `src/androidTest/` - Instrumented tests (UI tests, benchmarks)
|
||||
- `src/androidTest/java/com/b44t/messenger/uitests/` - UI tests
|
||||
- `src/androidTest/java/com/b44t/messenger/uibenchmarks/` - Performance benchmarks
|
||||
- `src/gplay/` - Google Play flavor-specific code
|
||||
- `src/foss/` - F-Droid/FOSS flavor-specific code
|
||||
- `jni/deltachat-core-rust/` - Native Rust core library (submodule)
|
||||
- `jni/deltachat-core-rust/` - Native Rust core library (submodule, **don't edit directly**)
|
||||
- `scripts/` - Build and helper scripts
|
||||
- `scripts/ndk-make.sh` - Build native libraries
|
||||
- `scripts/install-toolchains.sh` - Install Rust cross-compilation toolchains
|
||||
- `scripts/generate-rpc-bindings.sh` - Generate JSON-RPC bindings
|
||||
- `docs/` - Documentation
|
||||
- `fastlane/` - App store metadata and screenshots
|
||||
- `.github/workflows/` - CI/CD workflows (GitHub Actions)
|
||||
|
||||
## Build Instructions
|
||||
|
||||
@@ -33,17 +43,36 @@ ArcaneChat is a Delta Chat Android client built on top of the official Delta Cha
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
This MUST be done first before any build attempts.
|
||||
|
||||
2. **Build native libraries:**
|
||||
2. **Set up environment variables:**
|
||||
```bash
|
||||
export ANDROID_NDK_ROOT=/path/to/ndk/27.0.12077973
|
||||
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
|
||||
```
|
||||
Note: Path format varies by OS (linux-x86_64, darwin-x86_64, etc.)
|
||||
|
||||
3. **Install Rust toolchains:**
|
||||
```bash
|
||||
scripts/install-toolchains.sh
|
||||
```
|
||||
Required for building the native Rust components.
|
||||
|
||||
4. **Build native libraries:**
|
||||
```bash
|
||||
scripts/ndk-make.sh
|
||||
```
|
||||
Note: First run may take significant time as it builds for all architectures (armeabi-v7a, arm64-v8a, x86, x86_64)
|
||||
**IMPORTANT:** First run takes 30-60 minutes as it builds for all architectures (armeabi-v7a, arm64-v8a, x86, x86_64).
|
||||
For faster development builds, build for a single architecture:
|
||||
```bash
|
||||
scripts/ndk-make.sh armeabi-v7a
|
||||
```
|
||||
|
||||
3. **Build APK:**
|
||||
5. **Build APK:**
|
||||
```bash
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
Build time: ~2-5 minutes after native libraries are built.
|
||||
|
||||
### Build Flavors
|
||||
|
||||
@@ -55,6 +84,24 @@ ArcaneChat is a Delta Chat Android client built on top of the official Delta Cha
|
||||
- Debug APKs: `build/outputs/apk/gplay/debug/` and `build/outputs/apk/fat/debug/`
|
||||
- Release APKs require signing configuration in `~/.gradle/gradle.properties`
|
||||
|
||||
### Common Build Issues
|
||||
|
||||
1. **Missing NDK or incorrect version:**
|
||||
- Error: `ANDROID_NDK_ROOT not set` or native library missing
|
||||
- Solution: Install NDK 27.0.12077973 and set ANDROID_NDK_ROOT environment variable
|
||||
|
||||
2. **Submodules not initialized:**
|
||||
- Error: Missing deltachat-core-rust files
|
||||
- Solution: Run `git submodule update --init --recursive`
|
||||
|
||||
3. **Gradle wrapper validation:**
|
||||
- Always validate gradle wrapper before building: `./gradlew wrapper --gradle-version=current`
|
||||
- Wrapper is validated in CI via `gradle/actions/wrapper-validation@v4`
|
||||
|
||||
4. **Clean build issues:**
|
||||
- If build fails, try: `./gradlew clean && scripts/ndk-make.sh && ./gradlew assembleDebug`
|
||||
- Remove `build/` directory if clean doesn't work
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Unit Tests
|
||||
@@ -62,16 +109,19 @@ ArcaneChat is a Delta Chat Android client built on top of the official Delta Cha
|
||||
```bash
|
||||
./gradlew test
|
||||
```
|
||||
Expected duration: 1-3 minutes
|
||||
|
||||
### Running Instrumented Tests
|
||||
|
||||
1. **Disable animations** on your device/emulator:
|
||||
- Developer Options → Set "Window animation scale", "Transition animation scale", and "Animator duration scale" to 0x
|
||||
- **CRITICAL:** Tests will fail if animations are enabled
|
||||
|
||||
2. **Run tests:**
|
||||
```bash
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
Expected duration: 10-30 minutes depending on device/emulator
|
||||
|
||||
### Online Tests
|
||||
|
||||
@@ -129,6 +179,14 @@ TEST_MAIL_PW=yourpassword
|
||||
- Java bindings are in `src/main/java/com/b44t/messenger/Dc*.java`
|
||||
- JSON-RPC bindings in `chat.delta.rpc.*` package (generated via dcrpcgen)
|
||||
|
||||
### Generating JSON-RPC Bindings
|
||||
|
||||
To regenerate JSON-RPC bindings after core changes:
|
||||
```bash
|
||||
./scripts/generate-rpc-bindings.sh
|
||||
```
|
||||
**Note:** Requires Rust tooling and [dcrpcgen tool](https://github.com/chatmail/dcrpcgen) installed
|
||||
|
||||
### Working with Translations
|
||||
|
||||
- Translations managed via Transifex (not in repository)
|
||||
@@ -142,6 +200,43 @@ Decode crash symbols:
|
||||
$ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decoded.txt
|
||||
```
|
||||
|
||||
## Validation and Quality Checks
|
||||
|
||||
### Pre-commit Checks
|
||||
|
||||
Before committing changes, always run:
|
||||
|
||||
1. **Gradle wrapper validation:**
|
||||
```bash
|
||||
./gradlew wrapper --gradle-version=current
|
||||
```
|
||||
|
||||
2. **Build verification:**
|
||||
```bash
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
3. **Unit tests:**
|
||||
```bash
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
4. **Code style:** Match existing code style in modified files (no automatic formatter configured)
|
||||
|
||||
### When to Rebuild Native Libraries
|
||||
|
||||
Rebuild native libraries (`scripts/ndk-make.sh`) when:
|
||||
- Updating deltachat-core-rust submodule
|
||||
- Modifying anything in `jni/` directory
|
||||
- Changing NDK version
|
||||
- After `git clean -fdx` or fresh clone
|
||||
|
||||
**DO NOT** rebuild native libraries for:
|
||||
- Pure Java/Kotlin code changes
|
||||
- Resource file changes
|
||||
- Gradle configuration changes (unless changing native library linking)
|
||||
- Documentation updates
|
||||
|
||||
## WebXDC Support
|
||||
|
||||
ArcaneChat has extended WebXDC support:
|
||||
@@ -152,12 +247,24 @@ ArcaneChat has extended WebXDC support:
|
||||
|
||||
## Important Files
|
||||
|
||||
- `build.gradle` - Main build configuration
|
||||
- `build.gradle` - Main build configuration (Android Gradle Plugin 8.11.1, Java 8 compatibility)
|
||||
- `CONTRIBUTING.md` - Contribution guidelines
|
||||
- `BUILDING.md` - Detailed build setup
|
||||
- `BUILDING.md` - Detailed build setup instructions
|
||||
- `RELEASE.md` - Release process
|
||||
- `proguard-rules.pro` - ProGuard configuration
|
||||
- `google-services.json` - Firebase configuration (gplay flavor)
|
||||
- `proguard-rules.pro` - ProGuard configuration (enabled for both debug and release)
|
||||
- `google-services.json` - Firebase configuration (gplay flavor only)
|
||||
- `settings.gradle` - Gradle settings
|
||||
- `.github/workflows/` - CI/CD configuration
|
||||
|
||||
## Dependencies and Constraints
|
||||
|
||||
- **Java Version:** Java 8 compatibility (do not use Java 9+ features)
|
||||
- **Gradle:** Use wrapper (`./gradlew`) to ensure correct Gradle version
|
||||
- **NDK:** Must use version 27.0.12077973 (specified in build.gradle)
|
||||
- **Min SDK:** 21 (Android 5.0) - code must be compatible
|
||||
- **Target SDK:** 36 (Android 16) - test on this API level when possible
|
||||
- **ProGuard:** Always enabled - ensure ProGuard rules are correct for new dependencies
|
||||
- **Multi-dex:** Enabled - app exceeds 65k method limit
|
||||
|
||||
## Package Structure
|
||||
|
||||
@@ -173,3 +280,35 @@ ArcaneChat has extended WebXDC support:
|
||||
- Native library must be rebuilt after core changes
|
||||
- ProGuard is enabled in both debug and release builds
|
||||
- Multi-dex is enabled due to app size
|
||||
|
||||
## CI/CD Workflows
|
||||
|
||||
### Preview APK Workflow (.github/workflows/preview-apk.yml)
|
||||
|
||||
Runs on every pull request to build and upload a preview APK:
|
||||
|
||||
1. **Setup steps:**
|
||||
- Checks out repository with submodules
|
||||
- Validates Fastlane metadata
|
||||
- Sets up Rust cache (working-directory: jni/deltachat-core-rust)
|
||||
- Sets up Java 17 (Temurin distribution)
|
||||
- Sets up Android SDK
|
||||
- Caches Gradle dependencies
|
||||
- Sets up NDK r27
|
||||
|
||||
2. **Build process:**
|
||||
```bash
|
||||
scripts/install-toolchains.sh && scripts/ndk-make.sh armeabi-v7a
|
||||
./gradlew --no-daemon -PABI_FILTER=armeabi-v7a assembleFossDebug
|
||||
```
|
||||
Note: Builds only armeabi-v7a for faster CI builds
|
||||
|
||||
3. **Output:** Uploads APK artifact to GitHub Actions
|
||||
|
||||
### Important CI Considerations
|
||||
|
||||
- Always validate Gradle wrapper before committing changes
|
||||
- Fastlane metadata must be valid (validated in CI)
|
||||
- Use `--no-daemon` flag for Gradle in CI environments
|
||||
- CI builds use FOSS flavor to avoid Google Services dependencies
|
||||
- Expected CI build time: 15-25 minutes for full workflow
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Delta Chat Android Changelog
|
||||
|
||||
## v2.40.0
|
||||
## v2.43.0
|
||||
2026-02
|
||||
|
||||
* Improve switch speed when changing profiles
|
||||
@@ -15,6 +15,10 @@
|
||||
* Add indication for blocked contacts in user profile
|
||||
* Allow to start calls with video disabled
|
||||
* Show hint for empty contact search results
|
||||
* Add background playing for voice messages and other audio files
|
||||
* Allow scanning Invitation Code when creating a new profile
|
||||
* Add context menu in long-pressing relays items instead of showing buttons
|
||||
* Enhanced video player UI
|
||||
* Fix: Show dialog if pasted QR codes are invalid
|
||||
* Fix: Refresh chat list when returning from conversation if selected profile changed
|
||||
* Fix: Update menu when using "select all" in contact selection
|
||||
@@ -23,9 +27,10 @@
|
||||
* Fix multi-device seen messages synchronization when using multiple relays
|
||||
* Fix mailto handling
|
||||
* Fix layout problems inside in-chat apps
|
||||
* Fix real-time for in-chat apps that need it
|
||||
* Avoid crash when the app is minimized with profile switcher or reactions dialogs open
|
||||
* Remove "trash icon" option from contact selection list when adding members to group
|
||||
* Update to core 2.40.0
|
||||
* Update to core 2.43.0
|
||||
|
||||
## v2.35.0
|
||||
2026-01
|
||||
|
||||
+7
-2
@@ -34,7 +34,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
versionCode 30000737
|
||||
versionName "2.40.0"
|
||||
versionName "2.43.0"
|
||||
|
||||
applicationId "chat.delta.lite"
|
||||
multiDexEnabled true
|
||||
@@ -211,6 +211,8 @@ dependencies {
|
||||
implementation "io.noties.markwon:inline-parser:$markwon_version"
|
||||
implementation 'com.airbnb.android:lottie:4.2.2' // Lottie animations support.
|
||||
|
||||
def media3_version = "1.8.0" // 1.9.0 need minSdkVersion 23
|
||||
|
||||
implementation 'androidx.concurrent:concurrent-futures:1.3.0'
|
||||
implementation 'androidx.sharetarget:sharetarget:1.2.0'
|
||||
implementation 'androidx.webkit:webkit:1.14.0'
|
||||
@@ -231,8 +233,11 @@ dependencies {
|
||||
implementation 'androidx.work:work-runtime:2.9.1'
|
||||
implementation 'androidx.emoji2:emoji2-emojipicker:1.5.0'
|
||||
implementation 'com.google.guava:guava:31.1-android'
|
||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1' // plays video and audio
|
||||
implementation 'com.google.android.exoplayer:exoplayer-core:2.19.1' // FIXME: exoplayer dependencies kept for Video, but we shall migrate them at some point
|
||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.19.1'
|
||||
implementation "androidx.media3:media3-exoplayer:$media3_version"
|
||||
implementation "androidx.media3:media3-session:$media3_version"
|
||||
implementation "androidx.media3:media3-ui:$media3_version"
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
|
||||
implementation 'com.google.zxing:core:3.3.0' // fixed version to support SDK<24
|
||||
implementation ('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false } // QR Code scanner
|
||||
|
||||
+1
-1
Submodule jni/deltachat-core-rust updated: 5cdbc9d736...7ad67cfa56
@@ -0,0 +1,17 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="228"
|
||||
android:viewportHeight="280">
|
||||
<group android:scaleX="0.35014287"
|
||||
android:scaleY="0.43"
|
||||
android:translateX="74.08372"
|
||||
android:translateY="79.8">
|
||||
<path
|
||||
android:pathData="m10.03,234.14c0.3,-0.01 0.6,-0.02 0.9,-0.04 -0.07,-0.49 -0.14,-0.97 -0.2,-1.46 -0.15,-1.34 -0.26,-2.69 -0.25,-4.04 -0.02,-0.86 -0.05,-1.71 -0.07,-2.57 -0.09,-0.06 -0.18,-0.13 -0.27,-0.19 -0.02,-0.02 -0.04,-0.03 -0.07,-0.05zM44.87,232.95c11.71,-8.35 26.86,-14.79 46.21,-15.9 0,0 39.93,-0.27 47.91,-3.53 7.98,-3.26 68.68,-14.69 82.94,-98.43 14.26,-83.74 -1.06,-115.09 -1.06,-115.09 0,0 -21.14,55.68 -81.02,59.81 0,0 -14.5,1.03 -38.82,1.42 -24.32,0.39 -75.77,20.65 -90.55,85.62l-0.22,43.44c2.5,4.22 5.49,8.12 8.91,11.66 3.99,4.11 8.11,8.12 12.79,11.45 2.26,1.65 4.65,3.2 6.51,5.33 1.94,2.34 3.33,5 4.2,7.93 0.71,2.1 1.45,4.2 2.2,6.28z"
|
||||
android:fillColor="@color/ic_launcher_background"/>
|
||||
<path
|
||||
android:pathData="m217.97,45.86c-0.3,0.01 -0.6,0.02 -0.9,0.04 0.07,0.49 0.14,0.97 0.2,1.46 0.15,1.34 0.26,2.69 0.25,4.04 0.02,0.86 0.05,1.71 0.07,2.57 0.09,0.06 0.18,0.13 0.27,0.19 0.02,0.02 0.04,0.03 0.07,0.05zM183.13,47.05c-11.71,8.35 -26.86,14.79 -46.21,15.9 0,0 -39.93,0.27 -47.91,3.53 -7.98,3.26 -68.68,14.69 -82.94,98.43 -14.26,83.74 1.06,115.09 1.06,115.09 0,0 21.14,-55.68 81.02,-59.81 0,0 14.5,-1.03 38.82,-1.42 24.32,-0.39 75.77,-20.65 90.55,-85.62l0.22,-43.44c-2.5,-4.22 -5.49,-8.12 -8.91,-11.66 -3.99,-4.11 -8.11,-8.12 -12.79,-11.45 -2.26,-1.65 -4.65,-3.2 -6.51,-5.33 -1.94,-2.34 -3.33,-5 -4.2,-7.93 -0.71,-2.1 -1.45,-4.2 -2.2,-6.28z"
|
||||
android:fillColor="@color/ic_launcher_background"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/white"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/white"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -38,6 +38,7 @@
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
|
||||
<!-- force compiling emojipicker on sdk<21; runtime checks are required then -->
|
||||
<uses-sdk tools:overrideLibrary="androidx.emoji2.emojipicker"/>
|
||||
@@ -391,6 +392,15 @@
|
||||
android:name=".service.FetchForegroundService"
|
||||
android:foregroundServiceType="dataSync" />
|
||||
|
||||
<service
|
||||
android:name=".service.AudioPlaybackService"
|
||||
android:foregroundServiceType="mediaPlayback"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.media3.session.MediaSessionService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<receiver android:name=".notifications.MarkReadReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
|
||||
@@ -1188,6 +1188,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1372,12 +1376,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1453,7 +1455,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1464,12 +1466,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1479,12 +1478,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1045,31 +1045,31 @@ für die <a href="https://chatmail.at/clients">Chatmail-Clients</a> umfasst, von
|
||||
|
||||
</h3>
|
||||
|
||||
<p>We would like to improve Delta Chat with your help,
|
||||
which is why Delta Chat for Android asks whether you want
|
||||
to send anonymous usage statistics.</p>
|
||||
<p>Wir möchten Delta Chat mit deiner Hilfe verbessern.
|
||||
Deshalb fragt Delta Chat für Android, ob du
|
||||
anonyme Nutzungsstatistiken senden möchtest.</p>
|
||||
|
||||
<p>You can turn it on and off at
|
||||
<strong>Settings → Advanced → Send statistics to Delta Chat’s developers</strong>.</p>
|
||||
<p>Du kannst dies unter
|
||||
<strong>Einstellungen → Erweitert → Statistik an Delta Chat Entwickler senden</strong> ein- und ausschalten.</p>
|
||||
|
||||
<p>When you turn it on,
|
||||
weekly statistics will be automatically sent to a bot.</p>
|
||||
<p>Wenn eingeschaltet,
|
||||
werden wöchentlich Statistiken automatisch an einen Bot gesendet.</p>
|
||||
|
||||
<p>We are interested e.g. in statistics like:</p>
|
||||
<p>Wir sind beispielsweise an folgenden Statistiken interessiert:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>How many contacts are introduced by personally scanning a QR code?</p>
|
||||
<p>Wie viele Kontakte werden durch das persönliche Scannen eines QR-Codes hergestellt?</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Which versions of Delta Chat are being used?</p>
|
||||
<p>Welche Versionen von Delta Chat werden verwendet?</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>What errors occur for users?</p>
|
||||
<p>Welche Fehler treten bei Benutzern auf?</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>We will <em>not</em> collect any personally identifiable information about you.</p>
|
||||
<p>Wir werden <em>keinerlei</em> personenbezogene Daten über dich sammeln.</p>
|
||||
|
||||
<h3 id="ich-bin-an-technischen-details-interessiert-gibt-es-hierzu-weitere-infos">
|
||||
|
||||
@@ -1107,6 +1107,10 @@ zum Austausch von Verschlüsselungsinformationen durch Scannen von QR-Codes oder
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> wird verwendet, um automatisch eine Ende-zu-Ende-Verschlüsselung zwischen Kontakten und allen Mitgliedern einer Gruppe herzustellen.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, dessen vollständige Implementierung für 2026 geplant ist,
|
||||
wir post-quantum-resistente Verschlüsselung und Forward Secrecy einführen.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Teilen eines Kontakts im Chat</a>
|
||||
ermöglicht es den Empfängern, eine Ende-zu-Ende-Verschlüsselung mit dem Kontakt zu verwenden.</p>
|
||||
@@ -1280,15 +1284,13 @@ selbst wenn die Nachricht nicht Ende-zu-Ende-verschlüsselt war.</p>
|
||||
speichern Delta-Chat-Apps keine Metadaten über Kontakte oder Gruppen auf Servern. Auch nicht in verschlüsselter Form.
|
||||
Stattdessen werden alle Gruppen-Metadaten durchgängig verschlüsselt und ausschließlich auf den Endgeräten der Nutzer gespeichert.</p>
|
||||
|
||||
<p>Servers can therefore only see:</p>
|
||||
<p>Server können daher nur das folgende sehen:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Absender- und Empfängeradressen, standardmäßig zufällig generiert</li>
|
||||
<li>Größe der Nachricht</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>Alle anderen Metadaten zu Nachrichten, Kontakten und Gruppen befinden sich im Ende-zu-Ende-verschlüsselten Teil der Nachrichten.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1299,15 +1301,15 @@ Stattdessen werden alle Gruppen-Metadaten durchgängig verschlüsselt und aussch
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Both for protecting against metadata-collecting servers
|
||||
as well as against the threat of device seizure
|
||||
we recommend to use a <a href="https://chatmail.at/relays">chatmail relay</a>
|
||||
to create chat profiles using random addresses for transport.
|
||||
Note that Delta Chat apps on all platforms support multiple profiles
|
||||
so you can easily use situation-specific profiles next to your “main” profile
|
||||
with the knowledge that all their data, along with all metadata, will be deleted.
|
||||
Moreover, if a device is seized then chat contacts using short-lived profiles
|
||||
can not be identified easily.</p>
|
||||
<p>Sowohl zum Schutz vor Servern, die Metadaten sammeln,
|
||||
als auch als Schutz bei Beschlagnahmung von Geräten
|
||||
empfehlen wir die Verwendung eines <a href="https://chatmail.at/relays">Chatmail-Relays</a>,
|
||||
um Chat-Profile mit zufälligen Adressen für den Transport zu erstellen.
|
||||
Beachte, dass Delta-Chat-Apps mehrere Profile unterstützen,
|
||||
sodass du neben deinem „Hauptprofil” ganz einfach situationsspezifische Profile verwenden kannst,
|
||||
mit der Gewissheit, dass alle Daten sowie alle Metadaten gelöscht werden.
|
||||
Darüber hinaus können Chat-Kontakte, die kurzlebige Profile verwenden,
|
||||
im Falle einer Beschlagnahmung des Geräts nicht ohne Weiteres identifiziert werden.</p>
|
||||
|
||||
<h3 id="wer-sieht-meine-ip-adresse">
|
||||
|
||||
@@ -1350,11 +1352,10 @@ um seine Serverinfrastruktur darüber im Unklaren zu lassen, wer eine Nachricht
|
||||
Dies ist besonders wichtig, weil der Signal-Server die Handynummer jedes Kontos kennt,
|
||||
die in der Regel mit einer Passidentität verbunden ist.</p>
|
||||
|
||||
<p>Even if <a href="https://chatmail.at/relays">chatmail relays</a>
|
||||
do not ask for any private data (including no phone numbers),
|
||||
it might still be worthwhile to protect relational metadata between addresses.
|
||||
We don’t foresee bigger problems in using random throw-away addresses for sealed sending
|
||||
but an implementation has not been agreed as a priority yet.</p>
|
||||
<p>Auch wenn <a href="https://chatmail.at/relays">Chatmail-Relays</a>
|
||||
keine privaten Daten (einschließlich Telefonnummern) abfragen,
|
||||
könnte es dennoch sinnvoll sein, Metadaten zwischen Adressen zu schützen.
|
||||
Wir sehen keine größeren Probleme bei der Verwendung von zufälligen Wegwerfadressen für aber eine Umsetzung wurde noch nicht als priorisiert.</p>
|
||||
|
||||
<h3 id="pfs">
|
||||
|
||||
@@ -1364,23 +1365,20 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Nein, noch nicht.</p>
|
||||
<p>Noch nicht, aber es kommt mit <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
and someone has collected your prior in-transit messages,
|
||||
they will be able to decrypt and read them using the leaked decryption key.
|
||||
Note that Forward Secrecy only increases security if you delete messages.
|
||||
Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
<p>Delta Chat unterstützt derzeit keine Perfect Forward Secrecy (PFS).
|
||||
Das bedeutet, dass, wenn Ihr privater Schlüssel offengelegt wird
|
||||
und jemand Ihre früheren Nachrichten während der Übertragung gesammelt hat,
|
||||
diese mit dem offengelegten Schlüssel entschlüsselt und gelesen werden können.
|
||||
Beachten Sie, dass Forward Secrecy die Sicherheit nur erhöht, wenn du Nachrichten löschst.
|
||||
Andernfalls kann jemand, der deinen Schlüssel erhält,
|
||||
in der Regel auch alle deine nicht gelöschten Nachrichten abrufen
|
||||
und muss zuvor gesammelte Nachrichten nicht einmal entschlüsseln.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, dessen vollständige Implementierung für 2026 geplant ist,
|
||||
wird durch automatische Schlüsselrotation eine zuverlässige Löschung (Forward Secrecy) gewährleisten.
|
||||
Dieser Ansatz ist im Entwurf <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> festgelegt.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1390,11 +1388,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Nein, noch nicht.</p>
|
||||
<p>Noch nicht, aber es kommt mit <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat verwendet die Rust OpenPGP-Bibliothek <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
die den neuesten <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP Entwurf</a> unterstützt.
|
||||
Wir beabsichtigen, PQC-Unterstützung zum <a href="https://github.com/chatmail/core">chatmail core</a> hinzuzufügen, sobald der Entwurf bei der IETF in Zusammenarbeit mit anderen OpenPGP-Implementierern fertiggestellt ist.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, dessen vollständige Implementierung für 2026 geplant ist,
|
||||
wird eine post-quantum-resistente Verschlüsselung zum Schutz vor Angriffen durch Quantencomputer bieten.
|
||||
Delta Chat verwendet die Rust-OpenPGP-Bibliothek <a href="https://github.com/rpgp/rpgp">rPGP</a>,
|
||||
die den neuesten <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Kryptografie OpenPGP Entfurf</a> unterstützt.
|
||||
Die Implementierung ist in <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> festgelegt.</p>
|
||||
|
||||
<h3 id="wie-kann-ich-die-verschlüsselung-manuell-überprüfen">
|
||||
|
||||
@@ -1420,12 +1420,11 @@ ist die Verbindung sicher.</p>
|
||||
|
||||
<p>Nein.</p>
|
||||
|
||||
<p>Delta Chat generates secure OpenPGP keys according to the Autocrypt specification 1.1.
|
||||
We do not recommend or offer users to perform manual key management.
|
||||
We want to ensure that security audits can focus on a few proven cryptographic algorithms
|
||||
instead of the full breadth of possible algorithms allowed with OpenPGP.
|
||||
If you want to extract your OpenPGP key, there only is an expert method:
|
||||
you need to look it up in the “keypairs” SQLite table of a profile backup tar-file.</p>
|
||||
<p>Delta Chat generiert sichere OpenPGP-Schlüssel gemäß der Autocrypt-Spezifikation 1.1.
|
||||
Wir bieten Benutzern keine manuelle Schlüsselverwaltung an, noch empfehlen diese.
|
||||
Wir wollen sicherstellen, dass sich Sicherheitsüberprüfungen auf einige wenige bewährte kryptografische Algorithmen konzentrieren können,
|
||||
anstatt auf die gesamte Bandbreite der mit OpenPGP zulässigen Algorithmen.
|
||||
Wenn Sie Ihren OpenPGP-Schlüssel extrahieren möchten, gibt es nur eine Methode für Experten: Sie müssen ihn in der SQLite-Tabelle „keypairs” des Backups nachschlagen.</p>
|
||||
|
||||
<h3 id="security-audits">
|
||||
|
||||
@@ -1535,31 +1534,24 @@ Wir nutzen vielmehr öffentliche Finanzierungsquellen, die bisher aus der EU und
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>2023 und 2024 wurden wir in das Next-Generation-Internet-Programm (NGI)
|
||||
für unsere Arbeit an <a href="https://nlnet.nl/project/WebXDC-Push/">Webxdc-PUSH</a> aufgenommen,
|
||||
zusammen mit Kooperationspartnern, die an
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">Webxdc-Evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">Webxdc-XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> und
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
Alle diese Projekte sind teilweise abgeschlossen oder sollen Anfang 2025 abgeschlossen werden.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Im Jahr 2021 erhielten wir weitere EU-Mittel für zwei “Next-Generation-Internet”-Anträge, nämlich für <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - E-Mail-Provider-Portabilitätsverzeichnis</a> (~97K EUR) und <a href="https://nlnet.nl/project/EmailPorting/">AEAP - E-Mail-Adressportierung</a> (~90K EUR). Ziel sind bessere Unterstützung von Mehrfachkonten, verbesserten QR-Code-Kontakt- und -Gruppen-Setups sowie Netzwerkverbesserungen auf allen Plattformen.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p>Die <a href="https://nlnet.nl/">NLnet-Stiftung</a> bewilligte 2019/2020 46K EUR für die Fertigstellung von Rust-/Python-Bindungs und die Einrichtung eines Chat-Bot-Ökosystems.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p>Der <a href="https://opentechfund.org">Open Technology Fund</a> hat Delta Chat erstmals 2018/2019 bezuschusst; mit dieser Förderung (~$200K) wurden hauptsächlich die Android-App verbessert sowie das Release der Desktop-App in einer Betaversion ermöglicht. Basierend auf Nutzererfahrungen im Menschenrechtskontext wurden zudem verschiedene Funktionen entwickelt, siehe unseren Bericht <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
Die zweite Förderung 2019/2020 (~$300K) half uns bei der Erstellung der iOS-Version, unsere Kernbibliothek in die Programmiersprache “Rust” zu konvertieren und neue Funktionen für alle Plattformen bereitzustellen.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Das EU-Projekt <a href="https://nextleap.eu">NEXTLEAP</a> finanzierte 2017 und 2018 die Entwicklung und Implementierung von “Verifizierten Gruppen” und “Setup Kontakt” und half auch bei der Integration der Ende-zu-Ende-Verschlüsselung durch <a href="https://autocrypt.org">Autocrypt</a>.</p>
|
||||
|
||||
@@ -1188,6 +1188,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1372,12 +1376,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1453,7 +1455,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1464,12 +1466,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1479,12 +1478,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1184,6 +1184,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1365,12 +1369,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1446,7 +1448,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1457,12 +1459,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1472,12 +1471,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1175,6 +1175,9 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, qui est prévu pour 2026, amènera un chiffrement avec résistance post-quantique ainsi que la confidentialité persistante (“forward secrecy”).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
chat</a>
|
||||
@@ -1358,12 +1361,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1418,7 +1419,7 @@ For example, tapping a link exposes IP Addresses to unknown parties and is the b
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Non, pas encore.</p>
|
||||
|
||||
<p>The Signal messenger introduced <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender” in 2018</a>
|
||||
to keep their server infrastructure ignorant of who is sending a message to a set of recipients.
|
||||
@@ -1439,7 +1440,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Pas encore mais cela arrive avec <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1450,12 +1451,8 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, prévu pour 2026, permettra la suppression fiable (forward secrecy) grâce à une rotation automatique des clefs.
|
||||
Cette approche est détaillée dans le brouillon du <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">certificat Autocrypt v2 OpenPGP</a>.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1465,12 +1462,11 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Pas encore mais cela arrive avec <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, prévu pour 2026, amènera un chiffrement avec résistance post-quantique pour protéger contre les attaques effectuées par des ordinateurs quantiques.
|
||||
Delta Chat utilise la librairie Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a> qui supporte les dernières <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
L’implémentation est détaillée dans le brouillon du <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">certificat Autocrypt v2 OpenPGP</a>.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1188,6 +1188,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1372,12 +1376,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1453,7 +1455,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1464,12 +1466,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1479,12 +1478,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1173,6 +1173,10 @@ per scambiare informazioni sulla configurazione della crittografia tramite la sc
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> viene utilizzato per stabilire
|
||||
automaticamente la crittografia end-to-end tra i contatti e tutti i membri di una chat di gruppo.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, la cui piena implementazione è prevista per il 2026,
|
||||
introdurrà una crittografia post-quantistica resistente e una segretezza avanzata.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Condivisione di un contatto con una
|
||||
@@ -1436,7 +1440,7 @@ ma un’implementazione non è stata ancora concordata come priorità.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, non ancora.</p>
|
||||
<p>Non ancora, ma arriverà con <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat al momento non supporta la tecnologia Perfect Forward Secrecy (PFS).
|
||||
Ciò significa che se la tua chiave di decrittazione privata viene divulgata
|
||||
@@ -1447,12 +1451,9 @@ In caso contrario, chi ottiene le tue chiavi di decrittazione
|
||||
in genere è in grado di ottenere anche tutti i tuoi messaggi non eliminati
|
||||
e non ha nemmeno bisogno di decifrare i messaggi raccolti in precedenza.</p>
|
||||
|
||||
<p>Abbiamo progettato un approccio Forward Secrecy che ha superato
|
||||
l’esame iniziale di alcuni crittografi ed esperti di implementazione
|
||||
ma è in attesa di una stesura più formale
|
||||
per accertarne l’affidabilità nella messaggistica federata e nell’utilizzo su più dispositivi,
|
||||
prima di poter essere implementato in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
che lo renderebbe disponibile in tutti i <a href="https://chatmail.at/clients">clients di chatmail</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">autocrypt v2</a>, la cui piena implementazione è prevista per il 2026,
|
||||
garantirà un’eliminazione affidabile (segretezza in avanti) tramite rotazione automatica delle chiavi.
|
||||
Questo approccio è specificato nella bozza dei <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">certificati OpenPGP di Autocrypt v2</a>.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1462,12 +1463,13 @@ che lo renderebbe disponibile in tutti i <a href="https://chatmail.at/clients">c
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, non ancora.</p>
|
||||
<p>Non ancora, ma arriverà con <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat utilizza la libreria Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, la cui piena implementazione è prevista per il 2026,
|
||||
offrirà una crittografia post-quantistica resistente per proteggere dagli attacchi ai computer quantistici.
|
||||
Delta Chat utilizza la libreria Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
che supporta l’ultima <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">bozza IETF Post-Quantum-Cryptography OpenPGP</a>.
|
||||
Il nostro obiettivo è aggiungere il supporto PQC nel <a href="https://github.com/chatmail/core">core di chatmail</a> dopo che la bozza sarà stata finalizzata dall’IETF
|
||||
in collaborazione con altri implementatori di OpenPGP.</p>
|
||||
L’implementazione è specificata nella bozza dei <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Certificati OpenPGP Autocrypt v2</a>.</p>
|
||||
|
||||
<h3 id="come-posso-controllare-manualmente-le-informazioni-di-crittografia">
|
||||
|
||||
@@ -1647,31 +1649,31 @@ ordinate cronologicamente:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>Nel 2023 e nel 2024 siamo stati accettati nel programma Next Generation Internet (NGI)
|
||||
per il nostro lavoro in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
insieme ai partner di collaborazione che lavorano su
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> e
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
Tutti questi progetti sono parzialmente completati o saranno completati all’inizio del 2025.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Nel 2021 abbiamo ricevuto ulteriori finanziamenti dall’UE per due proposte di Next-Generation-Internet, ovvero per <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - directory di portabilità dei provider di posta elettronica</a> (~97.000 EUR) e <a href="https://nlnet.nl/project/EmailPorting/">AEAP - portabilità degli indirizzi email</a> (~90.000 EUR), che hanno portato a un migliore supporto multi-profilo, a un miglioramento delle impostazioni di contatto e di gruppo tramite codice QR e a numerosi miglioramenti di rete su tutte le piattaforme.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p>La <a href="https://nlnet.nl/">fondazione NLnet</a> ha concesso nel 2019/2020 46.000 EUR per
|
||||
completando i collegamenti Rust/Python e avviando un ecosistema Chat-bot.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p>L’<a href="https://opentechfund.org">Open Technology Fund</a> ci ha dato una
|
||||
prima sovvenzione 2018/2019 (~$200K) durante la quale abbiamo notevolmente migliorato l’app Android
|
||||
e ha rilasciato una prima versione beta dell’app desktop, e che inoltre
|
||||
ancorato i nostri sviluppi delle funzionalità nella ricerca sulla UX nei contesti dei diritti umani,
|
||||
vedete il nostro <a href="https://delta.chat/en/2019-07-19-uxreport">Rapporto Needfinding e UX</a> conclusivo.
|
||||
La seconda sovvenzione 2019/2020 (~$300K) ci ha aiutato a farlo
|
||||
rilasciare nelle versioni Delta/iOS, per convertire la nostra libreria principale in Rust, e
|
||||
per fornire nuove funzionalità per tutte le piattaforme.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Il progetto UE <a href="https://nextleap.eu">NEXTLEAP</a> ha finanziato la ricerca
|
||||
|
||||
@@ -1182,6 +1182,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1366,12 +1370,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1447,7 +1449,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1458,12 +1460,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1473,12 +1472,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1102,6 +1102,10 @@ weekly statistics will be automatically sent to a bot.</p>
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> służy do automatycznego ustanawiania szyfrowania typu end-to-end między kontaktami a wszystkimi członkami czatu grupowego.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Udostępnienie kontaktu na czacie</a> umożliwia odbiorcom korzystanie z szyfrowania typu end-to-end z tym kontaktem.</p>
|
||||
</li>
|
||||
@@ -1236,12 +1240,10 @@ even if the message was not end-to-end encrypted.</p>
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>Wszystkie pozostałe metadane dotyczące wiadomości, kontaktów i grup znajdują się w zaszyfrowanej metodą end-to-end części wiadomości.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1314,11 +1316,13 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Nie, jeszcze nie.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat obecnie nie obsługuje mechanizmu Perfect Forward Secrecy (PFS). Oznacza to, że jeśli twój prywatny klucz deszyfrujący zostanie ujawniony, a ktoś zdobędzie twoje wcześniejsze wiadomości w trakcie transmisji, będzie mógł je odszyfrować i odczytać za pomocą ujawnionego klucza deszyfrującego. Należy pamiętać, że mechanizm Forward Secrecy zwiększa bezpieczeństwo tylko w przypadku usuwania wiadomości. W przeciwnym razie osoba, która uzyska twoje klucze deszyfrujące, zazwyczaj będzie mogła uzyskać dostęp do wszystkich nieusuniętych wiadomości i nie będzie musiała odszyfrowywać żadnych wcześniej zebranych wiadomości.</p>
|
||||
|
||||
<p>Opracowaliśmy metodę Forward Secrecy, która przeszła wstępną analizę niektórych kryptografów i ekspertów ds. wdrożeń, ale oczekuje na bardziej formalne opracowanie, które potwierdzi jej niezawodne działanie w federacyjnym przesyłaniu wiadomości i w przypadku korzystania z wielu urządzeń, zanim zostanie zaimplementowana w <a href="https://github.com/chatmail/core">rdzeniu chatmail</a>, co uczyniłoby ją dostępną we wszystkich <a href="https://chatmail.at/clients">klientach chatmail</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1328,9 +1332,13 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Nie, jeszcze nie.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat korzysta z biblioteki Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>, która obsługuje najnowszy <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">projekt OpenPGP IETF Post-Quantum-Cryptography</a>. Planujemy dodać obsługę PQC do <a href="https://github.com/chatmail/core">rdzenia chatmail</a> po sfinalizowaniu projektu w IETF we współpracy z innymi implementatorami OpenPGP.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="jak-mogę-ręcznie-sprawdzić-informacje-o-szyfrowaniu">
|
||||
|
||||
@@ -1463,32 +1471,17 @@ Raczej korzystamy z publicznych źródeł finansowania, jak dotąd pochodzących
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>W latach 2023 i 2024 zostaliśmy przyjęci do programu Next Generation Internet (NGI) za naszą pracę w <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>, wraz z partnerami współpracującymi pracującymi nad <a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>, <a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>, <a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> i <a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>. Wszystkie te projekty są częściowo ukończone lub zostaną ukończone na początku 2025 r.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>In 2021 we received further EU funding for two Next-Generation-Internet
|
||||
proposals, namely for <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - email provider portability directory</a> (~97K EUR) and <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90K EUR) which resulted in better multi-profile support, improved QR-code contact and group setups and many networking improvements on all platforms.</p>
|
||||
<p>W 2021 r. otrzymaliśmy kolejne dofinansowanie z UE na dwie propozycje dotyczące Internetu nowej generacji, a mianowicie na <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD – katalog przenośności dostawcy poczty e-mail</a> ( ~97 tys. EUR) i <a href="https://nlnet.nl/project/EmailPorting/">AEAP – przenoszenie adresu e-mail</a> (~90 tys. EUR), co zaowocowało lepszą obsługą wielu kont, ulepszonymi kontaktami i ustawieniami grup za pomocą kodów QR oraz wieloma ulepszeniami sieciowymi na wszystkich platformach.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p><a href="https://nlnet.nl/">Fundacja NLnet</a> przekazała w latach 2019/2020 kwotę 46 tys. EUR na wykonanie wiązań Rust/Python i uruchomienie ekosystemu Chat-bot.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p><a href="https://opentechfund.org">Open Technology Fund</a> przyznał nam pierwszy grant w 2018/2019 (~200 000 $), dzięki któremu znacznie ulepszyliśmy aplikację na Androida i wydaliśmy pierwszą wersję beta aplikacji na komputery stacjonarne, a także ugruntował rozwój naszych funkcji w badaniach UX w kontekście praw człowieka, zobacz nasz końcowy raport <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX</a>.
|
||||
Druga dotacja w 2019/2020 (~300 000 4) pomogła nam wydać wersje Delta/iOS, przekonwertować naszą podstawową bibliotekę na Rust i zapewnić nowe funkcje dla wszystkich platform.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Unijny projekt <a href="https://nextleap.eu">NEXTLEAP</a> sfinansował badania i wdrożenie zweryfikowanych grup i ustawień protokołów kontaktowych w latach 2017 i 2018, a także pomógł zintegrować szyfrowanie end-to-end poprzez <a href="https://autocrypt.org">Autocrypt</a>.</p>
|
||||
|
||||
@@ -1183,6 +1183,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1367,12 +1371,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1448,7 +1450,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1459,12 +1461,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1474,12 +1473,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1181,6 +1181,10 @@ Chatmail использует INBOX по умолчанию для ретран
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> используется для автоматической
|
||||
настройки сквозного шифрования между контактами и всеми членами группового чата.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, полное внедрение которого запланировано на 2026 год,
|
||||
обеспечит поддержку постквантового шифрования и прямой секретности.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Обмен контактом в
|
||||
@@ -1427,7 +1431,7 @@ Delta Chat вместо этого использует реализацию Ope
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Нет, еще нет.</p>
|
||||
<p>Нет, пока нет.</p>
|
||||
|
||||
<p>Мессенджер Signal внедрил функцию <a href="https://signal.org/blog/sealed-sender/">“Sealed Sender” (Засекреченный отправитель) в 2018 году</a>,
|
||||
чтобы их серверная инфраструктура не имела информации о том, кто отправляет сообщение группе получателей.
|
||||
@@ -1448,7 +1452,7 @@ Delta Chat вместо этого использует реализацию Ope
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Нет, еще нет.</p>
|
||||
<p>Пока нет, но это будет реализовано в <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>На данный момент, Delta Chat не поддерживает Perfect Forward Secrecy (PFS) (Совершенную прямую секретность).
|
||||
Это означает, что если ваш приватный ключ дешифрования будет скомпрометирован,
|
||||
@@ -1459,12 +1463,9 @@ Delta Chat вместо этого использует реализацию Ope
|
||||
также может получить все ваши не удалённые сообщения
|
||||
и ему даже не нужно расшифровывать какие-либо ранее собранные сообщения.</p>
|
||||
|
||||
<p>Мы разработали подход к Forward Secrecy (Прямой секретности), который прошёл
|
||||
первичную проверку некоторыми криптографами и экспертами по реализации
|
||||
но требует более формального описания
|
||||
чтобы убедиться, что он надёжно работает в федеративном обмене сообщениями и при использовании нескольких устройств,
|
||||
прежде чем он может быть внедрён в <a href="https://github.com/chatmail/core">ядро chatmail</a>,
|
||||
что сделает его доступным во всех <a href="https://chatmail.at/clients">клиентах clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, полное внедрение которого запланировано на 2026 год,
|
||||
обеспечит надёжное удаление (прямую секретность) за счёт автоматической ротации ключей.
|
||||
Этот подход описан в черновике спецификации <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a>.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1474,12 +1475,13 @@ Delta Chat вместо этого использует реализацию Ope
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Нет, еще нет.</p>
|
||||
<p>Пока нет, но эта возможность появится в <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat использует библиотеку OpenPGP на Rust <a href="https://github.com/rpgp/rpgp">rPGP</a>,
|
||||
которая поддерживает последний <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">черновик IETF Post-Quantum-Cryptography OpenPGP</a>.
|
||||
Мы планируем добавить поддержку PQC в <a href="https://github.com/chatmail/core">ядро chatmail</a> после того, как черновик будет окончательно утвержден в IETF
|
||||
в сотрудничестве с другими разработчиками OpenPGP.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, полное внедрение которого запланировано на 2026 год,
|
||||
обеспечит поддержку постквантового шифрования для защиты от атак с использованием квантовых компьютеров.
|
||||
Delta Chat использует Rust-библиотеку OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
которая поддерживает актуальный черновик IETF <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP</a>.
|
||||
Особенности реализации описаны в черновике спецификации <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a>.</p>
|
||||
|
||||
<h3 id="как-можно-вручную-проверить-информацию-о-шифровании">
|
||||
|
||||
@@ -1658,32 +1660,32 @@ Google Play Store, F-Droid, Huawei App Gallery, iOS и macOS App Store, Microsof
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>В 2023 и 2024 годах мы были приняты в программу Next Generation Internet (NGI)
|
||||
за нашу работу над <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
в сотрудничестве с партнерами, работающими над
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> и
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
Все эти проекты частично завершены или будут завершены в начале 2025 года.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>В 2021 г. мы получили дополнительное финансирование из ЕС для двух Next-Generation-Internet
|
||||
целей, а именно для <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - e-mail provider portability directory</a> (~97 тыс. евро) и <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90 тыс. евро). Это привело к улучшению поддержки нескольких профилей, улучшению настройки контактов и групп с помощью QR-кода и многим улучшениям в сетевом взаимодействии на всех платформах.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p>Фонд <a href="https://nlnet.nl/">NLnet Foundation</a> выделил в 2019/2020 году 46 тысяч евро на
|
||||
доработку связки Rust/Python и создание экосистемы чат-ботов..</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p>Фонд <a href="https://opentechfund.org">Open Technology Fund</a> предоставил нам
|
||||
первый грант в 2018/2019 году (~$200 тыс.), благодаря которому мы существенно улучшили приложение для Android
|
||||
и выпустили первую бета-версию приложения для настольных систем, а также провели
|
||||
исследования в области UX в контексте прав человека,
|
||||
см. наш заключительный отчет <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
Второй грант, полученный в 2019/2020 году (~$300 тыс.), помог нам
|
||||
выпустить версии Delta/iOS, перевести наш основной код на Rust и
|
||||
предоставить новые функции для всех платформ.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Проект ЕС <a href="https://nextleap.eu">NEXTLEAP</a> финансировал исследование
|
||||
|
||||
@@ -1188,6 +1188,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1372,12 +1376,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1453,7 +1455,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1464,12 +1466,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1479,12 +1478,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
|
||||
@@ -1190,6 +1190,10 @@ to exchange encryption setup information through QR-code scanning or “invite l
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
establishing end-to-end encryption between contacts and all members of a group chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Sharing a contact to a
|
||||
@@ -1374,12 +1378,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1455,7 +1457,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1466,12 +1468,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1481,12 +1480,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
@@ -1675,28 +1675,31 @@ along with collaboration partners working on
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>In 2021 we received further EU funding for two Next-Generation-Internet
|
||||
proposals, namely for <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - email provider portability directory</a> (~97K EUR) and <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90K EUR) which resulted in better multi-profile support, improved QR-code contact and group setups and many networking improvements on all platforms.</p>
|
||||
<p>Më 2021-n morëm financime të mëtejshme nga BE për dy propozime që shtrihen në
|
||||
“Internetin e Brezit Tjetër”, konkretisht për <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - e-mail provider portability directory</a> (~97K euro) dhe <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90K euro) që sollën mbulim më të mirë për përdorues me shumë
|
||||
llogari, përmirësim të gjërave për kontakte me kod QR dhe grupe, si dhe mjaft
|
||||
përmirësime në punën në rrjet për krejt platformat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p><a href="https://nlnet.nl/">Fondacioni NLnet</a> dhuroi 46K euro gjatë 2019/2020 për
|
||||
plotësimin e <em>Rust/Python bindings</em> dhe për t’i dhënë udhë një ekosistemi
|
||||
Chat-bot.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p><a href="https://opentechfund.org">Open Technology Fund</a> na dha grantin e parë
|
||||
për 2018/2019 (~200 mijë dollarë) me të cilin përmirësuam ndjeshëm aplikacionin
|
||||
për Android dhe hodhëm në qarkullim një version të parë beta aplikacioni për Desktop,
|
||||
si dhe i afroi më tepër zhvillimet tona për veçori me kërkime UX në kontekste të drejtash të njeriut,
|
||||
shihni <a href="https://delta.chat/en/2019-07-19-uxreport">raportin tonë përfundimtar “Needfinding and UX”</a>.
|
||||
Granti i dytë për 2019/2020 (~$300K) na ndihmoi të hedhim në qarkullim
|
||||
versione Delta/iOS, për të shndërruar bibliotekën tonë bazë në Rust, si dhe
|
||||
për të sjellë veçori të reja për krejt platformat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nextleap.eu">NEXTLEAP</a> EU project funded the research
|
||||
and implementation of verified groups and setup contact protocols
|
||||
in 2017 and 2018 and also helped to integrate end-to-end Encryption
|
||||
through <a href="https://autocrypt.org">Autocrypt</a>.</p>
|
||||
<p>Projekti <a href="https://nextleap.eu">NEXTLEAP</a> i BE-së financoi kërkimin
|
||||
për dhe sendërtimin e grupeve të verifikuara dhe protokolleve të
|
||||
ujdisjes së kontakteve më 2017-n dhe 2018-n dhe ndihmoi gjithashtu
|
||||
të integrohet Fshehtëzim Skaj-më-Skaj përmes <a href="https://autocrypt.org">Autocrypt</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Ndonjëherë marrim dhurime unike nga individë privatë.
|
||||
|
||||
@@ -140,17 +140,10 @@
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>If you are <strong>face to face</strong> with your friend or family,
|
||||
tap the <strong>QR Code</strong> icon <img style="vertical-align:middle; height:1.3em; margin:1px" src="../qr-icon.png" />
|
||||
on the main screen.<br />
|
||||
Ask your chat partner to <strong>scan</strong> the QR image
|
||||
with their Delta Chat app.</p>
|
||||
<p>Якщо ви перебуваєте <strong>віч-на-віч</strong> зі своїм другом або родиною, торкніться піктограми <strong>QR-код</strong> на головному екрані <img style="vertical-align:middle; height:1.3em; margin:1px" src="../qr-icon.png" /> на головному екрані. Попросіть вашого партнера по чату <strong>сканувати</strong> QR-зображення за допомогою їхнього застосунку Delta Chat.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>For a <strong>remote</strong> contact setup,
|
||||
from the same screen,
|
||||
click “Copy” or “Share” and send the <strong>invite link</strong>
|
||||
through another private chat.</p>
|
||||
<p>Для <strong>віддаленого</strong> налаштування контакту, на тому ж самому екрані, натисніть “Копіювати” або “Поділитися” і відправте <strong>запрошувальне посилання</strong> через інший приватний чат.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1095,6 +1088,10 @@ to send anonymous usage statistics.</p>
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> використовується для автоматичного встановлення наскрізного шифрування між контактами і всіма учасниками групового чату.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">Поширення контакту в чаті</a> дозволяє отримувачам використовувати наскрізне шифрування з контактом.</p>
|
||||
</li>
|
||||
@@ -1298,11 +1295,13 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Ні, поки ще ні.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat наразі не підтримує ідеальну пряму секретність (Perfect Forward Secrecy, PFS). Це означає, що якщо ваш приватний ключ для розшифрування буде скомпрометовано, а хтось заздалегідь зібрав ваші повідомлення під час передачі, він зможе розшифрувати та прочитати їх, використовуючи зламаний ключ. Зверніть увагу, що пряма секретність підвищує рівень безпеки лише в тому разі, якщо ви видаляєте повідомлення. Інакше, якщо хтось отримує доступ до ваших ключів розшифрування, він зазвичай також має доступ до всіх ваших невидалених повідомлень і навіть не потребує розшифровувати заздалегідь перехоплені дані.</p>
|
||||
|
||||
<p>Ми розробили підхід Forward Secrecy, який витримав початкову експертизу від деяких криптографів та експертів з реалізації але чекає на більш офіційний звіт щоб переконатися, що він надійно працює в об’єднаних системах обміну повідомленнями та при використанні декількох пристроїв, перш ніж його можна буде реалізувати в <a href="https://github.com/chatmail/core">ядрі чату</a>, що зробить його доступним у всіх <a href="https://chatmail.at/clients">клієнтах чату</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1312,9 +1311,13 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>Ні, поки ще ні.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat використовує бібліотеку Rust OpenPGP <a href="https://github.com/rpgp/rpgp">rPGP</a> яка підтримує останню версію <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>. Ми плануємо додати підтримку PQC у <a href="https://github.com/chatmail/core">chatmail core</a> після того, як проект буде завершено у IETF у співпраці з іншими розробниками OpenPGP.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="як-я-можу-вручну-перевірити-інформацію-про-шифрування">
|
||||
|
||||
@@ -1445,32 +1448,24 @@ Google Play Store, F-Droid, Huawei App Gallery, iOS and macOS App Store, Microso
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>У 2023 та 2024 роках нас прийняли до програми Next Generation Internet (NGI) за нашу роботу над <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>, а також у співпраці з партнерами, які працюють над <a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>, <a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>, <a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> та <a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>. Усі ці проєкти частково завершені або будуть завершені на початку 2025 року.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>In 2021 we received further EU funding for two Next-Generation-Internet
|
||||
proposals, namely for <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - email provider portability directory</a> (~97K EUR) and <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90K EUR) which resulted in better multi-profile support, improved QR-code contact and group setups and many networking improvements on all platforms.</p>
|
||||
<p>У 2021 році ми отримали подальше фінансування від ЄС на дві пропозиції щодо Інтернету наступного покоління а саме на <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - каталог перенесення провайдерів електронної пошти</a> (~97 тис. євро) та <a href="https://nlnet.nl/project/EmailPorting/">AEAP - перенесення адрес електронної пошти</a> (~90 тис. євро), що дозволило нам покращити багатопрофільну підтримку, вдосконалити налаштування контактів та груп за допомогою QR-коду та багато інших мережевих покращень на всіх платформах.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p>Фонд <a href="https://nlnet.nl/">NLnet</a> виділив у 2019/2020 роках 46 тисяч євро на
|
||||
завершення прив’язок Rust/Python та запуск екосистеми чат-ботів.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p><a href="https://opentechfund.org">Open Technology Fund</a> надав нам два гранти.
|
||||
Перший грант 2018/2019 року (~$200K), допоміг значно покращили додаток для Android
|
||||
і випустили першу бета-версію додатка для ПК, і який до того ж
|
||||
закріпив наші розробки функцій у дослідженнях UX у контексті прав людини,
|
||||
дивіться наш підсумковий звіт <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
Другий грант 2019/2020 року (~$300K) допоміг нам
|
||||
випустити Delta/iOS версію, конвертувати нашу основному бібліотеку на Rust,
|
||||
і додати нові функції для всіх платформ.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Проект ЄС <a href="https://nextleap.eu">NEXTLEAP</a> фінансував дослідження та впровадження верифікованих груп і протоколів встановлення контактів у 2017 та 2018 роках, а також допоміг інтегрувати наскрізне шифрування через <a href="https://autocrypt.org">Autocrypt</a>.</p>
|
||||
|
||||
@@ -1161,6 +1161,10 @@ weekly statistics will be automatically sent to a bot.</p>
|
||||
<li>
|
||||
<p><a href="https://autocrypt.org">Autocrypt</a> is used for automatically
|
||||
用于在联系人和群聊的所有成员之间自动建立端到端加密。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption and forward secrecy.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://github.com/chatmail/core/blob/main/spec.md#attaching-a-contact-to-a-message">将联系人分享到聊天中
|
||||
@@ -1342,12 +1346,10 @@ Instead, all group metadata is end-to-end encrypted and stored on end-user devic
|
||||
<p>Servers can therefore only see:</p>
|
||||
|
||||
<ul>
|
||||
<li>the sender and receiver addresses</li>
|
||||
<li>and the message size.</li>
|
||||
<li>Sender and receiver addresses, randomly generated by default</li>
|
||||
<li>Message size</li>
|
||||
</ul>
|
||||
|
||||
<p>By default, the addresses are randomly generated.</p>
|
||||
|
||||
<p>All other message, contact and group metadata resides in the end-to-end encrypted part of messages.</p>
|
||||
|
||||
<h3 id="device-seizure">
|
||||
@@ -1423,7 +1425,7 @@ but an implementation has not been agreed as a priority yet.</p>
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat today doesn’t support Perfect Forward Secrecy (PFS).
|
||||
This means that if your private decryption key is leaked,
|
||||
@@ -1434,12 +1436,9 @@ Otherwise, someone obtaining your decryption keys
|
||||
is typically also able to get all your non-deleted messages
|
||||
and doesn’t even need to decrypt any previously collected messages.</p>
|
||||
|
||||
<p>We designed a Forward Secrecy approach that withstood
|
||||
initial examination from some cryptographers and implementation experts
|
||||
but is pending a more formal write up
|
||||
to ascertain it reliably works in federated messaging and with multi-device usage,
|
||||
before it could be implemented in <a href="https://github.com/chatmail/core">chatmail core</a>,
|
||||
which would make it available in all <a href="https://chatmail.at/clients">chatmail clients</a>.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will provide reliable deletion (forward secrecy) through automatic key rotation.
|
||||
This approach is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="pqc">
|
||||
|
||||
@@ -1449,12 +1448,13 @@ which would make it available in all <a href="https://chatmail.at/clients">chatm
|
||||
|
||||
</h3>
|
||||
|
||||
<p>No, not yet.</p>
|
||||
<p>Not yet, but it’s coming with <a href="https://autocrypt2.org">Autocrypt v2</a>.</p>
|
||||
|
||||
<p>Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
We aim to add PQC support in <a href="https://github.com/chatmail/core">chatmail core</a> after the draft is finalized at the IETF
|
||||
in collaboration with other OpenPGP implementers.</p>
|
||||
<p><a href="https://autocrypt2.org">Autocrypt v2</a>, scheduled for full implementation in 2026,
|
||||
will bring post-quantum resistant encryption to protect against quantum computer attacks.
|
||||
Delta Chat uses the Rust OpenPGP library <a href="https://github.com/rpgp/rpgp">rPGP</a>
|
||||
which supports the latest <a href="https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/">IETF Post-Quantum-Cryptography OpenPGP draft</a>.
|
||||
The implementation is specified in the <a href="https://datatracker.ietf.org/doc/draft-autocrypt-openpgp-v2-cert/">Autocrypt v2 OpenPGP Certificates</a> draft.</p>
|
||||
|
||||
<h3 id="how-can-i-manually-check-encryption-information">
|
||||
|
||||
@@ -1624,32 +1624,22 @@ Google Play Store, F-Droid, Huawei App Gallery, iOS and macOS App Store, Microso
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>In 2023 and 2024 we got accepted in the Next Generation Internet (NGI)
|
||||
program for our work in <a href="https://nlnet.nl/project/WebXDC-Push/">webxdc PUSH</a>,
|
||||
along with collaboration partners working on
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">webxdc evolve</a>,
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">webxdc XMPP</a>,
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> and
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a>.
|
||||
All of these projects are partially completed or to be completed in early 2025.</p>
|
||||
<p>在 2023 年和 2024 年,我们的 <a href="https://nlnet.nl/project/WebXDC-Push/">WebXDC PUSH</a> 工作已在下一代互联网 (NGI) 中获得认可,
|
||||
并与致力于
|
||||
<a href="https://nlnet.nl/project/Webxdc-Evolve/">WebXDC evolve</a>、
|
||||
<a href="https://nlnet.nl/project/WebXDC-XMPP/">WebXDC XMPP</a>、
|
||||
<a href="https://nlnet.nl/project/DeltaTouch/">DeltaTouch</a> 和
|
||||
<a href="https://nlnet.nl/project/DeltaTauri/">DeltaTauri</a> 的合作伙伴合作。
|
||||
所有这些项目都已部分完成或将在 2025 年初完成。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>In 2021 we received further EU funding for two Next-Generation-Internet
|
||||
proposals, namely for <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - email provider portability directory</a> (~97K EUR) and <a href="https://nlnet.nl/project/EmailPorting/">AEAP - email address porting</a> (~90K EUR) which resulted in better multi-profile support, improved QR-code contact and group setups and many networking improvements on all platforms.</p>
|
||||
<p>在 2021 年,我们从两项下一代互联网提案收到了欧盟的进一步资助,即 <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - 电子邮件提供商可移植性目录</a>(约 9.7 万欧元)和 <a href="https://nlnet.nl/project/EmailPorting/">AEAP - 电子邮件地址移植</a>(约 9 万欧元)。这带来了更好的多账户支持,改进的二维码联系人和群组设置,和所有平台上的多处网络改进。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://nlnet.nl/">NLnet foundation</a> granted in 2019/2020 EUR 46K for
|
||||
completing Rust/Python bindings and instigating a Chat-bot eco-system.</p>
|
||||
<p><a href="https://nlnet.nl/">NLnet 基金会</a> 2019/2020 年拨款 4.6 万欧元,用于完成 Rust/Python 绑定并建立聊天机器人生态系统。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="https://opentechfund.org">Open Technology Fund</a> gave us a
|
||||
first 2018/2019 grant (~$200K) during which we majorly improved the Android app
|
||||
and released a first Desktop app beta version, and which moreover
|
||||
moored our feature developments in UX research in human rights contexts,
|
||||
see our concluding <a href="https://delta.chat/en/2019-07-19-uxreport">Needfinding and UX report</a>.
|
||||
The second 2019/2020 grant (~$300K) helped us to
|
||||
release Delta/iOS versions, to convert our core library to Rust, and
|
||||
to provide new features for all platforms.</p>
|
||||
<p>在<a href="https://opentechfund.org">开放技术基金</a> 2018/2019 年提供的第一笔赠款(约 20 万美元)期间,我们显著改善了安卓应用,发布了第一个桌面测试版,并根据人权方面的用户体验研究进行了功能开发,请参阅我们的结论<a href="https://delta.chat/en/2019-07-19-uxreport">《需求发现与用户体验报告》</a>。2019/2020 年的第二笔赠款(约 30 万美元)对发布 Delta/iOS 版本,将核心库转换到 Rust ,以及为所有平台开发新功能提供了帮助。</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="https://nextleap.eu">NEXTLEAP</a>欧盟项目资助了以下研究和实施工作:在 2017 年和 2018 年实施的验证组和设置联系协议和通过 <a href="https://autocrypt.org">Autocrypt</a>整合了端到端加密。</p>
|
||||
|
||||
@@ -682,7 +682,8 @@ public class Rpc {
|
||||
* Set group name.
|
||||
* <p>
|
||||
* If the group is already _promoted_ (any message was sent to the group),
|
||||
* all group members are informed by a special status message that is sent automatically by this function.
|
||||
* or if this is a brodacast channel,
|
||||
* all members are informed by a special status message that is sent automatically by this function.
|
||||
* <p>
|
||||
* Sends out #DC_EVENT_CHAT_MODIFIED and #DC_EVENT_MSGS_CHANGED if a status message was sent.
|
||||
*/
|
||||
@@ -690,11 +691,37 @@ public class Rpc {
|
||||
transport.call("set_chat_name", mapper.valueToTree(accountId), mapper.valueToTree(chatId), mapper.valueToTree(newName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set group or broadcast channel description.
|
||||
* <p>
|
||||
* If the group is already _promoted_ (any message was sent to the group),
|
||||
* or if this is a brodacast channel,
|
||||
* all members are informed by a special status message that is sent automatically by this function.
|
||||
* <p>
|
||||
* Sends out #DC_EVENT_CHAT_MODIFIED and #DC_EVENT_MSGS_CHANGED if a status message was sent.
|
||||
* <p>
|
||||
* See also [`Self::get_chat_description`] / `getChatDescription()`.
|
||||
*/
|
||||
public void setChatDescription(Integer accountId, Integer chatId, String description) throws RpcException {
|
||||
transport.call("set_chat_description", mapper.valueToTree(accountId), mapper.valueToTree(chatId), mapper.valueToTree(description));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the chat description from the database.
|
||||
* <p>
|
||||
* UIs show this in the profile page of the chat,
|
||||
* it is settable by [`Self::set_chat_description`] / `setChatDescription()`.
|
||||
*/
|
||||
public String getChatDescription(Integer accountId, Integer chatId) throws RpcException {
|
||||
return transport.callForResult(new TypeReference<String>(){}, "get_chat_description", mapper.valueToTree(accountId), mapper.valueToTree(chatId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set group profile image.
|
||||
* <p>
|
||||
* If the group is already _promoted_ (any message was sent to the group),
|
||||
* all group members are informed by a special status message that is sent automatically by this function.
|
||||
* or if this is a brodacast channel,
|
||||
* all members are informed by a special status message that is sent automatically by this function.
|
||||
* <p>
|
||||
* Sends out #DC_EVENT_CHAT_MODIFIED and #DC_EVENT_MSGS_CHANGED if a status message was sent.
|
||||
* <p>
|
||||
|
||||
@@ -4,6 +4,7 @@ package chat.delta.rpc.types;
|
||||
public enum SystemMessageType {
|
||||
Unknown,
|
||||
GroupNameChanged,
|
||||
GroupDescriptionChanged,
|
||||
GroupImageChanged,
|
||||
MemberAddedToGroup,
|
||||
MemberRemovedFromGroup,
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.media3.session.MediaController;
|
||||
import androidx.media3.session.SessionCommand;
|
||||
import androidx.media3.session.SessionToken;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
@@ -18,11 +26,13 @@ import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcEvent;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.service.AudioPlaybackService;
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -30,6 +40,7 @@ import java.util.ArrayList;
|
||||
public class AllMediaActivity extends PassphraseRequiredActionBarActivity
|
||||
implements DcEventCenter.DcEventDelegate
|
||||
{
|
||||
private static final String TAG = AllMediaActivity.class.getSimpleName();
|
||||
|
||||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String CONTACT_ID_EXTRA = "contact_id";
|
||||
@@ -57,6 +68,10 @@ public class AllMediaActivity extends PassphraseRequiredActionBarActivity
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager viewPager;
|
||||
|
||||
private @Nullable MediaController mediaController;
|
||||
private ListenableFuture<MediaController> mediaControllerFuture;
|
||||
private AudioPlaybackViewModel playbackViewModel;
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme = new DynamicNoActionBarTheme();
|
||||
@@ -91,11 +106,19 @@ public class AllMediaActivity extends PassphraseRequiredActionBarActivity
|
||||
DcEventCenter eventCenter = DcHelper.getEventCenter(this);
|
||||
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
|
||||
eventCenter.addObserver(DcContext.DC_EVENT_CONTACTS_CHANGED, this);
|
||||
|
||||
playbackViewModel = new ViewModelProvider(this).get(AudioPlaybackViewModel.class);
|
||||
initializeMediaController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
DcHelper.getEventCenter(this).removeObservers(this);
|
||||
if (mediaController != null) {
|
||||
MediaController.releaseFuture(mediaControllerFuture);
|
||||
mediaController = null;
|
||||
playbackViewModel.setMediaController(null);
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -124,6 +147,40 @@ public class AllMediaActivity extends PassphraseRequiredActionBarActivity
|
||||
this.tabLayout = ViewUtil.findById(this, R.id.tab_layout);
|
||||
}
|
||||
|
||||
private void initializeMediaController() {
|
||||
SessionToken sessionToken = new SessionToken(this,
|
||||
new ComponentName(this, AudioPlaybackService.class));
|
||||
mediaControllerFuture = new MediaController.Builder(this, sessionToken)
|
||||
.buildAsync();
|
||||
mediaControllerFuture.addListener(() -> {
|
||||
try {
|
||||
mediaController = mediaControllerFuture.get();
|
||||
addActivityContext(
|
||||
this.getIntent().getExtras(),
|
||||
this.getClass().getName()
|
||||
);
|
||||
playbackViewModel.setMediaController(mediaController);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error connecting to audio playback service", e);
|
||||
}
|
||||
}, ContextCompat.getMainExecutor(this));
|
||||
}
|
||||
|
||||
private void addActivityContext(Bundle extras, String activityClassName) {
|
||||
if (mediaController == null) return;
|
||||
|
||||
Bundle commandArgs = new Bundle();
|
||||
commandArgs.putString("activity_class", activityClassName);
|
||||
if (extras != null) {
|
||||
commandArgs.putAll(extras);
|
||||
}
|
||||
|
||||
SessionCommand updateContextCommand =
|
||||
new SessionCommand("UPDATE_ACTIVITY_CONTEXT", Bundle.EMPTY);
|
||||
|
||||
mediaController.sendCustomCommand(updateContextCommand, commandArgs);
|
||||
}
|
||||
|
||||
private boolean isGlobalGallery() {
|
||||
return contactId==0 && chatId==0;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,10 @@ import androidx.annotation.NonNull;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
import com.codewaves.stickyheadergrid.StickyHeaderGridAdapter;
|
||||
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.components.DocumentView;
|
||||
import org.thoughtcrime.securesms.components.WebxdcView;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.mms.DocumentSlide;
|
||||
@@ -31,7 +32,8 @@ class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||
private final ItemClickListener itemClickListener;
|
||||
private final Set<DcMsg> selected;
|
||||
|
||||
private BucketedThreadMedia media;
|
||||
private BucketedThreadMedia media;
|
||||
private AudioPlaybackViewModel playbackViewModel;
|
||||
|
||||
private static class ViewHolder extends StickyHeaderGridAdapter.ItemViewHolder {
|
||||
private final DocumentView documentView;
|
||||
@@ -71,6 +73,10 @@ class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||
this.media = media;
|
||||
}
|
||||
|
||||
public void setPlaybackViewModel(AudioPlaybackViewModel playbackViewModel) {
|
||||
this.playbackViewModel = playbackViewModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StickyHeaderGridAdapter.HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent, int headerType) {
|
||||
return new HeaderHolder(LayoutInflater.from(context).inflate(R.layout.contact_selection_list_divider, parent, false));
|
||||
@@ -97,7 +103,8 @@ class AllMediaDocumentsAdapter extends StickyHeaderGridAdapter {
|
||||
viewHolder.webxdcView.setVisibility(View.GONE);
|
||||
|
||||
viewHolder.audioView.setVisibility(View.VISIBLE);
|
||||
viewHolder.audioView.setAudio((AudioSlide)slide, dcMsg.getDuration());
|
||||
viewHolder.audioView.setPlaybackViewModel(playbackViewModel);
|
||||
viewHolder.audioView.setAudio((AudioSlide)slide);
|
||||
viewHolder.audioView.setOnClickListener(view -> itemClickListener.onMediaClicked(dcMsg));
|
||||
viewHolder.audioView.setOnLongClickListener(view -> { itemClickListener.onMediaLongClicked(dcMsg); return true; });
|
||||
viewHolder.audioView.disablePlayer(!selected.isEmpty());
|
||||
|
||||
@@ -16,6 +16,7 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -25,6 +26,7 @@ import com.b44t.messenger.DcEvent;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
|
||||
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader;
|
||||
@@ -72,9 +74,11 @@ public class AllMediaDocumentsFragment
|
||||
// add padding to avoid content hidden behind system bars
|
||||
ViewUtil.applyWindowInsets(recyclerView, true, false, true, true);
|
||||
|
||||
this.recyclerView.setAdapter(new AllMediaDocumentsAdapter(getContext(),
|
||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||
this));
|
||||
AllMediaDocumentsAdapter adapter = new AllMediaDocumentsAdapter(getContext(),
|
||||
new BucketedThreadMediaLoader.BucketedThreadMedia(getContext()),
|
||||
this);
|
||||
this.recyclerView.setAdapter(adapter);
|
||||
adapter.setPlaybackViewModel(new ViewModelProvider(requireActivity()).get(AudioPlaybackViewModel.class));
|
||||
this.recyclerView.setLayoutManager(gridManager);
|
||||
this.recyclerView.setHasFixedSize(true);
|
||||
|
||||
@@ -239,12 +243,13 @@ public class AllMediaDocumentsFragment
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem menuItem) {
|
||||
int itemId = menuItem.getItemId();
|
||||
AudioPlaybackViewModel playbackViewModel = new ViewModelProvider(requireActivity()).get(AudioPlaybackViewModel.class);
|
||||
if (itemId == R.id.details) {
|
||||
handleDisplayDetails(getSelectedMessageRecord(getListAdapter().getSelectedMedia()));
|
||||
mode.finish();
|
||||
return true;
|
||||
} else if (itemId == R.id.delete) {
|
||||
handleDeleteMessages(chatId, getListAdapter().getSelectedMedia());
|
||||
handleDeleteMessages(chatId, getListAdapter().getSelectedMedia(), playbackViewModel::stopByIds, playbackViewModel::stopByIds);
|
||||
mode.finish();
|
||||
return true;
|
||||
} else if (itemId == R.id.share) {
|
||||
|
||||
@@ -50,11 +50,11 @@ public abstract class BaseConversationItem extends LinearLayout
|
||||
this.rpc = DcHelper.getRpc(context);
|
||||
}
|
||||
|
||||
protected void bind(@NonNull DcMsg messageRecord,
|
||||
@NonNull DcChat dcChat,
|
||||
@NonNull Set<DcMsg> batchSelected,
|
||||
boolean pulseHighlight,
|
||||
@NonNull Recipient conversationRecipient)
|
||||
protected void bindPartial(@NonNull DcMsg messageRecord,
|
||||
@NonNull DcChat dcChat,
|
||||
@NonNull Set<DcMsg> batchSelected,
|
||||
boolean pulseHighlight,
|
||||
@NonNull Recipient conversationRecipient)
|
||||
{
|
||||
this.messageRecord = messageRecord;
|
||||
this.dcChat = dcChat;
|
||||
@@ -126,6 +126,8 @@ public abstract class BaseConversationItem extends LinearLayout
|
||||
|
||||
public void onClick(View v) {
|
||||
if (!shouldInterceptClicks(messageRecord) && parent != null) {
|
||||
// The click workaround on ConversationItem shall be revised.
|
||||
// In fact, it is probably better rethinking accessibility approach for the items.
|
||||
if (batchSelected.isEmpty() && Util.isTouchExplorationEnabled(context)) {
|
||||
BaseConversationItem.this.onAccessibilityClick();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import androidx.annotation.Nullable;
|
||||
import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
@@ -17,7 +19,9 @@ public interface BindableConversationItem extends Unbindable {
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Set<DcMsg> batchSelected,
|
||||
@NonNull Recipient recipients,
|
||||
boolean pulseHighlight);
|
||||
boolean pulseHighlight,
|
||||
@Nullable AudioPlaybackViewModel playbackViewModel,
|
||||
AudioView.OnActionListener audioPlayPauseListener);
|
||||
|
||||
DcMsg getMessageRecord();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ClipData;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
@@ -65,7 +66,12 @@ import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.media3.session.MediaController;
|
||||
import androidx.media3.session.SessionCommand;
|
||||
import androidx.media3.session.SessionToken;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcContact;
|
||||
@@ -76,7 +82,7 @@ import com.b44t.messenger.DcMsg;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment;
|
||||
import org.thoughtcrime.securesms.audio.AudioRecorder;
|
||||
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
|
||||
import org.thoughtcrime.securesms.calls.CallUtil;
|
||||
import org.thoughtcrime.securesms.components.AnimatingToggle;
|
||||
import org.thoughtcrime.securesms.components.AttachmentTypeSelector;
|
||||
import org.thoughtcrime.securesms.components.ComposeText;
|
||||
@@ -86,6 +92,8 @@ import org.thoughtcrime.securesms.components.InputPanel;
|
||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||
import org.thoughtcrime.securesms.components.ScaleStableImageView;
|
||||
import org.thoughtcrime.securesms.components.SendButton;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.components.emoji.MediaKeyboard;
|
||||
import org.thoughtcrime.securesms.connect.AccountManager;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
@@ -104,19 +112,19 @@ import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.scribbles.ScribbleActivity;
|
||||
import org.thoughtcrime.securesms.service.AudioPlaybackService;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.ShareUtil;
|
||||
import org.thoughtcrime.securesms.util.SendRelayedMessageUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.ShareUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener;
|
||||
import org.thoughtcrime.securesms.util.guava.Optional;
|
||||
import org.thoughtcrime.securesms.util.views.ProgressDialog;
|
||||
import org.thoughtcrime.securesms.video.recode.VideoRecoder;
|
||||
import org.thoughtcrime.securesms.calls.CallUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -138,14 +146,13 @@ import chat.delta.util.SettableFuture;
|
||||
*/
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
implements ConversationFragment.ConversationFragmentListener,
|
||||
AttachmentManager.AttachmentListener,
|
||||
SearchView.OnQueryTextListener,
|
||||
DcEventCenter.DcEventDelegate,
|
||||
OnKeyboardShownListener,
|
||||
InputPanel.Listener,
|
||||
InputPanel.MediaListener
|
||||
{
|
||||
implements ConversationFragment.ConversationFragmentListener,
|
||||
AttachmentManager.AttachmentListener,
|
||||
SearchView.OnQueryTextListener,
|
||||
DcEventCenter.DcEventDelegate,
|
||||
OnKeyboardShownListener,
|
||||
InputPanel.Listener,
|
||||
InputPanel.MediaListener, AudioView.OnActionListener {
|
||||
private static final String TAG = ConversationActivity.class.getSimpleName();
|
||||
|
||||
public static final String ACCOUNT_ID_EXTRA = "account_id";
|
||||
@@ -185,6 +192,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
private MediaKeyboard emojiPicker;
|
||||
protected HidingLinearLayout quickAttachmentToggle;
|
||||
private InputPanel inputPanel;
|
||||
private @Nullable MediaController mediaController;
|
||||
private com.google.common.util.concurrent.ListenableFuture<MediaController> mediaControllerFuture;
|
||||
private AudioPlaybackViewModel playbackViewModel;
|
||||
|
||||
private ApplicationContext context;
|
||||
private Recipient recipient;
|
||||
@@ -217,6 +227,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
initializeActionBar();
|
||||
initializeViews();
|
||||
initializeResources();
|
||||
|
||||
playbackViewModel = new ViewModelProvider(this).get(AudioPlaybackViewModel.class);
|
||||
initializeMediaController();
|
||||
|
||||
initializeSecurity(false, isDefaultSms).addListener(new AssertedSuccessListener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
@@ -267,6 +281,36 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeMediaController() {
|
||||
SessionToken sessionToken = new SessionToken(this,
|
||||
new ComponentName(this, AudioPlaybackService.class));
|
||||
mediaControllerFuture = new MediaController.Builder(this, sessionToken)
|
||||
.buildAsync();
|
||||
mediaControllerFuture.addListener(() -> {
|
||||
try {
|
||||
mediaController = mediaControllerFuture.get();
|
||||
playbackViewModel.setMediaController(mediaController);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error connecting to audio playback service", e);
|
||||
}
|
||||
}, ContextCompat.getMainExecutor(this));
|
||||
}
|
||||
|
||||
private void addActivityContext(Bundle extras, String activityClassName) {
|
||||
if (mediaController == null) return;
|
||||
|
||||
Bundle commandArgs = new Bundle();
|
||||
commandArgs.putString("activity_class", activityClassName);
|
||||
if (extras != null) {
|
||||
commandArgs.putAll(extras);
|
||||
}
|
||||
|
||||
SessionCommand updateContextCommand =
|
||||
new SessionCommand("UPDATE_ACTIVITY_CONTEXT", Bundle.EMPTY);
|
||||
|
||||
mediaController.sendCustomCommand(updateContextCommand, commandArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
@@ -337,7 +381,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
DcHelper.getNotificationCenter(this).clearVisibleChat();
|
||||
if (isFinishing()) overridePendingTransition(R.anim.fade_scale_in, R.anim.slide_to_right);
|
||||
inputPanel.onPause();
|
||||
AudioSlidePlayer.stopAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -357,6 +400,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
DcHelper.getEventCenter(this).removeObservers(this);
|
||||
if (mediaController != null) {
|
||||
MediaController.releaseFuture(mediaControllerFuture);
|
||||
mediaController = null;
|
||||
playbackViewModel.setMediaController(null);
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -634,6 +682,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
extras.putInt(ConversationListFragment.RELOAD_LIST, 1);
|
||||
}
|
||||
|
||||
playbackViewModel.stopNonMessageAudioPlayback();
|
||||
|
||||
boolean archived = getIntent().getBooleanExtra(FROM_ARCHIVED_CHATS_EXTRA, false);
|
||||
Intent intent = new Intent(this, (archived ? ConversationListArchiveActivity.class : ConversationListActivity.class));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
@@ -1007,20 +1057,30 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
recipient = new Recipient(this, dcChat);
|
||||
glideRequests = GlideApp.with(this);
|
||||
|
||||
setComposePanelVisibility();
|
||||
setComposePanelVisibility(true);
|
||||
initializeContactRequest();
|
||||
}
|
||||
|
||||
private void setComposePanelVisibility() {
|
||||
private void setComposePanelVisibility(boolean isInitialization) {
|
||||
if (dcChat.canSend()) {
|
||||
composePanel.setVisibility(View.VISIBLE);
|
||||
attachmentManager.setHidden(false);
|
||||
inputPanel.setSubjectVisible(!dcChat.isEncrypted());
|
||||
// FIXME: disabled for now to avoid problems with chat scrolling and keyboard covering input bar
|
||||
// ViewUtil.forceApplyWindowInsets(findViewById(R.id.root_layout), true, false, true, true);
|
||||
// fragment.handleRemoveBottomInsets();
|
||||
} else {
|
||||
composePanel.setVisibility(View.GONE);
|
||||
attachmentManager.setHidden(true);
|
||||
hideSoftKeyboard();
|
||||
inputPanel.setSubjectVisible(false);
|
||||
// FIXME: disabled for now to avoid problems with chat scrolling and keyboard covering input bar
|
||||
/*
|
||||
if (isInitialization) {
|
||||
ViewUtil.forceApplyWindowInsets(findViewById(R.id.root_layout), true, false, true, false);
|
||||
fragment.handleAddBottomInsets();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1057,11 +1117,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
return new SettableFuture<>(false);
|
||||
}
|
||||
|
||||
return attachmentManager.setMedia(glideRequests, uri, null, mediaType, 0, 0, chatId);
|
||||
return attachmentManager.setMedia(glideRequests, uri, null, mediaType, 0, 0, chatId, playbackViewModel);
|
||||
}
|
||||
|
||||
private ListenableFuture<Boolean> setMedia(DcMsg msg, @NonNull MediaType mediaType) {
|
||||
return attachmentManager.setMedia(glideRequests, Uri.fromFile(new File(msg.getFile())), msg, mediaType, 0, 0, chatId);
|
||||
return attachmentManager.setMedia(glideRequests, Uri.fromFile(new File(msg.getFile())), msg, mediaType, 0, 0, chatId, playbackViewModel);
|
||||
}
|
||||
|
||||
private void addAttachmentContactInfo(int contactId) {
|
||||
@@ -1113,6 +1173,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
inputPanel.clearSubject();
|
||||
}
|
||||
|
||||
// Stop draft audio playback regardless, since it is unlikely
|
||||
// we will need background playback for drafts
|
||||
playbackViewModel.stopNonMessageAudioPlayback();
|
||||
|
||||
DcContext dcContext = DcHelper.getContext(context);
|
||||
Util.runOnAnyBackgroundThread(() -> {
|
||||
DcMsg msg = null;
|
||||
@@ -1425,6 +1489,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
// Listeners
|
||||
|
||||
@Override
|
||||
public void onPlayPauseButtonClicked(View view) {
|
||||
addActivityContext(
|
||||
this.getIntent().getExtras(),
|
||||
this.getClass().getName()
|
||||
);
|
||||
}
|
||||
|
||||
private class AttachmentTypeListener implements AttachmentTypeSelector.AttachmentClickedListener {
|
||||
@Override
|
||||
public void onClick(int type) {
|
||||
@@ -1593,7 +1665,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
dcChat = dcContext.getChat(chatId);
|
||||
titleView.setTitle(glideRequests, dcChat);
|
||||
initializeSecurity(isSecureText, isDefaultSms);
|
||||
setComposePanelVisibility();
|
||||
setComposePanelVisibility(false);
|
||||
initializeContactRequest();
|
||||
} else if ((eventId == DcContext.DC_EVENT_INCOMING_MSG
|
||||
|| eventId == DcContext.DC_EVENT_MSG_READ)
|
||||
|
||||
@@ -34,6 +34,8 @@ import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationAdapter.HeaderViewHolder;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
@@ -59,6 +61,7 @@ import java.util.Set;
|
||||
* @author Moxie Marlinspike
|
||||
*
|
||||
*/
|
||||
// FIXME: this breaks type checks, that is why there are so many casts.
|
||||
public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
extends RecyclerView.Adapter
|
||||
implements StickyHeaderDecoration.StickyHeaderAdapter<HeaderViewHolder>
|
||||
@@ -97,6 +100,8 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
private long pulseHighlightingSince = -1;
|
||||
private int lastSeenPosition = -1;
|
||||
private long lastSeen = -1;
|
||||
private AudioPlaybackViewModel playbackViewModel;
|
||||
private AudioView.OnActionListener audioPlayPauseListener;
|
||||
|
||||
protected static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public <V extends View & BindableConversationItem> ViewHolder(final @NonNull V itemView) {
|
||||
@@ -170,6 +175,14 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
return fromDb;
|
||||
}
|
||||
|
||||
public void setPlaybackViewModel(AudioPlaybackViewModel playbackViewModel) {
|
||||
this.playbackViewModel = playbackViewModel;
|
||||
}
|
||||
|
||||
public void setAudioPlayPauseListener(AudioView.OnActionListener audioPlayPauseListener) {
|
||||
this.audioPlayPauseListener = audioPlayPauseListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the message with msgId in the chat list, counted from the top
|
||||
*/
|
||||
@@ -237,7 +250,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
long elapsed = now - pulseHighlightingSince;
|
||||
boolean pulseHighlight = (positionCurrentlyPulseHighlighting == position && elapsed < PULSE_HIGHLIGHT_MILLIS);
|
||||
|
||||
holder.getItem().bind(getMsg(position), dcChat, glideRequests, batchSelected, recipient, pulseHighlight);
|
||||
holder.getItem().bind(getMsg(position), dcChat, glideRequests, batchSelected, recipient, pulseHighlight, playbackViewModel, audioPlayPauseListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
|
||||
@@ -52,6 +53,7 @@ import com.b44t.messenger.DcEvent;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationAdapter.ItemClickListener;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.reminder.DozeReminder;
|
||||
import org.thoughtcrime.securesms.connect.DcEventCenter;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
@@ -101,6 +103,7 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
private StickyHeaderDecoration dateDecoration;
|
||||
private View scrollToBottomButton;
|
||||
private View floatingLocationButton;
|
||||
private View bottomDivider;
|
||||
private AddReactionView addReactionView;
|
||||
private TextView noMessageTextView;
|
||||
private Timer reloadTimer;
|
||||
@@ -108,6 +111,8 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
public boolean isPaused;
|
||||
private Debouncer markseenDebouncer;
|
||||
private Rpc rpc;
|
||||
private boolean pendingAddBottomInsets;
|
||||
private boolean pendingRemoveBottomInsets;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
@@ -141,6 +146,7 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
floatingLocationButton = ViewUtil.findById(view, R.id.floating_location_button);
|
||||
addReactionView = ViewUtil.findById(view, R.id.add_reaction_view);
|
||||
noMessageTextView = ViewUtil.findById(view, R.id.no_messages_text_view);
|
||||
bottomDivider = ViewUtil.findById(view, R.id.bottom_divider);
|
||||
|
||||
scrollToBottomButton.setOnClickListener(v -> scrollToBottom());
|
||||
|
||||
@@ -159,18 +165,32 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
// with hardware layers, drawing may result in errors as "OpenGLRenderer: Path too large to be rendered into a texture"
|
||||
list.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
|
||||
if (pendingAddBottomInsets) {
|
||||
bottomDivider.setVisibility(View.GONE);
|
||||
ViewUtil.forceApplyWindowInsets(list, false, true, false, true);
|
||||
ViewUtil.forceApplyWindowInsetsAsMargin(scrollToBottomButton, true, true, true, true);
|
||||
pendingAddBottomInsets = false;
|
||||
}
|
||||
|
||||
if (pendingRemoveBottomInsets) {
|
||||
bottomDivider.setVisibility(View.VISIBLE);
|
||||
ViewUtil.forceApplyWindowInsets(list, false, true, false, false);
|
||||
ViewUtil.forceApplyWindowInsetsAsMargin(scrollToBottomButton, true, true, true, false);
|
||||
pendingRemoveBottomInsets = false;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle bundle) {
|
||||
super.onActivityCreated(bundle);
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
initializeResources();
|
||||
initializeListAdapter();
|
||||
}
|
||||
|
||||
private void setNoMessageText() {
|
||||
private void setNoMessageText() {
|
||||
DcChat dcChat = getListAdapter().getChat();
|
||||
if(dcChat.isMultiUser()){
|
||||
if (dcChat.isInBroadcast() || dcChat.isOutBroadcast()) {
|
||||
@@ -197,6 +217,28 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
}
|
||||
}
|
||||
|
||||
public void handleAddBottomInsets() {
|
||||
if (bottomDivider != null) {
|
||||
bottomDivider.setVisibility(View.GONE);
|
||||
ViewUtil.forceApplyWindowInsets(list, false, true, false, true);
|
||||
ViewUtil.forceApplyWindowInsetsAsMargin(scrollToBottomButton, false, false, false, true);
|
||||
pendingAddBottomInsets = false;
|
||||
} else {
|
||||
pendingAddBottomInsets = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void handleRemoveBottomInsets() {
|
||||
if (bottomDivider != null) {
|
||||
bottomDivider.setVisibility(View.VISIBLE);
|
||||
ViewUtil.forceApplyWindowInsets(list, false, true, false, false);
|
||||
ViewUtil.forceApplyWindowInsetsAsMargin(scrollToBottomButton, false, false, false, false);
|
||||
pendingRemoveBottomInsets = false;
|
||||
} else {
|
||||
pendingRemoveBottomInsets = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
DcHelper.getEventCenter(getContext()).removeObservers(this);
|
||||
@@ -291,6 +333,10 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
if (this.recipient != null && this.chatId != -1) {
|
||||
ConversationAdapter adapter = new ConversationAdapter(getActivity(), this.recipient.getChat(), GlideApp.with(this), selectionClickListener, this.recipient);
|
||||
list.setAdapter(adapter);
|
||||
AudioPlaybackViewModel playbackViewModel =
|
||||
new ViewModelProvider(requireActivity()).get(AudioPlaybackViewModel.class);
|
||||
adapter.setPlaybackViewModel(playbackViewModel);
|
||||
adapter.setAudioPlayPauseListener(((ConversationActivity) requireActivity()));
|
||||
|
||||
if (dateDecoration != null) {
|
||||
list.removeItemDecoration(dateDecoration);
|
||||
@@ -407,7 +453,14 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
}
|
||||
|
||||
public void handleClearChat() {
|
||||
handleDeleteMessages((int) chatId, getListAdapter().getMessageIds());
|
||||
AudioPlaybackViewModel playbackViewModel =
|
||||
new ViewModelProvider(requireActivity()).get(AudioPlaybackViewModel.class);
|
||||
|
||||
handleDeleteMessages(
|
||||
(int) chatId,
|
||||
getListAdapter().getMessageIds(),
|
||||
playbackViewModel::stopByIds,
|
||||
playbackViewModel::stopByIds);
|
||||
}
|
||||
|
||||
private ConversationAdapter getListAdapter() {
|
||||
@@ -940,12 +993,15 @@ public class ConversationFragment extends MessageSelectorFragment
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
hideAddReactionView();
|
||||
int itemId = item.getItemId();
|
||||
AudioPlaybackViewModel playbackViewModel =
|
||||
new ViewModelProvider(requireActivity()).get(AudioPlaybackViewModel.class);
|
||||
|
||||
if (itemId == R.id.menu_context_copy) {
|
||||
handleCopyMessage(getListAdapter().getSelectedItems());
|
||||
actionMode.finish();
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_context_delete_message) {
|
||||
handleDeleteMessages((int) chatId, getListAdapter().getSelectedItems());
|
||||
handleDeleteMessages((int) chatId, getListAdapter().getSelectedItems(), playbackViewModel::stopByIds, playbackViewModel::stopByIds);
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_context_share) {
|
||||
DcHelper.openForViewOrShare(getContext(), getSelectedMessageRecord(getListAdapter().getSelectedItems()).getId(), Intent.ACTION_SEND);
|
||||
|
||||
@@ -41,8 +41,7 @@ import com.b44t.messenger.DcChat;
|
||||
import com.b44t.messenger.DcContact;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.calls.CallUtil;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.BorderlessImageView;
|
||||
import org.thoughtcrime.securesms.components.CallItemView;
|
||||
@@ -52,6 +51,8 @@ import org.thoughtcrime.securesms.components.DocumentView;
|
||||
import org.thoughtcrime.securesms.components.QuoteView;
|
||||
import org.thoughtcrime.securesms.components.VcardView;
|
||||
import org.thoughtcrime.securesms.components.WebxdcView;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.mms.DocumentSlide;
|
||||
@@ -71,7 +72,6 @@ import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
import org.thoughtcrime.securesms.calls.CallUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -181,9 +181,11 @@ public class ConversationItem extends BaseConversationItem
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Set<DcMsg> batchSelected,
|
||||
@NonNull Recipient recipients,
|
||||
boolean pulseHighlight)
|
||||
boolean pulseHighlight,
|
||||
@Nullable AudioPlaybackViewModel playbackViewModel,
|
||||
AudioView.OnActionListener audioPlayPauseListener)
|
||||
{
|
||||
bind(messageRecord, dcChat, batchSelected, pulseHighlight, recipients);
|
||||
bindPartial(messageRecord, dcChat, batchSelected, pulseHighlight, recipients);
|
||||
this.glideRequests = glideRequests;
|
||||
this.showSender = ((dcChat.isMultiUser() || dcChat.isSelfTalk()) && !messageRecord.isOutgoing()) || messageRecord.getOverrideSenderName() != null;
|
||||
|
||||
@@ -204,7 +206,7 @@ public class ConversationItem extends BaseConversationItem
|
||||
|
||||
setGutterSizes(messageRecord, showSender);
|
||||
setMessageShape(messageRecord);
|
||||
setMediaAttributes(messageRecord, showSender);
|
||||
setMediaAttributes(messageRecord, showSender, playbackViewModel, audioPlayPauseListener);
|
||||
setBodyText(messageRecord);
|
||||
setBubbleState(messageRecord);
|
||||
setContactPhoto();
|
||||
@@ -482,24 +484,10 @@ public class ConversationItem extends BaseConversationItem
|
||||
}
|
||||
|
||||
private void setMediaAttributes(@NonNull DcMsg messageRecord,
|
||||
boolean showSender)
|
||||
boolean showSender,
|
||||
AudioPlaybackViewModel playbackViewModel,
|
||||
AudioView.OnActionListener audioPlayPauseListener)
|
||||
{
|
||||
class SetDurationListener implements AudioSlidePlayer.Listener {
|
||||
@Override
|
||||
public void onStart() {}
|
||||
|
||||
@Override
|
||||
public void onStop() {}
|
||||
|
||||
@Override
|
||||
public void onProgress(AudioSlide slide, double progress, long millis) {}
|
||||
|
||||
@Override
|
||||
public void onReceivedDuration(int millis) {
|
||||
messageRecord.lateFilingMediaSize(0,0, millis);
|
||||
audioViewStub.get().setDuration(millis);
|
||||
}
|
||||
}
|
||||
if (hasAudio(messageRecord)) {
|
||||
audioViewStub.get().setVisibility(View.VISIBLE);
|
||||
if (mediaThumbnailStub.resolved()) mediaThumbnailStub.get().setVisibility(View.GONE);
|
||||
@@ -509,15 +497,9 @@ public class ConversationItem extends BaseConversationItem
|
||||
if (vcardViewStub.resolved()) vcardViewStub.get().setVisibility(View.GONE);
|
||||
if (callViewStub.resolved()) callViewStub.get().setVisibility(View.GONE);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
int duration = messageRecord.getDuration();
|
||||
if (duration == 0) {
|
||||
AudioSlide audio = new AudioSlide(context, messageRecord);
|
||||
AudioSlidePlayer audioSlidePlayer = AudioSlidePlayer.createFor(getContext(), audio, new SetDurationListener());
|
||||
audioSlidePlayer.requestDuration();
|
||||
}
|
||||
|
||||
audioViewStub.get().setAudio(new AudioSlide(context, messageRecord), duration);
|
||||
audioViewStub.get().setPlaybackViewModel(playbackViewModel);
|
||||
audioViewStub.get().setOnActionListener(audioPlayPauseListener);
|
||||
audioViewStub.get().setAudio(new AudioSlide(context, messageRecord));
|
||||
audioViewStub.get().setOnClickListener(passthroughClickListener);
|
||||
audioViewStub.get().setOnLongClickListener(passthroughClickListener);
|
||||
audioViewStub.get().setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
|
||||
|
||||
@@ -99,6 +99,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
public static final String CLEAR_NOTIFICATIONS = "clear_notifications";
|
||||
public static final String ACCOUNT_ID_EXTRA = "account_id";
|
||||
public static final String FROM_WELCOME = "from_welcome";
|
||||
public static final String FROM_WELCOME_RAW_QR = "from_welcome_raw_qr";
|
||||
private static final int REQUEST_CODE_CONFIRM_CREDENTIALS_DELETE_PROFILE = ScreenLockUtil.REQUEST_CODE_CONFIRM_CREDENTIALS+1;
|
||||
|
||||
private ConversationListFragment conversationListFragment;
|
||||
@@ -193,6 +194,13 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
if (BuildConfig.DEBUG) checkNdkArchitecture();
|
||||
|
||||
DcHelper.maybeShowMigrationError(this);
|
||||
|
||||
String rawQrString = getIntent().getStringExtra(FROM_WELCOME_RAW_QR);
|
||||
// Launch chat directly, if coming from onboarding with a join chat/group QR
|
||||
if (rawQrString != null) {
|
||||
QrCodeHandler qrCodeHandler = new QrCodeHandler(this);
|
||||
qrCodeHandler.secureJoinByQr(rawQrString, SecurejoinSource.Scan, SecurejoinUiPath.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -621,7 +629,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
refreshAvatar();
|
||||
refreshUnreadIndicator();
|
||||
refreshTitle();
|
||||
conversationListFragment.loadChatlist();
|
||||
conversationListFragment.loadChatlistAsync();
|
||||
}
|
||||
|
||||
public void onDeleteProfile(int profileId) {
|
||||
|
||||
@@ -233,7 +233,7 @@ public class ConversationListFragment extends BaseConversationListFragment
|
||||
private final Object loadChatlistLock = new Object();
|
||||
private boolean inLoadChatlist;
|
||||
private boolean needsAnotherLoad;
|
||||
private void loadChatlistAsync() {
|
||||
public void loadChatlistAsync() {
|
||||
synchronized (loadChatlistLock) {
|
||||
needsAnotherLoad = true;
|
||||
if (inLoadChatlist) {
|
||||
@@ -260,7 +260,7 @@ public class ConversationListFragment extends BaseConversationListFragment
|
||||
});
|
||||
}
|
||||
|
||||
public void loadChatlist() {
|
||||
private void loadChatlist() {
|
||||
int listflags = 0;
|
||||
if (archive) {
|
||||
listflags |= DcContext.DC_GCL_ARCHIVED_ONLY;
|
||||
|
||||
@@ -271,12 +271,6 @@ public class ConversationListItem extends RelativeLayout
|
||||
} else {
|
||||
deliveryStatusIndicator.setNone();
|
||||
}
|
||||
|
||||
if (state == DcMsg.DC_STATE_OUT_FAILED) {
|
||||
deliveryStatusIndicator.setTint(Color.RED);
|
||||
} else {
|
||||
deliveryStatusIndicator.resetTint();
|
||||
}
|
||||
}
|
||||
|
||||
int unreadCount = thread.getUnreadCount();
|
||||
|
||||
@@ -15,6 +15,8 @@ import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.thoughtcrime.securesms.components.DeliveryStatusView;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
@@ -61,9 +63,11 @@ public class ConversationUpdateItem extends BaseConversationItem
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Set<DcMsg> batchSelected,
|
||||
@NonNull Recipient conversationRecipient,
|
||||
boolean pulseUpdate)
|
||||
boolean pulseUpdate,
|
||||
@Nullable AudioPlaybackViewModel playbackViewModel,
|
||||
AudioView.OnActionListener audioPlayPauseListener)
|
||||
{
|
||||
bind(messageRecord, dcChat, batchSelected, pulseUpdate, conversationRecipient);
|
||||
bindPartial(messageRecord, dcChat, batchSelected, pulseUpdate, conversationRecipient);
|
||||
setGenericInfoRecord(messageRecord);
|
||||
}
|
||||
|
||||
@@ -119,12 +123,6 @@ public class ConversationUpdateItem extends BaseConversationItem
|
||||
else if (messageRecord.isPreparing()) deliveryStatusView.setPreparing();
|
||||
else if (messageRecord.isPending()) deliveryStatusView.setPending();
|
||||
else deliveryStatusView.setNone();
|
||||
|
||||
if (messageRecord.isFailed()) {
|
||||
deliveryStatusView.setTint(Color.RED);
|
||||
} else {
|
||||
deliveryStatusView.setTint(textColor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
@@ -44,12 +45,14 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
import chat.delta.rpc.Rpc;
|
||||
import chat.delta.rpc.RpcException;
|
||||
|
||||
public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
implements ItemClickListener
|
||||
{
|
||||
|
||||
private static final String TAG = GroupCreateActivity.class.getSimpleName();
|
||||
public static final String EDIT_GROUP_CHAT_ID = "edit_group_chat_id";
|
||||
public static final String CREATE_BROADCAST = "create_broadcast";
|
||||
public static final String UNENCRYPTED = "unencrypted";
|
||||
@@ -63,6 +66,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
private boolean unencrypted;
|
||||
private boolean broadcast;
|
||||
private EditText groupName;
|
||||
private EditText chatDescription;
|
||||
private ListView lv;
|
||||
private ImageView avatar;
|
||||
private Bitmap avatarBmp;
|
||||
@@ -140,6 +144,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
lv = ViewUtil.findById(this, R.id.selected_contacts_list);
|
||||
avatar = ViewUtil.findById(this, R.id.avatar);
|
||||
groupName = ViewUtil.findById(this, R.id.group_name);
|
||||
chatDescription = ViewUtil.findById(this, R.id.chat_description);
|
||||
TextView chatHints = ViewUtil.findById(this, R.id.chat_hints);
|
||||
|
||||
// add padding to avoid content hidden behind system bars
|
||||
@@ -178,6 +183,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
} else if (unencrypted) {
|
||||
avatar.setVisibility(View.GONE);
|
||||
groupName.setHint(R.string.subject);
|
||||
findViewById(R.id.chat_description_container).setVisibility(View.GONE);
|
||||
chatHints.setVisibility(View.GONE);
|
||||
} else {
|
||||
chatHints.setVisibility(View.GONE);
|
||||
@@ -186,6 +192,14 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
if(isEdit()) {
|
||||
groupName.setText(dcContext.getChat(groupChatId).getName());
|
||||
lv.setVisibility(View.GONE);
|
||||
|
||||
Rpc rpc = DcHelper.getRpc(this);
|
||||
try {
|
||||
String description = rpc.getChatDescription(rpc.getSelectedAccountId(), groupChatId);
|
||||
chatDescription.setText(description);
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "RPC error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,22 +275,22 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
|
||||
private void createGroup(String groupName) {
|
||||
if (broadcast) {
|
||||
try {
|
||||
groupChatId = DcHelper.getRpc(this).createBroadcast(dcContext.getAccountId(), groupName);
|
||||
} catch (RpcException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
Rpc rpc = DcHelper.getRpc(this);
|
||||
int accId;
|
||||
try {
|
||||
accId = rpc.getSelectedAccountId();
|
||||
if (broadcast) {
|
||||
groupChatId = rpc.createBroadcast(accId, groupName);
|
||||
} else if (unencrypted) {
|
||||
groupChatId = rpc.createGroupChatUnencrypted(accId, groupName);
|
||||
} else {
|
||||
groupChatId = rpc.createGroupChat(accId, groupName, false);
|
||||
}
|
||||
} else if (unencrypted) {
|
||||
try {
|
||||
groupChatId = DcHelper.getRpc(this).createGroupChatUnencrypted(dcContext.getAccountId(), groupName);
|
||||
} catch (RpcException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
groupChatId = dcContext.createGroupChat(groupName);
|
||||
|
||||
rpc.setChatDescription(accId, groupChatId, getChatDescription());
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "RPC error", e);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int contactId : getAdapter().getContacts()) {
|
||||
@@ -307,6 +321,14 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
dcContext.setChatName(groupChatId, groupName);
|
||||
|
||||
Rpc rpc = DcHelper.getRpc(this);
|
||||
String description = getChatDescription();
|
||||
try {
|
||||
rpc.setChatDescription(rpc.getSelectedAccountId(), groupChatId, description);
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "RPC error", e);
|
||||
}
|
||||
|
||||
if (avatarChanged) AvatarHelper.setGroupAvatar(this, groupChatId, avatarBmp);
|
||||
|
||||
attachmentManager.cleanup();
|
||||
@@ -331,6 +353,10 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
return ret;
|
||||
}
|
||||
|
||||
private @Nullable String getChatDescription() {
|
||||
return chatDescription.getText() != null ? chatDescription.getText().toString().trim() : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
@@ -63,6 +63,8 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import chat.delta.rpc.Rpc;
|
||||
import chat.delta.rpc.RpcException;
|
||||
@@ -79,6 +81,7 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
|
||||
private ImageView avatar;
|
||||
private EditText name;
|
||||
private TextView invitationText;
|
||||
private TextView privacyPolicyBtn;
|
||||
private Button signUpBtn;
|
||||
|
||||
@@ -86,7 +89,11 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
private boolean imageLoaded;
|
||||
private String providerHost;
|
||||
private String providerQrData;
|
||||
private String rawQrData;
|
||||
private DcLot parsedQrData;
|
||||
private boolean isDcLogin;
|
||||
private boolean isContactInvitation;
|
||||
private boolean isGroupInvitation;
|
||||
|
||||
private AttachmentManager attachmentManager;
|
||||
private Bitmap avatarBmp;
|
||||
@@ -96,6 +103,8 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
|
||||
private DcContext dcContext;
|
||||
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
@@ -206,17 +215,31 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
|
||||
private void setProviderFromQr(String rawQr) {
|
||||
DcLot qrParsed = dcContext.checkQr(rawQr);
|
||||
boolean isDcLogin = qrParsed.getState() == DcContext.DC_QR_LOGIN;
|
||||
if (isDcLogin || qrParsed.getState() == DcContext.DC_QR_ACCOUNT) {
|
||||
this.isDcLogin = isDcLogin;
|
||||
providerHost = qrParsed.getText1();
|
||||
providerQrData = rawQr;
|
||||
updateProvider();
|
||||
} else {
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(R.string.qraccount_qr_code_cannot_be_used)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_LOGIN:
|
||||
isDcLogin = true; // Intentional fall-through
|
||||
case DcContext.DC_QR_ACCOUNT:
|
||||
providerHost = qrParsed.getText1();
|
||||
providerQrData = rawQr;
|
||||
updateProvider();
|
||||
break;
|
||||
case DcContext.DC_QR_ASK_VERIFYCONTACT:
|
||||
isContactInvitation = true;
|
||||
rawQrData = rawQr;
|
||||
parsedQrData = qrParsed;
|
||||
updateProvider();
|
||||
break;
|
||||
case DcContext.DC_QR_ASK_VERIFYGROUP:
|
||||
isGroupInvitation = true;
|
||||
rawQrData = rawQr;
|
||||
parsedQrData = qrParsed;
|
||||
updateProvider();
|
||||
break;
|
||||
default:
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(R.string.qraccount_qr_code_cannot_be_used)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +283,7 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
DcHelper.getEventCenter(this).removeObservers(this);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
@@ -311,6 +335,7 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
private void initializeResources() {
|
||||
this.avatar = findViewById(R.id.avatar);
|
||||
this.name = findViewById(R.id.name_text);
|
||||
this.invitationText = findViewById(R.id.invitation_label);
|
||||
this.privacyPolicyBtn = findViewById(R.id.privacy_policy_button);
|
||||
this.signUpBtn = findViewById(R.id.signup_button);
|
||||
|
||||
@@ -358,6 +383,19 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
privacyPolicyBtn.setText(TextUtil.markAsExternal(
|
||||
getString(R.string.instant_onboarding_agree_instance, providerHost)));
|
||||
}
|
||||
|
||||
if (parsedQrData != null) {
|
||||
if (isContactInvitation) {
|
||||
String name = dcContext.getContact(parsedQrData.getId()).getDisplayName();
|
||||
invitationText.setText(this.getString(R.string.instant_onboarding_contact_info, name));
|
||||
invitationText.setVisibility(View.VISIBLE);
|
||||
} else if (isGroupInvitation) {
|
||||
String groupName = parsedQrData.getText1();
|
||||
invitationText.setText(this.getString(R.string.instant_onboarding_group_info, groupName));
|
||||
invitationText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,11 +457,14 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), ConversationListActivity.class);
|
||||
intent.putExtra(ConversationListActivity.FROM_WELCOME, true);
|
||||
if (isContactInvitation || isGroupInvitation) {
|
||||
intent.putExtra(ConversationListActivity.FROM_WELCOME_RAW_QR, rawQrData);
|
||||
}
|
||||
|
||||
startActivity(intent);
|
||||
finishAffinity();
|
||||
}
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void createProfile() {
|
||||
if (TextUtils.isEmpty(this.name.getText())) {
|
||||
Toast.makeText(this, R.string.please_enter_name, Toast.LENGTH_LONG).show();
|
||||
@@ -431,37 +472,31 @@ public class InstantOnboardingActivity extends BaseActionBarActivity implements
|
||||
}
|
||||
final String name = this.name.getText().toString();
|
||||
|
||||
new AsyncTask<Void, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
Context context = InstantOnboardingActivity.this;
|
||||
DcHelper.set(context, DcHelper.CONFIG_DISPLAY_NAME, name);
|
||||
executor.execute(() -> {
|
||||
Context context = InstantOnboardingActivity.this;
|
||||
DcHelper.set(context, DcHelper.CONFIG_DISPLAY_NAME, name);
|
||||
|
||||
if (avatarChanged) {
|
||||
try {
|
||||
AvatarHelper.setSelfAvatar(InstantOnboardingActivity.this, avatarBmp);
|
||||
Prefs.setProfileAvatarId(InstantOnboardingActivity.this, new SecureRandom().nextInt());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
boolean result = true;
|
||||
if (avatarChanged) {
|
||||
try {
|
||||
AvatarHelper.setSelfAvatar(InstantOnboardingActivity.this, avatarBmp);
|
||||
Prefs.setProfileAvatarId(InstantOnboardingActivity.this, new SecureRandom().nextInt());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
result = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute(Boolean result) {
|
||||
super.onPostExecute(result);
|
||||
|
||||
if (result) {
|
||||
boolean finalResult = result;
|
||||
runOnUiThread(() -> {
|
||||
if (finalResult) {
|
||||
attachmentManager.cleanup();
|
||||
startQrAccountCreation(providerQrData);
|
||||
} else {
|
||||
Toast.makeText(InstantOnboardingActivity.this, R.string.error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void startQrAccountCreation(String qrCode)
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
@@ -12,6 +13,7 @@ import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.b44t.messenger.DcChat;
|
||||
@@ -57,10 +59,14 @@ public abstract class MessageSelectorFragment
|
||||
}
|
||||
|
||||
protected void handleDeleteMessages(int chatId, final Set<DcMsg> messageRecords) {
|
||||
handleDeleteMessages(chatId, DcMsg.msgSetToIds(messageRecords));
|
||||
handleDeleteMessages(chatId, DcMsg.msgSetToIds(messageRecords), null, null);
|
||||
}
|
||||
|
||||
protected void handleDeleteMessages(int chatId, final int[] messageIds) {
|
||||
protected void handleDeleteMessages(int chatId, final Set<DcMsg> messageRecords, Consumer<int[]> deleteForMeListenerExtra, Consumer<int[]> deleteForAllListenerExtra) {
|
||||
handleDeleteMessages(chatId, DcMsg.msgSetToIds(messageRecords), deleteForMeListenerExtra, deleteForAllListenerExtra);
|
||||
}
|
||||
|
||||
protected void handleDeleteMessages(int chatId, final int[] messageIds, Consumer<int[]> deleteForMeListenerExtra, Consumer<int[]> deleteForAllListenerExtra) {
|
||||
DcContext dcContext = DcHelper.getContext(getContext());
|
||||
DcChat dcChat = dcContext.getChat(chatId);
|
||||
boolean canDeleteForAll = true;
|
||||
@@ -79,20 +85,24 @@ public abstract class MessageSelectorFragment
|
||||
String text = getActivity().getResources().getQuantityString(R.plurals.ask_delete_messages, messageIds.length, messageIds.length);
|
||||
int positiveBtnLabel = dcChat.isSelfTalk() ? R.string.delete : R.string.delete_for_me;
|
||||
|
||||
DialogInterface.OnClickListener deleteForMeListener = (d, which) -> {
|
||||
Util.runOnAnyBackgroundThread(() -> dcContext.deleteMsgs(messageIds));
|
||||
if (actionMode != null) actionMode.finish();
|
||||
if (deleteForMeListenerExtra != null) deleteForMeListenerExtra.accept(messageIds);
|
||||
};
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity())
|
||||
.setMessage(text)
|
||||
.setCancelable(true)
|
||||
.setNeutralButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(positiveBtnLabel, (d, which) -> {
|
||||
Util.runOnAnyBackgroundThread(() -> dcContext.deleteMsgs(messageIds));
|
||||
if (actionMode != null) actionMode.finish();
|
||||
});
|
||||
.setPositiveButton(positiveBtnLabel, deleteForMeListener);
|
||||
|
||||
if(canDeleteForAll) {
|
||||
builder.setNegativeButton(R.string.delete_for_everyone, (d, which) -> {
|
||||
DialogInterface.OnClickListener deleteForAllListener = (d, which) -> {
|
||||
Util.runOnAnyBackgroundThread(() -> dcContext.sendDeleteRequest(messageIds));
|
||||
if (actionMode != null) actionMode.finish();
|
||||
});
|
||||
if (deleteForAllListenerExtra != null) deleteForAllListenerExtra.accept(messageIds);
|
||||
};
|
||||
builder.setNegativeButton(R.string.delete_for_everyone, deleteForAllListener);
|
||||
AlertDialog dialog = builder.show();
|
||||
Util.redButton(dialog, AlertDialog.BUTTON_NEGATIVE);
|
||||
Util.redPositiveButton(dialog);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -30,8 +31,13 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import chat.delta.rpc.Rpc;
|
||||
import chat.delta.rpc.RpcException;
|
||||
|
||||
public class ProfileAdapter extends RecyclerView.Adapter
|
||||
{
|
||||
private static final String TAG = ProfileAdapter.class.getSimpleName();
|
||||
|
||||
public static final int ITEM_AVATAR = 10;
|
||||
public static final int ITEM_DIVIDER = 20;
|
||||
public static final int ITEM_SIGNATURE = 25;
|
||||
@@ -195,7 +201,7 @@ public class ProfileAdapter extends RecyclerView.Adapter
|
||||
}
|
||||
else if(holder.itemView instanceof ProfileStatusItem) {
|
||||
ProfileStatusItem item = (ProfileStatusItem) holder.itemView;
|
||||
item.setOnLongClickListener(view -> {clickListener.onStatusLongClicked(); return true;});
|
||||
item.setOnLongClickListener(view -> {clickListener.onStatusLongClicked(dcContact == null); return true;});
|
||||
item.set(data.label);
|
||||
}
|
||||
else if(holder.itemView instanceof ProfileAvatarItem) {
|
||||
@@ -230,7 +236,7 @@ public class ProfileAdapter extends RecyclerView.Adapter
|
||||
|
||||
public interface ItemClickListener {
|
||||
void onSettingsClicked(int settingsId);
|
||||
void onStatusLongClicked();
|
||||
void onStatusLongClicked(boolean isMultiUser);
|
||||
void onSharedChatClicked(int chatId);
|
||||
void onMemberClicked(int contactId);
|
||||
void onMemberLongClicked(int contactId);
|
||||
@@ -278,8 +284,21 @@ public class ProfileAdapter extends RecyclerView.Adapter
|
||||
|
||||
itemData.add(new ItemData(ITEM_AVATAR, null, 0));
|
||||
|
||||
if (isSelfTalk || dcContact != null && !dcContact.getStatus().isEmpty()) {
|
||||
itemDataStatusText = isSelfTalk ? context.getString(R.string.saved_messages_explain) : dcContact.getStatus();
|
||||
if (isSelfTalk) {
|
||||
itemDataStatusText = context.getString(R.string.saved_messages_explain);
|
||||
} else if (dcContact != null) {
|
||||
itemDataStatusText = dcContact.getStatus();
|
||||
} else if (dcChat != null && dcChat.isEncrypted()) {
|
||||
// Load group or channel description
|
||||
try {
|
||||
Rpc rpc = DcHelper.getRpc(context);
|
||||
itemDataStatusText = rpc.getChatDescription(rpc.getSelectedAccountId(), dcChat.getId());
|
||||
} catch (RpcException e) {
|
||||
Log.e(TAG, "RPC error", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!itemDataStatusText.isEmpty()) {
|
||||
itemData.add(new ItemData(ITEM_SIGNATURE, itemDataStatusText, 0));
|
||||
} else {
|
||||
itemData.add(new ItemData(ITEM_DIVIDER, null, 0));
|
||||
|
||||
@@ -140,10 +140,10 @@ public class ProfileFragment extends Fragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusLongClicked() {
|
||||
public void onStatusLongClicked(boolean isMultiUser) {
|
||||
Context context = requireContext();
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.pref_default_status_label)
|
||||
.setTitle(isMultiUser? R.string.chat_description : R.string.pref_default_status_label)
|
||||
.setItems(new CharSequence[]{
|
||||
context.getString(R.string.menu_copy_to_clipboard)
|
||||
},
|
||||
|
||||
@@ -77,7 +77,7 @@ public class WebViewActivity extends PassphraseRequiredActionBarActivity
|
||||
findViewById(R.id.status_bar_background).setBackgroundResource(R.drawable.search_toolbar_shadow);
|
||||
} else {
|
||||
// add padding to avoid content hidden behind system bars
|
||||
ViewUtil.applyWindowInsets(findViewById(R.id.content_container), true, true, true, true, true);
|
||||
ViewUtil.applyWindowInsets(findViewById(R.id.content_container), true, true, true, true, true, false);
|
||||
}
|
||||
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
package org.thoughtcrime.securesms.audio;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.DefaultLoadControl;
|
||||
import com.google.android.exoplayer2.DefaultRenderersFactory;
|
||||
import com.google.android.exoplayer2.LoadControl;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.PlaybackException;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.guava.Optional;
|
||||
import org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class AudioSlidePlayer {
|
||||
|
||||
private static final String TAG = AudioSlidePlayer.class.getSimpleName();
|
||||
|
||||
private static @NonNull Optional<AudioSlidePlayer> playing = Optional.absent();
|
||||
|
||||
private final @NonNull Context context;
|
||||
private final @NonNull AudioSlide slide;
|
||||
private final @NonNull Handler progressEventHandler;
|
||||
|
||||
private @NonNull WeakReference<Listener> listener;
|
||||
private @Nullable SimpleExoPlayer mediaPlayer;
|
||||
private @Nullable SimpleExoPlayer durationCalculator;
|
||||
|
||||
public synchronized static AudioSlidePlayer createFor(@NonNull Context context,
|
||||
@NonNull AudioSlide slide,
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
if (playing.isPresent() && playing.get().getAudioSlide().equals(slide)) {
|
||||
playing.get().setListener(listener);
|
||||
return playing.get();
|
||||
} else {
|
||||
return new AudioSlidePlayer(context, slide, listener);
|
||||
}
|
||||
}
|
||||
|
||||
private AudioSlidePlayer(@NonNull Context context,
|
||||
@NonNull AudioSlide slide,
|
||||
@NonNull Listener listener)
|
||||
{
|
||||
this.context = context;
|
||||
this.slide = slide;
|
||||
this.listener = new WeakReference<>(listener);
|
||||
this.progressEventHandler = new ProgressEventHandler(this);
|
||||
}
|
||||
|
||||
public void requestDuration() {
|
||||
try {
|
||||
LoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).build();
|
||||
durationCalculator = new SimpleExoPlayer.Builder(context, new DefaultRenderersFactory(context))
|
||||
.setTrackSelector(new DefaultTrackSelector(context))
|
||||
.setLoadControl(loadControl)
|
||||
.build();
|
||||
durationCalculator.setPlayWhenReady(false);
|
||||
durationCalculator.addListener(new Player.Listener() {
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
if (playbackState == Player.STATE_READY) {
|
||||
Util.runOnMain(() -> {
|
||||
synchronized (AudioSlidePlayer.this) {
|
||||
if (durationCalculator == null) return;
|
||||
Log.d(TAG, "request duration " + durationCalculator.getDuration());
|
||||
getListener().onReceivedDuration(Long.valueOf(durationCalculator.getDuration()).intValue());
|
||||
durationCalculator.release();
|
||||
durationCalculator.removeListener(this);
|
||||
durationCalculator = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
durationCalculator.prepare(createMediaSource(slide.getUri()));
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, e);
|
||||
getListener().onReceivedDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void play(final double progress) throws IOException {
|
||||
play(progress, false);
|
||||
}
|
||||
|
||||
private void play(final double progress, boolean earpiece) throws IOException {
|
||||
if (this.mediaPlayer != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (slide.getUri() == null) {
|
||||
throw new IOException("Slide has no URI!");
|
||||
}
|
||||
|
||||
LoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).build();
|
||||
this.mediaPlayer = new SimpleExoPlayer.Builder(context, new DefaultRenderersFactory(context))
|
||||
.setTrackSelector(new DefaultTrackSelector(context))
|
||||
.setLoadControl(loadControl)
|
||||
.build();
|
||||
|
||||
mediaPlayer.prepare(createMediaSource(slide.getUri()));
|
||||
mediaPlayer.setPlayWhenReady(true);
|
||||
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setContentType(earpiece ? C.AUDIO_CONTENT_TYPE_SPEECH : C.AUDIO_CONTENT_TYPE_MUSIC)
|
||||
.setUsage(earpiece ? C.USAGE_VOICE_COMMUNICATION : C.USAGE_MEDIA)
|
||||
.build(), false);
|
||||
mediaPlayer.addListener(new Player.Listener() {
|
||||
|
||||
boolean started = false;
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
Log.d(TAG, "onPlayerStateChanged(" + playWhenReady + ", " + playbackState + ")");
|
||||
switch (playbackState) {
|
||||
case Player.STATE_READY:
|
||||
|
||||
Log.i(TAG, "onPrepared() " + mediaPlayer.getBufferedPercentage() + "% buffered");
|
||||
synchronized (AudioSlidePlayer.this) {
|
||||
if (mediaPlayer == null) return;
|
||||
Log.d(TAG, "DURATION: " + mediaPlayer.getDuration());
|
||||
|
||||
if (started) {
|
||||
Log.d(TAG, "Already started. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
if (progress > 0) {
|
||||
mediaPlayer.seekTo((long) (mediaPlayer.getDuration() * progress));
|
||||
}
|
||||
|
||||
setPlaying(AudioSlidePlayer.this);
|
||||
}
|
||||
|
||||
keepScreenOn(true);
|
||||
notifyOnStart();
|
||||
progressEventHandler.sendEmptyMessage(0);
|
||||
break;
|
||||
|
||||
case Player.STATE_ENDED:
|
||||
Log.i(TAG, "onComplete");
|
||||
synchronized (AudioSlidePlayer.this) {
|
||||
getListener().onReceivedDuration(Long.valueOf(mediaPlayer.getDuration()).intValue());
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
|
||||
keepScreenOn(false);
|
||||
notifyOnStop();
|
||||
progressEventHandler.removeMessages(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
Log.w(TAG, "MediaPlayer Error: " + error);
|
||||
|
||||
synchronized (AudioSlidePlayer.this) {
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
|
||||
notifyOnStop();
|
||||
progressEventHandler.removeMessages(0);
|
||||
|
||||
// Failed to play media file, maybe another app can handle it
|
||||
int msgId = getAudioSlide().getDcMsgId();
|
||||
DcHelper.openForViewOrShare(context, msgId, Intent.ACTION_VIEW);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MediaSource createMediaSource(@NonNull Uri uri) {
|
||||
DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(context, "GenericUserAgent", null);
|
||||
AttachmentDataSourceFactory attachmentDataSourceFactory = new AttachmentDataSourceFactory(defaultDataSourceFactory);
|
||||
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true);
|
||||
|
||||
return new ProgressiveMediaSource.Factory(attachmentDataSourceFactory, extractorsFactory)
|
||||
.createMediaSource(MediaItem.fromUri(uri));
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
Log.i(TAG, "Stop called!");
|
||||
|
||||
keepScreenOn(false);
|
||||
removePlaying(this);
|
||||
|
||||
if (this.mediaPlayer != null) {
|
||||
this.mediaPlayer.stop();
|
||||
this.mediaPlayer.release();
|
||||
}
|
||||
|
||||
this.mediaPlayer = null;
|
||||
}
|
||||
|
||||
public static void stopAll() {
|
||||
if (playing.isPresent()) {
|
||||
synchronized (AudioSlidePlayer.class) {
|
||||
if (playing.isPresent()) {
|
||||
playing.get().stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(@NonNull Listener listener) {
|
||||
this.listener = new WeakReference<>(listener);
|
||||
|
||||
if (this.mediaPlayer != null && this.mediaPlayer.getPlaybackState() == Player.STATE_READY) {
|
||||
notifyOnStart();
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull AudioSlide getAudioSlide() {
|
||||
return slide;
|
||||
}
|
||||
|
||||
|
||||
private Pair<Double, Integer> getProgress() {
|
||||
if (mediaPlayer == null || mediaPlayer.getCurrentPosition() <= 0 || mediaPlayer.getDuration() <= 0) {
|
||||
return new Pair<>(0D, 0);
|
||||
} else {
|
||||
return new Pair<>((double) mediaPlayer.getCurrentPosition() / (double) mediaPlayer.getDuration(),
|
||||
(int) mediaPlayer.getCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyOnStart() {
|
||||
Util.runOnMain(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getListener().onStart();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyOnStop() {
|
||||
Util.runOnMain(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getListener().onStop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyOnProgress(final double progress, final long millis) {
|
||||
Util.runOnMain(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getListener().onProgress(slide, progress, millis);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private @NonNull Listener getListener() {
|
||||
Listener listener = this.listener.get();
|
||||
|
||||
if (listener != null) return listener;
|
||||
else return new Listener() {
|
||||
@Override
|
||||
public void onStart() {}
|
||||
@Override
|
||||
public void onStop() {}
|
||||
@Override
|
||||
public void onProgress(AudioSlide slide, double progress, long millis) {}
|
||||
@Override
|
||||
public void onReceivedDuration(int millis) {}
|
||||
};
|
||||
}
|
||||
|
||||
public void keepScreenOn(boolean keepOn) {
|
||||
if (context instanceof Activity) {
|
||||
if (keepOn) {
|
||||
((Activity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
} else {
|
||||
((Activity) context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized static void setPlaying(@NonNull AudioSlidePlayer player) {
|
||||
if (playing.isPresent() && playing.get() != player) {
|
||||
playing.get().notifyOnStop();
|
||||
playing.get().stop();
|
||||
}
|
||||
|
||||
playing = Optional.of(player);
|
||||
}
|
||||
|
||||
private synchronized static void removePlaying(@NonNull AudioSlidePlayer player) {
|
||||
if (playing.isPresent() && playing.get() == player) {
|
||||
playing = Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
void onStart();
|
||||
void onStop();
|
||||
void onProgress(AudioSlide slide, double progress, long millis);
|
||||
void onReceivedDuration(int millis);
|
||||
}
|
||||
|
||||
private static class ProgressEventHandler extends Handler {
|
||||
|
||||
private final WeakReference<AudioSlidePlayer> playerReference;
|
||||
|
||||
private ProgressEventHandler(@NonNull AudioSlidePlayer player) {
|
||||
this.playerReference = new WeakReference<>(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
AudioSlidePlayer player = playerReference.get();
|
||||
|
||||
if (player == null || player.mediaPlayer == null || !isPlayerActive(player.mediaPlayer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Pair<Double, Integer> progress = player.getProgress();
|
||||
player.notifyOnProgress(progress.first, progress.second);
|
||||
sendEmptyMessageDelayed(0, 50);
|
||||
}
|
||||
|
||||
private boolean isPlayerActive(@NonNull SimpleExoPlayer player) {
|
||||
return player.getPlaybackState() == Player.STATE_READY || player.getPlaybackState() == Player.STATE_BUFFERING;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioFocusRequest;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class AudioView extends FrameLayout implements AudioSlidePlayer.Listener {
|
||||
|
||||
private static final String TAG = AudioView.class.getSimpleName();
|
||||
|
||||
private final @NonNull AnimatingToggle controlToggle;
|
||||
private final @NonNull ImageView playButton;
|
||||
private final @NonNull ImageView pauseButton;
|
||||
private final @NonNull SeekBar seekBar;
|
||||
private final @NonNull TextView timestamp;
|
||||
private final @NonNull TextView title;
|
||||
private final @NonNull View mask;
|
||||
|
||||
private @Nullable AudioSlidePlayer audioSlidePlayer;
|
||||
private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener;
|
||||
private int backwardsCounter;
|
||||
|
||||
public AudioView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AudioView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AudioView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
inflate(context, R.layout.audio_view, this);
|
||||
|
||||
this.controlToggle = (AnimatingToggle) findViewById(R.id.control_toggle);
|
||||
this.playButton = (ImageView) findViewById(R.id.play);
|
||||
this.pauseButton = (ImageView) findViewById(R.id.pause);
|
||||
this.seekBar = (SeekBar) findViewById(R.id.seek);
|
||||
this.timestamp = (TextView) findViewById(R.id.timestamp);
|
||||
this.title = (TextView) findViewById(R.id.title);
|
||||
this.mask = findViewById(R.id.interception_mask);
|
||||
|
||||
this.timestamp.setText("00:00");
|
||||
|
||||
this.playButton.setOnClickListener(new PlayClickedListener());
|
||||
this.pauseButton.setOnClickListener(new PauseClickedListener());
|
||||
this.seekBar.setOnSeekBarChangeListener(new SeekBarModifiedListener());
|
||||
|
||||
this.playButton.setImageDrawable(context.getDrawable(R.drawable.play_icon));
|
||||
this.pauseButton.setImageDrawable(context.getDrawable(R.drawable.pause_icon));
|
||||
this.playButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
|
||||
this.pauseButton.setBackground(context.getDrawable(R.drawable.ic_circle_fill_white_48dp));
|
||||
|
||||
setTint(getContext().getResources().getColor(R.color.audio_icon));
|
||||
}
|
||||
|
||||
public void setAudio(final @NonNull AudioSlide audio, int duration)
|
||||
{
|
||||
controlToggle.displayQuick(playButton);
|
||||
seekBar.setEnabled(true);
|
||||
seekBar.setProgress(0);
|
||||
audioSlidePlayer = AudioSlidePlayer.createFor(getContext(), audio, this);
|
||||
timestamp.setText(DateUtils.getFormatedDuration(duration));
|
||||
|
||||
if(audio.asAttachment().isVoiceNote() || !audio.getFileName().isPresent()) {
|
||||
title.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
title.setText(audio.getFileName().get());
|
||||
title.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnClickListener(OnClickListener listener) {
|
||||
super.setOnClickListener(listener);
|
||||
this.mask.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnLongClickListener(OnLongClickListener listener) {
|
||||
super.setOnLongClickListener(listener);
|
||||
this.mask.setOnLongClickListener(listener);
|
||||
this.playButton.setOnLongClickListener(listener);
|
||||
this.pauseButton.setOnLongClickListener(listener);
|
||||
}
|
||||
|
||||
public void togglePlay() {
|
||||
if (this.playButton.getVisibility() == View.VISIBLE) {
|
||||
playButton.performClick();
|
||||
} else {
|
||||
pauseButton.performClick();
|
||||
}
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
String desc;
|
||||
if (this.title.getVisibility() == View.VISIBLE) {
|
||||
desc = getContext().getString(R.string.audio);
|
||||
} else {
|
||||
desc = getContext().getString(R.string.voice_message);
|
||||
}
|
||||
desc += "\n" + this.timestamp.getText();
|
||||
if (title.getVisibility() == View.VISIBLE) {
|
||||
desc += "\n" + this.title.getText();
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
if (getProgress()==0)
|
||||
this.timestamp.setText(DateUtils.getFormatedDuration(duration));
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (this.audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) {
|
||||
this.audioSlidePlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedDuration(int millis) {
|
||||
this.timestamp.setText(DateUtils.getFormatedDuration(millis));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (this.pauseButton.getVisibility() != View.VISIBLE) {
|
||||
togglePlayToPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (this.playButton.getVisibility() != View.VISIBLE) {
|
||||
togglePauseToPlay();
|
||||
}
|
||||
|
||||
if (seekBar.getProgress() + 5 >= seekBar.getMax()) {
|
||||
backwardsCounter = 4;
|
||||
onProgress(audioSlidePlayer.getAudioSlide(), 0.0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void disablePlayer(boolean disable) {
|
||||
this.mask.setVisibility(disable? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(AudioSlide slide, double progress, long millis) {
|
||||
if (!audioSlidePlayer.getAudioSlide().equals(slide)) {
|
||||
return;
|
||||
}
|
||||
int seekProgress = (int) Math.floor(progress * this.seekBar.getMax());
|
||||
|
||||
if (seekProgress > seekBar.getProgress() || backwardsCounter > 3) {
|
||||
backwardsCounter = 0;
|
||||
this.seekBar.setProgress(seekProgress);
|
||||
if (millis != -1) {
|
||||
this.timestamp.setText(DateUtils.getFormatedDuration(millis));
|
||||
}
|
||||
} else {
|
||||
backwardsCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTint(int foregroundTint) {
|
||||
this.playButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
|
||||
this.pauseButton.setBackgroundTintList(ColorStateList.valueOf(foregroundTint));
|
||||
|
||||
this.seekBar.getProgressDrawable().setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN);
|
||||
|
||||
this.seekBar.getThumb().setColorFilter(foregroundTint, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
public void getSeekBarGlobalVisibleRect(@NonNull Rect rect) {
|
||||
seekBar.getGlobalVisibleRect(rect);
|
||||
}
|
||||
|
||||
private double getProgress() {
|
||||
if (this.seekBar.getProgress() <= 0 || this.seekBar.getMax() <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return (double)this.seekBar.getProgress() / (double)this.seekBar.getMax();
|
||||
}
|
||||
}
|
||||
|
||||
private void togglePlayToPause() {
|
||||
controlToggle.displayQuick(pauseButton);
|
||||
|
||||
AnimatedVectorDrawable playToPauseDrawable = (AnimatedVectorDrawable) getContext().getDrawable(R.drawable.play_to_pause_animation);
|
||||
pauseButton.setImageDrawable(playToPauseDrawable);
|
||||
playToPauseDrawable.start();
|
||||
}
|
||||
|
||||
private void togglePauseToPlay() {
|
||||
controlToggle.displayQuick(playButton);
|
||||
|
||||
AnimatedVectorDrawable pauseToPlayDrawable = (AnimatedVectorDrawable) getContext().getDrawable(R.drawable.pause_to_play_animation);
|
||||
playButton.setImageDrawable(pauseToPlayDrawable);
|
||||
pauseToPlayDrawable.start();
|
||||
}
|
||||
|
||||
private class PlayClickedListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
Log.w(TAG, "playbutton onClick");
|
||||
if (audioSlidePlayer != null) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
if (audioFocusChangeListener == null) {
|
||||
audioFocusChangeListener = focusChange -> {
|
||||
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
|
||||
pauseButton.performClick();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
AudioAttributes playbackAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
AudioFocusRequest focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
|
||||
.setAudioAttributes(playbackAttributes)
|
||||
.setAcceptsDelayedFocusGain(false)
|
||||
.setWillPauseWhenDucked(false)
|
||||
.setOnAudioFocusChangeListener(audioFocusChangeListener)
|
||||
.build();
|
||||
|
||||
AudioManager audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.requestAudioFocus(focusRequest);
|
||||
}
|
||||
|
||||
togglePlayToPause();
|
||||
audioSlidePlayer.play(getProgress());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PauseClickedListener implements View.OnClickListener {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Log.w(TAG, "pausebutton onClick");
|
||||
if (audioSlidePlayer != null) {
|
||||
togglePauseToPlay();
|
||||
audioSlidePlayer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SeekBarModifiedListener implements SeekBar.OnSeekBarChangeListener {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
|
||||
|
||||
@Override
|
||||
public synchronized void onStartTrackingTouch(SeekBar seekBar) {
|
||||
if (audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) {
|
||||
audioSlidePlayer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onStopTrackingTouch(SeekBar seekBar) {
|
||||
try {
|
||||
if (audioSlidePlayer != null && pauseButton.getVisibility() == View.VISIBLE) {
|
||||
audioSlidePlayer.play(getProgress());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,8 +67,10 @@ public class CallItemView extends FrameLayout {
|
||||
title.setText(R.string.canceled_call);
|
||||
} else if (callInfo.state instanceof CallState.Declined) {
|
||||
title.setText(R.string.declined_call);
|
||||
} else if (callInfo.hasVideo) {
|
||||
title.setText(isOutgoing? R.string.outgoing_video_call : R.string.incoming_video_call);
|
||||
} else {
|
||||
title.setText(isOutgoing? R.string.outgoing_call : R.string.incoming_call);
|
||||
title.setText(isOutgoing? R.string.outgoing_audio_call : R.string.incoming_audio_call);
|
||||
}
|
||||
|
||||
icon.setImageResource(callInfo.hasVideo? R.drawable.ic_videocam_white_24dp : R.drawable.baseline_call_24);
|
||||
|
||||
@@ -151,12 +151,6 @@ public class ConversationItemFooter extends LinearLayout {
|
||||
else if (messageRecord.isDelivered()) deliveryStatusView.setSent();
|
||||
else if (messageRecord.isPreparing()) deliveryStatusView.setPreparing();
|
||||
else deliveryStatusView.setPending();
|
||||
|
||||
if (messageRecord.isFailed()) {
|
||||
deliveryStatusView.setTint(Color.RED);
|
||||
} else {
|
||||
deliveryStatusView.setTint(textColor); // Reset the color to the standard color (because the footer is re-used in a RecyclerView)
|
||||
}
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
||||
+20
-2
@@ -11,6 +11,9 @@ import android.widget.ImageView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RemovableEditableMediaView extends FrameLayout {
|
||||
|
||||
private final @NonNull ImageView remove;
|
||||
@@ -19,6 +22,7 @@ public class RemovableEditableMediaView extends FrameLayout {
|
||||
private final int removeSize;
|
||||
|
||||
private @Nullable View current;
|
||||
private final List<OnClickListener> removeClickListeners = new ArrayList<>();
|
||||
|
||||
public RemovableEditableMediaView(Context context) {
|
||||
this(context, null);
|
||||
@@ -72,8 +76,22 @@ public class RemovableEditableMediaView extends FrameLayout {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setRemoveClickListener(View.OnClickListener listener) {
|
||||
this.remove.setOnClickListener(listener);
|
||||
public void addRemoveClickListener(View.OnClickListener listener) {
|
||||
removeClickListeners.add(listener);
|
||||
updateRemoveClickListener();
|
||||
}
|
||||
|
||||
public void removeRemoveClickListener(View.OnClickListener listener) {
|
||||
removeClickListeners.remove(listener);
|
||||
updateRemoveClickListener();
|
||||
}
|
||||
|
||||
private void updateRemoveClickListener() {
|
||||
this.remove.setOnClickListener(v -> {
|
||||
for (OnClickListener listener : removeClickListeners) {
|
||||
listener.onClick(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setEditClickListener(View.OnClickListener listener) {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.thoughtcrime.securesms.components.audioplay;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class AudioPlaybackState {
|
||||
private final int msgId;
|
||||
private final @Nullable Uri audioUri;
|
||||
private final PlaybackStatus status;
|
||||
private final long currentPosition;
|
||||
private final long duration;
|
||||
|
||||
public enum PlaybackStatus {
|
||||
IDLE,
|
||||
LOADING,
|
||||
PLAYING,
|
||||
PAUSED,
|
||||
ERROR
|
||||
}
|
||||
|
||||
public AudioPlaybackState(int msgId,
|
||||
@Nullable Uri audioUri,
|
||||
PlaybackStatus status,
|
||||
long currentPosition,
|
||||
long duration) {
|
||||
this.msgId = msgId;
|
||||
this.audioUri = audioUri;
|
||||
this.status = status;
|
||||
this.currentPosition = currentPosition;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public static AudioPlaybackState idle() {
|
||||
return new AudioPlaybackState(0, null, PlaybackStatus.IDLE, 0, 0);
|
||||
}
|
||||
|
||||
public int getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Uri getAudioUri() {
|
||||
return audioUri;
|
||||
}
|
||||
|
||||
public PlaybackStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public long getCurrentPosition() {
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return duration;
|
||||
}
|
||||
}
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
package org.thoughtcrime.securesms.components.audioplay;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.session.MediaController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
|
||||
public class AudioPlaybackViewModel extends ViewModel {
|
||||
private static final String TAG = AudioPlaybackViewModel.class.getSimpleName();
|
||||
|
||||
private static final int NON_MESSAGE_AUDIO_MSG_ID = 0; // Audios not attached to a message doesn't have message id.
|
||||
|
||||
private final MutableLiveData<AudioPlaybackState> playbackState;
|
||||
|
||||
private final MutableLiveData<Map<Integer, Long>> durations = new MutableLiveData<>(new HashMap<>());
|
||||
private final Set<Integer> extractionInProgress = new HashSet<>();
|
||||
private final ExecutorService extractionExecutor = Executors.newFixedThreadPool(2);
|
||||
|
||||
private @Nullable MediaController mediaController;
|
||||
private final Handler handler;
|
||||
private boolean isUserSeeking = false;
|
||||
|
||||
public AudioPlaybackViewModel() {
|
||||
playbackState = new MutableLiveData<>(AudioPlaybackState.idle());
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
public LiveData<AudioPlaybackState> getPlaybackState() {
|
||||
return playbackState;
|
||||
}
|
||||
|
||||
public void setMediaController(@Nullable MediaController controller) {
|
||||
this.mediaController = controller;
|
||||
if (mediaController != null && mediaController.isPlaying()) {
|
||||
startUpdateProgress();
|
||||
}
|
||||
updateCurrentState(true);
|
||||
setupPlayerListener();
|
||||
}
|
||||
|
||||
// Public methods
|
||||
public void loadAudioAndPlay(int msgId, Uri audioUri) {
|
||||
if (mediaController == null) return;
|
||||
|
||||
// Set media item if we have a different audio.
|
||||
if (isDifferentAudio(msgId, audioUri)) {
|
||||
updateState(msgId, audioUri, AudioPlaybackState.PlaybackStatus.LOADING, 0, 0);
|
||||
|
||||
MediaItem mediaItem = new MediaItem.Builder()
|
||||
.setMediaId(String.valueOf(msgId))
|
||||
.setUri(audioUri)
|
||||
.build();
|
||||
mediaController.setMediaItem(mediaItem);
|
||||
mediaController.prepare();
|
||||
}
|
||||
|
||||
play(msgId, audioUri);
|
||||
}
|
||||
private boolean isSameAudio(int msgId, Uri audioUri) {
|
||||
return !isDifferentAudio(msgId, audioUri);
|
||||
}
|
||||
|
||||
private boolean isDifferentAudio(int msgId, Uri audioUri) {
|
||||
AudioPlaybackState currentState = playbackState.getValue();
|
||||
|
||||
return currentState != null && (
|
||||
msgId != currentState.getMsgId() ||
|
||||
currentState.getAudioUri() == null ||
|
||||
currentState.getAudioUri() != null && !currentState.getAudioUri().equals(audioUri));
|
||||
}
|
||||
|
||||
public LiveData<Map<Integer, Long>> getDurations() {
|
||||
return durations;
|
||||
}
|
||||
|
||||
public void ensureDurationLoaded(Context context, int msgId, Uri audioUri) {
|
||||
// Check cache
|
||||
Map<Integer, Long> currentDurations = durations.getValue();
|
||||
if (currentDurations != null && currentDurations.containsKey(msgId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check extracting
|
||||
synchronized (extractionInProgress) {
|
||||
if (extractionInProgress.contains(msgId)) {
|
||||
return;
|
||||
}
|
||||
extractionInProgress.add(msgId);
|
||||
}
|
||||
|
||||
// Extract in background
|
||||
extractionExecutor.execute(() -> {
|
||||
long duration = extractDurationFromAudio(context, audioUri);
|
||||
|
||||
handler.post(() -> {
|
||||
Map<Integer, Long> updatedDurations = new HashMap<>(durations.getValue());
|
||||
updatedDurations.put(msgId, duration);
|
||||
durations.setValue(updatedDurations);
|
||||
});
|
||||
|
||||
synchronized (extractionInProgress) {
|
||||
extractionInProgress.remove(msgId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private long extractDurationFromAudio(Context context, Uri audioUri) {
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
retriever.setDataSource(context, audioUri);
|
||||
String durationStr = retriever.extractMetadata(
|
||||
MediaMetadataRetriever.METADATA_KEY_DURATION
|
||||
);
|
||||
return durationStr != null ? Long.parseLong(durationStr) : 0;
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
} finally {
|
||||
try {
|
||||
retriever.release();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void pause(int msgId, Uri audioUri) {
|
||||
if (mediaController != null && isSameAudio(msgId, audioUri)) {
|
||||
mediaController.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public void play(int msgId, Uri audioUri) {
|
||||
if (mediaController != null && isSameAudio(msgId, audioUri)) {
|
||||
mediaController.play();
|
||||
}
|
||||
}
|
||||
|
||||
public void seekTo(long position, int msgId, Uri audioUri) {
|
||||
if (mediaController != null && isSameAudio(msgId, audioUri)) {
|
||||
mediaController.seekTo(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(int msgId, Uri audioUri) {
|
||||
if (mediaController != null && isSameAudio(msgId, audioUri)) {
|
||||
mediaController.stop();
|
||||
stopUpdateProgress();
|
||||
playbackState.setValue(AudioPlaybackState.idle());
|
||||
}
|
||||
}
|
||||
|
||||
public void stopNonMessageAudioPlayback() {
|
||||
stopByIds(NON_MESSAGE_AUDIO_MSG_ID);
|
||||
}
|
||||
|
||||
// A special method for deleting message, where we only use message Ids
|
||||
public void stopByIds(int... msgIds) {
|
||||
AudioPlaybackState currentState = playbackState.getValue();
|
||||
|
||||
if (mediaController != null && currentState != null) {
|
||||
for (int msgId : msgIds) {
|
||||
if (msgId == currentState.getMsgId()) {
|
||||
mediaController.stop();
|
||||
stopUpdateProgress();
|
||||
playbackState.setValue(AudioPlaybackState.idle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setUserSeeking(boolean isUserSeeking) {
|
||||
this.isUserSeeking = isUserSeeking;
|
||||
}
|
||||
|
||||
// Private methods
|
||||
private void setupPlayerListener() {
|
||||
if (mediaController == null) return;
|
||||
|
||||
mediaController.addListener(new Player.Listener() {
|
||||
@Override
|
||||
public void onEvents(Player player, Player.Events events) {
|
||||
if (events.containsAny(Player.EVENT_IS_PLAYING_CHANGED)) {
|
||||
if (player.isPlaying()) {
|
||||
startUpdateProgress();
|
||||
} else {
|
||||
stopUpdateProgress();
|
||||
}
|
||||
updateCurrentState(false);
|
||||
}
|
||||
if (events.containsAny(Player.EVENT_PLAYBACK_STATE_CHANGED)) {
|
||||
if (player.getPlaybackState() == Player.STATE_READY) {
|
||||
updateCurrentState(false);
|
||||
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||
// This is to prevent automatically playing after the audio
|
||||
// has been play to the end once, then user dragged the seek bar again
|
||||
mediaController.setPlayWhenReady(false);
|
||||
}
|
||||
}
|
||||
if (events.containsAny(Player.EVENT_PLAYER_ERROR)) {
|
||||
updateCurrentAudioState(AudioPlaybackState.PlaybackStatus.ERROR, 0, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateCurrentState(boolean queryPlaying) {
|
||||
if (mediaController == null) return;
|
||||
|
||||
AudioPlaybackState.PlaybackStatus status;
|
||||
if (mediaController.isPlaying()) {
|
||||
status = AudioPlaybackState.PlaybackStatus.PLAYING;
|
||||
} else if (mediaController.getPlaybackState() == Player.STATE_READY
|
||||
|| mediaController.getPlaybackState() == Player.STATE_ENDED) {
|
||||
status = AudioPlaybackState.PlaybackStatus.PAUSED;
|
||||
} else {
|
||||
status = AudioPlaybackState.PlaybackStatus.IDLE;
|
||||
}
|
||||
|
||||
Uri currentUri = null;
|
||||
int currentMsgId = 0;
|
||||
if (playbackState.getValue() != null) {
|
||||
currentMsgId = playbackState.getValue().getMsgId();
|
||||
currentUri = playbackState.getValue().getAudioUri();
|
||||
}
|
||||
if (queryPlaying || playbackState.getValue() == null) {
|
||||
MediaItem item = mediaController.getCurrentMediaItem();
|
||||
if (item != null) {
|
||||
try {
|
||||
currentMsgId = Integer.parseInt(item.mediaId);
|
||||
} catch (NumberFormatException e) {
|
||||
Log.w(TAG, "Invalid integer", e);
|
||||
}
|
||||
if (item.localConfiguration != null) {
|
||||
currentUri = item.localConfiguration.uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateState(
|
||||
currentMsgId,
|
||||
currentUri,
|
||||
status,
|
||||
mediaController.getCurrentPosition(),
|
||||
mediaController.getDuration());
|
||||
}
|
||||
|
||||
private void updateState(int msgId,
|
||||
Uri audioUri,
|
||||
AudioPlaybackState.PlaybackStatus status,
|
||||
long position,
|
||||
long duration) {
|
||||
// Sanitize longs
|
||||
if (position < 0 || position > Integer.MAX_VALUE) {
|
||||
position = 0;
|
||||
}
|
||||
if (duration < 0 || duration > Integer.MAX_VALUE) {
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
playbackState.setValue(new AudioPlaybackState(
|
||||
msgId, audioUri, status, position, duration
|
||||
));
|
||||
}
|
||||
|
||||
private void updateCurrentAudioState(AudioPlaybackState.PlaybackStatus status,
|
||||
long position,
|
||||
long duration) {
|
||||
AudioPlaybackState current = playbackState.getValue();
|
||||
|
||||
if (current != null) {
|
||||
updateState(current.getMsgId(), current.getAudioUri(), status, position, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// Progress tracking
|
||||
private final Runnable progressRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mediaController != null && mediaController.isPlaying() && !isUserSeeking) {
|
||||
updateCurrentAudioState(AudioPlaybackState.PlaybackStatus.PLAYING,
|
||||
mediaController.getCurrentPosition(),
|
||||
mediaController.getDuration());
|
||||
handler.postDelayed(this, 100);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void startUpdateProgress() {
|
||||
stopUpdateProgress();
|
||||
handler.post(progressRunnable);
|
||||
}
|
||||
|
||||
private void stopUpdateProgress() {
|
||||
handler.removeCallbacks(progressRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
stopUpdateProgress();
|
||||
extractionExecutor.shutdown();
|
||||
super.onCleared();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
package org.thoughtcrime.securesms.components.audioplay;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
|
||||
import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class AudioView extends FrameLayout {
|
||||
|
||||
private static final String TAG = AudioView.class.getSimpleName();
|
||||
|
||||
private final @NonNull ImageView playPauseButton;
|
||||
private final AnimatedVectorDrawableCompat playToPauseDrawable;
|
||||
private final AnimatedVectorDrawableCompat pauseToPlayDrawable;
|
||||
private final Drawable playDrawable;
|
||||
private final Drawable pauseDrawable;
|
||||
private final Animatable2Compat.AnimationCallback animationCallback;
|
||||
private final @NonNull SeekBar seekBar;
|
||||
private final @NonNull TextView timestamp;
|
||||
private final @NonNull TextView title;
|
||||
private final @NonNull View mask;
|
||||
private OnActionListener listener;
|
||||
|
||||
private int msgId = -1;
|
||||
private Uri audioUri;
|
||||
private int progress;
|
||||
private int duration;
|
||||
private AudioPlaybackViewModel viewModel;
|
||||
private final Observer<AudioPlaybackState> stateObserver = this::onPlaybackStateChanged;
|
||||
private final Observer<Map<Integer, Long>> durationObserver = this::onDurationsChanged;
|
||||
private boolean isPlaying;
|
||||
|
||||
public AudioView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AudioView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AudioView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
inflate(context, R.layout.audio_view, this);
|
||||
|
||||
this.playPauseButton = findViewById(R.id.play_pause);
|
||||
this.seekBar = findViewById(R.id.seek);
|
||||
this.timestamp = findViewById(R.id.timestamp);
|
||||
this.title = findViewById(R.id.title);
|
||||
this.mask = findViewById(R.id.interception_mask);
|
||||
|
||||
updateTimestampsAndSeekBar();
|
||||
|
||||
// Load drawables once
|
||||
this.playToPauseDrawable = AnimatedVectorDrawableCompat.create(
|
||||
getContext(), R.drawable.play_to_pause_animation);
|
||||
this.pauseToPlayDrawable = AnimatedVectorDrawableCompat.create(
|
||||
getContext(), R.drawable.pause_to_play_animation);
|
||||
this.playDrawable = AppCompatResources.getDrawable(getContext(), R.drawable.play_icon);
|
||||
this.pauseDrawable = AppCompatResources.getDrawable(getContext(), R.drawable.pause_icon);
|
||||
|
||||
this.animationCallback = new Animatable2Compat.AnimationCallback() {
|
||||
@Override
|
||||
public void onAnimationEnd(Drawable drawable) {
|
||||
Drawable endState = isPlaying ? pauseDrawable : playDrawable;
|
||||
playPauseButton.setImageDrawable(endState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
setupControls();
|
||||
}
|
||||
|
||||
private void setupControls() {
|
||||
// Set up observer in a very specific case when the view is detached and then re-attached,
|
||||
// but binding from adapter has not happened yet
|
||||
if (viewModel != null) {
|
||||
viewModel.getPlaybackState().removeObserver(stateObserver);
|
||||
viewModel.getPlaybackState().observeForever(stateObserver);
|
||||
|
||||
viewModel.getDurations().removeObserver(durationObserver);
|
||||
viewModel.getDurations().observeForever(durationObserver);
|
||||
}
|
||||
|
||||
playPauseButton.setOnClickListener(v -> {
|
||||
Log.w(TAG, "playPauseButton onClick");
|
||||
|
||||
if (viewModel == null || audioUri == null) return;
|
||||
|
||||
AudioPlaybackState state = viewModel.getPlaybackState().getValue();
|
||||
|
||||
if (state != null && msgId == state.getMsgId() && audioUri.equals(state.getAudioUri())) {
|
||||
// Same audio
|
||||
if (state.getStatus() == AudioPlaybackState.PlaybackStatus.PLAYING) {
|
||||
viewModel.pause(msgId, audioUri);
|
||||
} else {
|
||||
viewModel.play(msgId, audioUri);
|
||||
}
|
||||
} else {
|
||||
// Different audio
|
||||
// Note: they can be the same *physical* file, but in different messages
|
||||
viewModel.loadAudioAndPlay(msgId, audioUri);
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.onPlayPauseButtonClicked(v);
|
||||
}
|
||||
});
|
||||
|
||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
AudioView.this.progress = progress;
|
||||
updateTimestampsAndSeekBar();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
viewModel.setUserSeeking(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
viewModel.setUserSeeking(false);
|
||||
viewModel.seekTo(seekBar.getProgress(), msgId, audioUri);
|
||||
}
|
||||
});
|
||||
|
||||
if (playToPauseDrawable != null) {
|
||||
playToPauseDrawable.registerAnimationCallback(animationCallback);
|
||||
}
|
||||
if (pauseToPlayDrawable != null) {
|
||||
pauseToPlayDrawable.registerAnimationCallback(animationCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
if (viewModel != null) {
|
||||
viewModel.getPlaybackState().removeObserver(stateObserver);
|
||||
viewModel.getDurations().removeObserver(durationObserver);
|
||||
}
|
||||
if (playToPauseDrawable != null) {
|
||||
playToPauseDrawable.clearAnimationCallbacks();
|
||||
}
|
||||
if (pauseToPlayDrawable != null) {
|
||||
pauseToPlayDrawable.clearAnimationCallbacks();
|
||||
}
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
public void setPlaybackViewModel(AudioPlaybackViewModel viewModel) {
|
||||
if (this.viewModel != null) {
|
||||
this.viewModel.getPlaybackState().removeObserver(stateObserver);
|
||||
this.viewModel.getDurations().removeObserver(durationObserver);
|
||||
}
|
||||
|
||||
// ViewModel is used directly for simplicity, since there is no reuse yet
|
||||
this.viewModel = viewModel;
|
||||
|
||||
if (viewModel != null) {
|
||||
viewModel.getPlaybackState().observeForever(stateObserver);
|
||||
viewModel.getDurations().observeForever(durationObserver);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAudio(final @NonNull AudioSlide audio)
|
||||
{
|
||||
msgId = audio.getDcMsgId();
|
||||
audioUri = audio.getUri();
|
||||
playPauseButton.setImageDrawable(playDrawable);
|
||||
|
||||
seekBar.setEnabled(true);
|
||||
|
||||
// Get duration
|
||||
Map<Integer, Long> durations = viewModel.getDurations().getValue();
|
||||
if (durations != null && durations.containsKey(msgId)) {
|
||||
this.duration = Math.toIntExact(durations.get(msgId));
|
||||
updateTimestampsAndSeekBar();
|
||||
} else {
|
||||
viewModel.ensureDurationLoaded(getContext(), msgId, audioUri);
|
||||
}
|
||||
|
||||
if(audio.asAttachment().isVoiceNote() || !audio.getFileName().isPresent()) {
|
||||
title.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
title.setText(audio.getFileName().get());
|
||||
title.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnClickListener(OnClickListener listener) {
|
||||
super.setOnClickListener(listener);
|
||||
this.mask.setOnClickListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnLongClickListener(OnLongClickListener listener) {
|
||||
super.setOnLongClickListener(listener);
|
||||
this.mask.setOnLongClickListener(listener);
|
||||
this.playPauseButton.setOnLongClickListener(listener);
|
||||
}
|
||||
|
||||
public int getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public Uri getAudioUri() {
|
||||
return audioUri;
|
||||
}
|
||||
|
||||
public interface OnActionListener {
|
||||
void onPlayPauseButtonClicked(View view);
|
||||
}
|
||||
|
||||
public void setOnActionListener(OnActionListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void togglePlay() {
|
||||
playPauseButton.performClick();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
String desc;
|
||||
if (this.title.getVisibility() == View.VISIBLE) {
|
||||
desc = getContext().getString(R.string.audio);
|
||||
} else {
|
||||
desc = getContext().getString(R.string.voice_message);
|
||||
}
|
||||
desc += "\n" + this.timestamp.getText();
|
||||
if (title.getVisibility() == View.VISIBLE) {
|
||||
desc += "\n" + this.title.getText();
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
private void updateProgress(AudioPlaybackState state) {
|
||||
int duration = Math.toIntExact(state.getDuration());
|
||||
int position = Math.toIntExact(state.getCurrentPosition());
|
||||
|
||||
if (duration > 0) {
|
||||
this.progress = position;
|
||||
this.duration = duration;
|
||||
updateTimestampsAndSeekBar();
|
||||
}
|
||||
}
|
||||
|
||||
public void disablePlayer(boolean disable) {
|
||||
this.mask.setVisibility(disable? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void getSeekBarGlobalVisibleRect(@NonNull Rect rect) {
|
||||
seekBar.getGlobalVisibleRect(rect);
|
||||
}
|
||||
|
||||
private void togglePlayPause(boolean expectedPlaying) {
|
||||
isPlaying = expectedPlaying;
|
||||
Drawable expectedDrawable = expectedPlaying ? pauseDrawable : playDrawable;
|
||||
|
||||
boolean isAnimating = false;
|
||||
Drawable currentDrawable = playPauseButton.getDrawable();
|
||||
if (currentDrawable instanceof AnimatedVectorDrawableCompat) {
|
||||
isAnimating = ((AnimatedVectorDrawableCompat) currentDrawable).isRunning();
|
||||
}
|
||||
if (!isAnimating && playPauseButton.getDrawable() != expectedDrawable) {
|
||||
AnimatedVectorDrawableCompat animDrawable = expectedPlaying ? playToPauseDrawable : pauseToPlayDrawable;
|
||||
String contentDescription = getContext().getString(
|
||||
expectedPlaying ? R.string.menu_pause : R.string.menu_play);
|
||||
|
||||
if (animDrawable != null) {
|
||||
playPauseButton.setImageDrawable(animDrawable);
|
||||
playPauseButton.setContentDescription(contentDescription);
|
||||
|
||||
animDrawable.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onPlaybackStateChanged(AudioPlaybackState state) {
|
||||
if (audioUri == null || state == null) return;
|
||||
|
||||
// Check if this state is about this message
|
||||
boolean isThisMessage = msgId == state.getMsgId() && audioUri.equals(state.getAudioUri());
|
||||
|
||||
if (isThisMessage) {
|
||||
updateUIForPlaybackState(state);
|
||||
} else {
|
||||
togglePlayPause(false);
|
||||
|
||||
// Also clear progress to avoid confusion
|
||||
this.progress = 0;
|
||||
updateTimestampsAndSeekBar();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUIForPlaybackState(AudioPlaybackState state) {
|
||||
switch (state.getStatus()) {
|
||||
case PLAYING:
|
||||
togglePlayPause(true);
|
||||
updateProgress(state);
|
||||
break;
|
||||
|
||||
case PAUSED:
|
||||
togglePlayPause(false);
|
||||
updateProgress(state);
|
||||
break;
|
||||
|
||||
case LOADING:
|
||||
case ERROR:
|
||||
// No special handling yet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void onDurationsChanged(Map<Integer, Long> durations) {
|
||||
AudioPlaybackState state = viewModel.getPlaybackState().getValue();
|
||||
|
||||
// When there is no playback happening, msgId can be -1 and audioUri is null
|
||||
if (state != null &&
|
||||
msgId >= 0 && msgId == state.getMsgId() &&
|
||||
audioUri != null && audioUri.equals(state.getAudioUri())) {
|
||||
return; // Is playing this message
|
||||
}
|
||||
|
||||
Long duration = durations.get(msgId);
|
||||
if (duration != null && seekBar.getMax() <= 100) {
|
||||
this.duration = Math.toIntExact(duration);
|
||||
updateTimestampsAndSeekBar();
|
||||
seekBar.setMax(this.duration);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTimestampsAndSeekBar() {
|
||||
String progressText = DateUtils.getFormatedDuration(progress);
|
||||
String durationText = DateUtils.getFormatedDuration(duration);
|
||||
timestamp.setText(String.format("%s / %s", progressText, durationText));
|
||||
seekBar.setProgress(progress);
|
||||
seekBar.setMax(duration);
|
||||
}
|
||||
}
|
||||
@@ -132,7 +132,7 @@ public class DcHelper {
|
||||
dcContext.setStockTranslation(68, context.getString(R.string.device_talk));
|
||||
dcContext.setStockTranslation(69, context.getString(R.string.saved_messages));
|
||||
dcContext.setStockTranslation(70, context.getString(R.string.device_talk_explain));
|
||||
dcContext.setStockTranslation(71, context.getString(R.string.device_welcome_message, "https://i.delta.chat/#0A45953086F0C166D3BAF1D4BB2025496E4C2704&x=MVPi07rQBEmHO4FRb3brpwDe&j=n8mkKqu42WAKKUCx1bQOVh23&s=RxuXoa0vhvTs0QLsWM45Ues0&a=adb%40arcanechat.me&n=adb&b=ArcaneChat+Channel"));
|
||||
dcContext.setStockTranslation(71, context.getString(R.string.device_welcome_message, "https://i.delta.chat/#0A45953086F0C166D3BAF1D4BB2025496E4C2704&x=3KvvQZfzU4t-9u5s0PF3USGp&i=X-QDZ681F6Plz_uBu47CKdg4&s=IwE4LraLDcdPBW597wB7DBnI&a=arcanechat%40arcanechat.me&n=ArcaneChat&g=ArcaneChat+Community"));
|
||||
dcContext.setStockTranslation(73, context.getString(R.string.systemmsg_subject_for_new_contact));
|
||||
dcContext.setStockTranslation(74, context.getString(R.string.systemmsg_failed_sending_to));
|
||||
dcContext.setStockTranslation(84, context.getString(R.string.configuration_failed_with_error));
|
||||
@@ -210,8 +210,6 @@ public class DcHelper {
|
||||
dcContext.setStockTranslation(178, context.getString(R.string.member_x_removed));
|
||||
dcContext.setStockTranslation(190, context.getString(R.string.secure_join_wait));
|
||||
dcContext.setStockTranslation(193, context.getString(R.string.donate_device_msg));
|
||||
dcContext.setStockTranslation(194, context.getString(R.string.outgoing_call));
|
||||
dcContext.setStockTranslation(195, context.getString(R.string.incoming_call));
|
||||
dcContext.setStockTranslation(196, context.getString(R.string.declined_call));
|
||||
dcContext.setStockTranslation(197, context.getString(R.string.canceled_call));
|
||||
dcContext.setStockTranslation(198, context.getString(R.string.missed_call));
|
||||
@@ -223,6 +221,12 @@ public class DcHelper {
|
||||
dcContext.setStockTranslation(220, context.getString(R.string.proxy_enabled));
|
||||
dcContext.setStockTranslation(221, context.getString(R.string.proxy_enabled_hint));
|
||||
dcContext.setStockTranslation(230, context.getString(R.string.chat_unencrypted_explanation));
|
||||
dcContext.setStockTranslation(232, context.getString(R.string.outgoing_audio_call));
|
||||
dcContext.setStockTranslation(233, context.getString(R.string.outgoing_video_call));
|
||||
dcContext.setStockTranslation(234, context.getString(R.string.incoming_audio_call));
|
||||
dcContext.setStockTranslation(235, context.getString(R.string.incoming_video_call));
|
||||
dcContext.setStockTranslation(240, context.getString(R.string.chat_description_changed_by_you));
|
||||
dcContext.setStockTranslation(241, context.getString(R.string.chat_description_changed_by_other));
|
||||
}
|
||||
|
||||
public static File getImexDir() {
|
||||
|
||||
@@ -49,13 +49,13 @@ import org.thoughtcrime.securesms.WebxdcActivity;
|
||||
import org.thoughtcrime.securesms.WebxdcStoreActivity;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment;
|
||||
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.components.DocumentView;
|
||||
import org.thoughtcrime.securesms.components.RemovableEditableMediaView;
|
||||
import org.thoughtcrime.securesms.components.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.components.VcardView;
|
||||
import org.thoughtcrime.securesms.components.WebxdcView;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioPlaybackViewModel;
|
||||
import org.thoughtcrime.securesms.components.audioplay.AudioView;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.geolocation.DcLocationManager;
|
||||
@@ -121,7 +121,7 @@ public class AttachmentManager {
|
||||
//this.mapView = ViewUtil.findById(root, R.id.attachment_location);
|
||||
this.removableMediaView = ViewUtil.findById(root, R.id.removable_media_view);
|
||||
|
||||
removableMediaView.setRemoveClickListener(new RemoveButtonListener());
|
||||
removableMediaView.addRemoveClickListener(new RemoveButtonListener());
|
||||
removableMediaView.setEditClickListener(new EditButtonListener());
|
||||
thumbnail.setOnClickListener(new ThumbnailClickListener());
|
||||
}
|
||||
@@ -152,8 +152,6 @@ public class AttachmentManager {
|
||||
|
||||
markGarbage(getSlideUri());
|
||||
slide = Optional.absent();
|
||||
|
||||
audioView.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +233,8 @@ public class AttachmentManager {
|
||||
@NonNull final MediaType mediaType,
|
||||
final int width,
|
||||
final int height,
|
||||
final int chatId)
|
||||
final int chatId,
|
||||
AudioPlaybackViewModel playbackViewModel)
|
||||
{
|
||||
inflateStub();
|
||||
|
||||
@@ -285,26 +284,12 @@ public class AttachmentManager {
|
||||
setAttachmentPresent(true);
|
||||
|
||||
if (slide.hasAudio()) {
|
||||
class SetDurationListener implements AudioSlidePlayer.Listener {
|
||||
@Override
|
||||
public void onStart() {}
|
||||
|
||||
@Override
|
||||
public void onStop() {}
|
||||
|
||||
@Override
|
||||
public void onProgress(AudioSlide slide, double progress, long millis) {}
|
||||
|
||||
@Override
|
||||
public void onReceivedDuration(int millis) {
|
||||
((AudioView) removableMediaView.getCurrent()).setDuration(millis);
|
||||
}
|
||||
}
|
||||
AudioSlidePlayer audioSlidePlayer = AudioSlidePlayer.createFor(context, (AudioSlide) slide, new SetDurationListener());
|
||||
audioSlidePlayer.requestDuration();
|
||||
|
||||
audioView.setAudio((AudioSlide) slide, 0);
|
||||
audioView.setPlaybackViewModel(playbackViewModel);
|
||||
audioView.setAudio((AudioSlide) slide);
|
||||
removableMediaView.display(audioView, false);
|
||||
removableMediaView.addRemoveClickListener(v -> {
|
||||
playbackViewModel.stop(audioView.getMsgId(), audioView.getAudioUri());
|
||||
});
|
||||
result.set(true);
|
||||
} else if (slide.isVcard()) {
|
||||
vcardView.setVcard(glideRequests, (VcardSlide)slide, DcHelper.getRpc(context));
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.thoughtcrime.securesms.qr;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.journeyapps.barcodescanner.BarcodeResult;
|
||||
import com.journeyapps.barcodescanner.CaptureManager;
|
||||
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
|
||||
|
||||
public class CustomCaptureManager extends CaptureManager {
|
||||
|
||||
private OnResultInterceptor interceptor;
|
||||
|
||||
public CustomCaptureManager(Activity activity, DecoratedBarcodeView barcodeView) {
|
||||
super(activity, barcodeView);
|
||||
}
|
||||
|
||||
public void setResultInterceptor(OnResultInterceptor interceptor) {
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void returnResult(BarcodeResult rawResult) {
|
||||
if (interceptor != null) {
|
||||
interceptor.onResult(rawResult, () -> {
|
||||
super.returnResult(rawResult);
|
||||
});
|
||||
} else {
|
||||
super.returnResult(rawResult);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnResultInterceptor {
|
||||
void onResult(BarcodeResult result, Runnable finishCallback);
|
||||
}
|
||||
}
|
||||
@@ -325,25 +325,29 @@ public class QrCodeHandler {
|
||||
}
|
||||
builder.setMessage(msg);
|
||||
builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
||||
try {
|
||||
int newChatId = DcHelper.getRpc(activity).secureJoinWithUxInfo(dcContext.getAccountId(), qrRawString, source, uipath);
|
||||
if (newChatId == 0) throw new Exception("Securejoin failed to create a chat");
|
||||
|
||||
Intent intent = new Intent(activity, ConversationActivity.class);
|
||||
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, newChatId);
|
||||
activity.startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
AlertDialog.Builder builder1 = new AlertDialog.Builder(activity);
|
||||
builder1.setMessage(e.getMessage());
|
||||
builder1.setPositiveButton(android.R.string.ok, null);
|
||||
builder1.create().show();
|
||||
}
|
||||
secureJoinByQr(qrRawString, source, uipath);
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
}
|
||||
|
||||
public void addRelay(String qrData) {
|
||||
public void secureJoinByQr(String qrRawString, SecurejoinSource source, SecurejoinUiPath uipath) {
|
||||
try {
|
||||
int newChatId = DcHelper.getRpc(activity).secureJoinWithUxInfo(dcContext.getAccountId(), qrRawString, source, uipath);
|
||||
if (newChatId == 0) throw new Exception("Securejoin failed to create a chat");
|
||||
|
||||
Intent intent = new Intent(activity, ConversationActivity.class);
|
||||
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, newChatId);
|
||||
activity.startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
AlertDialog.Builder builder1 = new AlertDialog.Builder(activity);
|
||||
builder1.setMessage(e.getMessage());
|
||||
builder1.setPositiveButton(android.R.string.ok, null);
|
||||
builder1.create().show();
|
||||
}
|
||||
}
|
||||
|
||||
public void addRelay(String qrData) {
|
||||
ProgressDialog progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setMessage(activity.getResources().getString(R.string.one_moment));
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
|
||||
@@ -10,8 +10,12 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.journeyapps.barcodescanner.CaptureManager;
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcLot;
|
||||
import com.journeyapps.barcodescanner.CompoundBarcodeView;
|
||||
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity;
|
||||
@@ -26,10 +30,12 @@ public class RegistrationQrActivity extends BaseActionBarActivity {
|
||||
public static final String ADD_AS_SECOND_DEVICE_EXTRA = "add_as_second_device";
|
||||
public static final String QRDATA_EXTRA = "qrdata";
|
||||
|
||||
private CaptureManager capture;
|
||||
private CustomCaptureManager capture;
|
||||
|
||||
private CompoundBarcodeView barcodeScannerView;
|
||||
|
||||
private DcContext dcContext;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -66,6 +72,8 @@ public class RegistrationQrActivity extends BaseActionBarActivity {
|
||||
.onAnyResult(this::handleQrScanWithPermissions)
|
||||
.onAnyDenied(this::handleQrScanWithDeniedPermission)
|
||||
.execute();
|
||||
|
||||
dcContext = DcHelper.getContext(this);
|
||||
}
|
||||
|
||||
private void handleQrScanWithPermissions() {
|
||||
@@ -89,23 +97,70 @@ public class RegistrationQrActivity extends BaseActionBarActivity {
|
||||
DcHelper.openHelp(this, "#multiclient");
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_paste) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(QRDATA_EXTRA, Util.getTextFromClipboard(this));
|
||||
setResult(Activity.RESULT_OK, intent);
|
||||
finish();
|
||||
String rawQr = Util.getTextFromClipboard(this);
|
||||
|
||||
Runnable okCallback = () -> {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(QRDATA_EXTRA, rawQr);
|
||||
setResult(Activity.RESULT_OK, intent);
|
||||
finish();
|
||||
};
|
||||
|
||||
showConfirmDialog(rawQr, okCallback, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
private void showConfirmDialog(String rawQr, @NonNull Runnable okCallback, @Nullable Runnable cancelCallback) {
|
||||
DcLot qrParsed = dcContext.checkQr(rawQr);
|
||||
|
||||
String dialogMsg = "";
|
||||
if (qrParsed.getState() == DcContext.DC_QR_ASK_VERIFYCONTACT) {
|
||||
String name = dcContext.getContact(qrParsed.getId()).getDisplayName();
|
||||
dialogMsg = getString(R.string.instant_onboarding_confirm_contact, name);
|
||||
} else if (qrParsed.getState() == DcContext.DC_QR_ASK_VERIFYGROUP) {
|
||||
String groupName = qrParsed.getText1();
|
||||
dialogMsg = getString(R.string.instant_onboarding_confirm_group, groupName);
|
||||
}
|
||||
|
||||
if (qrParsed.getState() == DcContext.DC_QR_ASK_VERIFYCONTACT
|
||||
|| qrParsed.getState() == DcContext.DC_QR_ASK_VERIFYGROUP) {
|
||||
AlertDialog confirmDialog = new AlertDialog.Builder(this)
|
||||
.setMessage(dialogMsg)
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
okCallback.run();
|
||||
})
|
||||
.setNegativeButton("Cancel", (dialog, which) -> {
|
||||
if (cancelCallback != null) {
|
||||
cancelCallback.run();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
} else {
|
||||
okCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private void init(CompoundBarcodeView barcodeScannerView, Intent intent, Bundle savedInstanceState) {
|
||||
capture = new CaptureManager(this, barcodeScannerView);
|
||||
capture = new CustomCaptureManager(this, barcodeScannerView);
|
||||
|
||||
capture.setResultInterceptor((result, finishCallback) -> {
|
||||
String rawQr = result.getText();
|
||||
|
||||
showConfirmDialog(rawQr, finishCallback, () -> {
|
||||
barcodeScannerView.resume();
|
||||
capture.decode();
|
||||
});
|
||||
});
|
||||
|
||||
capture.initializeFromIntent(intent, savedInstanceState);
|
||||
capture.decode();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package org.thoughtcrime.securesms.relay;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
@@ -47,6 +49,9 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
/** QR provided via Intent extras needs to be saved to pass it to QrCodeHandler when authorization finishes */
|
||||
private String qrData = null;
|
||||
|
||||
/** Relay selected for context menu via onRelayLongClick() */
|
||||
private EnteredLoginParam contextMenuRelay = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -143,14 +148,54 @@ public class RelayListActivity extends BaseActionBarActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelayEdit(EnteredLoginParam relay) {
|
||||
public void onRelayLongClick(View view, EnteredLoginParam relay) {
|
||||
contextMenuRelay = relay;
|
||||
registerForContextMenu(view);
|
||||
openContextMenu(view);
|
||||
unregisterForContextMenu(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
getMenuInflater().inflate(R.menu.relay_item_context, menu);
|
||||
|
||||
boolean nonNullAddr = contextMenuRelay != null && contextMenuRelay.addr != null;
|
||||
boolean isMain = nonNullAddr && contextMenuRelay.addr.equals(adapter.getMainRelay());
|
||||
menu.findItem(R.id.menu_delete_relay).setVisible(!isMain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContextMenuClosed(android.view.Menu menu) {
|
||||
super.onContextMenuClosed(menu);
|
||||
contextMenuRelay = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(@NonNull MenuItem item) {
|
||||
if (contextMenuRelay == null) return super.onContextItemSelected(item);
|
||||
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.menu_edit_relay) {
|
||||
onRelayEdit(contextMenuRelay);
|
||||
contextMenuRelay = null;
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_delete_relay) {
|
||||
onRelayDelete(contextMenuRelay);
|
||||
contextMenuRelay = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
private void onRelayEdit(EnteredLoginParam relay) {
|
||||
Intent intent = new Intent(this, EditRelayActivity.class);
|
||||
intent.putExtra(EditRelayActivity.EXTRA_ADDR, relay.addr);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRelayDelete(EnteredLoginParam relay) {
|
||||
private void onRelayDelete(EnteredLoginParam relay) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.remove_transport)
|
||||
.setMessage(getString(R.string.confirm_remove_transport, relay.addr))
|
||||
|
||||
@@ -25,8 +25,7 @@ public class RelayListAdapter extends RecyclerView.Adapter<RelayListAdapter.Rela
|
||||
|
||||
public interface OnRelayClickListener {
|
||||
void onRelayClick(EnteredLoginParam relay);
|
||||
void onRelayEdit(EnteredLoginParam relay);
|
||||
void onRelayDelete(EnteredLoginParam relay);
|
||||
void onRelayLongClick(View view, EnteredLoginParam relay);
|
||||
}
|
||||
|
||||
public RelayListAdapter(OnRelayClickListener listener) {
|
||||
@@ -67,16 +66,12 @@ public class RelayListAdapter extends RecyclerView.Adapter<RelayListAdapter.Rela
|
||||
private final TextView titleText;
|
||||
private final TextView subtitleText;
|
||||
private final ImageView mainIndicator;
|
||||
private final ImageView editButton;
|
||||
private final ImageView deleteButton;
|
||||
|
||||
public RelayViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
titleText = itemView.findViewById(R.id.title);
|
||||
subtitleText = itemView.findViewById(R.id.subtitle);
|
||||
mainIndicator = itemView.findViewById(R.id.main_indicator);
|
||||
editButton = itemView.findViewById(R.id.edit_button);
|
||||
deleteButton = itemView.findViewById(R.id.delete_button);
|
||||
}
|
||||
|
||||
public void bind(EnteredLoginParam relay, boolean isMain, OnRelayClickListener listener) {
|
||||
@@ -84,7 +79,6 @@ public class RelayListAdapter extends RecyclerView.Adapter<RelayListAdapter.Rela
|
||||
titleText.setText(parts.length == 2? parts[1] : parts[0]);
|
||||
subtitleText.setText(parts.length == 2? parts[0] : "");
|
||||
mainIndicator.setVisibility(isMain ? View.VISIBLE : View.INVISIBLE);
|
||||
deleteButton.setVisibility(isMain ? View.GONE : View.VISIBLE);
|
||||
|
||||
itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
@@ -92,16 +86,11 @@ public class RelayListAdapter extends RecyclerView.Adapter<RelayListAdapter.Rela
|
||||
}
|
||||
});
|
||||
|
||||
editButton.setOnClickListener(v -> {
|
||||
itemView.setOnLongClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onRelayEdit(relay);
|
||||
}
|
||||
});
|
||||
|
||||
deleteButton.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onRelayDelete(relay);
|
||||
listener.onRelayLongClick(v, relay);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
import androidx.media3.session.MediaSession;
|
||||
import androidx.media3.session.MediaSessionService;
|
||||
import androidx.media3.session.SessionCommand;
|
||||
import androidx.media3.session.SessionCommands;
|
||||
import androidx.media3.session.SessionResult;
|
||||
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationListActivity;
|
||||
|
||||
public class AudioPlaybackService extends MediaSessionService {
|
||||
|
||||
private static final String TAG = AudioPlaybackService.class.getSimpleName();
|
||||
|
||||
private ExoPlayer player;
|
||||
private MediaSession session;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(C.USAGE_MEDIA) // USAGE_VOICE_COMMUNICATION is for VoIP calls
|
||||
.setContentType(C.AUDIO_CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
player = new ExoPlayer.Builder(this)
|
||||
.setAudioAttributes(audioAttributes, true)
|
||||
.setHandleAudioBecomingNoisy(true)
|
||||
.build();
|
||||
|
||||
// This is for click on the notification to go back to app
|
||||
Intent intent = new Intent(this, ConversationListActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
PendingIntent initialIntent = PendingIntent.getActivity(
|
||||
this, 0, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
|
||||
);
|
||||
|
||||
session = new MediaSession.Builder(this, player)
|
||||
.setSessionActivity(initialIntent)
|
||||
.setCallback(new MediaSession.Callback() {
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
public MediaSession.ConnectionResult onConnect(
|
||||
MediaSession session,
|
||||
MediaSession.ControllerInfo controller
|
||||
) {
|
||||
SessionCommands sessionCommands = MediaSession
|
||||
.ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon()
|
||||
.add(new SessionCommand("UPDATE_ACTIVITY_CONTEXT", new Bundle()))
|
||||
.build();
|
||||
|
||||
return new MediaSession.ConnectionResult.AcceptedResultBuilder(session)
|
||||
.setAvailableSessionCommands(sessionCommands)
|
||||
.build();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ListenableFuture<SessionResult> onCustomCommand(
|
||||
MediaSession session,
|
||||
MediaSession.ControllerInfo controller,
|
||||
SessionCommand customCommand,
|
||||
Bundle args
|
||||
) {
|
||||
if ("UPDATE_ACTIVITY_CONTEXT".equals(customCommand.customAction)) {
|
||||
updateSessionActivity(args);
|
||||
}
|
||||
return Futures.immediateFuture(
|
||||
new SessionResult(SessionResult.RESULT_SUCCESS));
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void updateSessionActivity(Bundle args) {
|
||||
try {
|
||||
// Put all the original extras back into the intent
|
||||
if (args != null && !args.isEmpty()) {
|
||||
String activityClassName = args.getString("activity_class");
|
||||
args.remove("activity_class");
|
||||
|
||||
if (activityClassName != null) {
|
||||
Class<?> activityClass = Class.forName(activityClassName);
|
||||
Intent intent = new Intent(this, activityClass);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.putExtras(args);
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
this,
|
||||
0,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
|
||||
);
|
||||
|
||||
session.setSessionActivity(pendingIntent);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e(TAG, "Activity class not found", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
|
||||
return session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (session != null) {
|
||||
session.release();
|
||||
session = null;
|
||||
}
|
||||
if (player != null) {
|
||||
player.release();
|
||||
player = null;
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
@@ -323,7 +323,15 @@ public class ViewUtil {
|
||||
* @param view The view to apply insets to
|
||||
*/
|
||||
public static void applyWindowInsetsAsMargin(@NonNull View view) {
|
||||
applyWindowInsetsAsMargin(view, true, true, true, true);
|
||||
applyWindowInsetsAsMargin(view, true, true, true, true, false);
|
||||
}
|
||||
|
||||
public static void applyWindowInsetsAsMargin(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
applyWindowInsetsAsMargin(view, left, top, right, bottom, false);
|
||||
}
|
||||
|
||||
public static void forceApplyWindowInsetsAsMargin(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
applyWindowInsetsAsMargin(view, left, top, right, bottom, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,8 +345,9 @@ public class ViewUtil {
|
||||
* @param top Whether to apply top inset
|
||||
* @param right Whether to apply right inset
|
||||
* @param bottom Whether to apply bottom inset
|
||||
* @param forceDispatch Whether to force application of insets
|
||||
*/
|
||||
public static void applyWindowInsetsAsMargin(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
public static void applyWindowInsetsAsMargin(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom, boolean forceDispatch) {
|
||||
// Only enable on API 30+ where WindowInsets APIs work correctly
|
||||
if (!isEdgeToEdgeSupported()) return;
|
||||
|
||||
@@ -371,10 +380,10 @@ public class ViewUtil {
|
||||
ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
|
||||
if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
|
||||
ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) layoutParams;
|
||||
marginParams.leftMargin = baseMarginLeft + insets.left;
|
||||
marginParams.topMargin = baseMarginTop + insets.top;
|
||||
marginParams.rightMargin = baseMarginRight + insets.right;
|
||||
marginParams.bottomMargin = baseMarginBottom + insets.bottom;
|
||||
marginParams.leftMargin = left ? baseMarginLeft + insets.left : baseMarginLeft;
|
||||
marginParams.topMargin = top ? baseMarginTop + insets.top : baseMarginTop;
|
||||
marginParams.rightMargin = right ? baseMarginRight + insets.right : baseMarginRight;
|
||||
marginParams.bottomMargin = bottom ? baseMarginBottom + insets.bottom : baseMarginBottom;
|
||||
v.setLayoutParams(marginParams);
|
||||
}
|
||||
|
||||
@@ -383,7 +392,14 @@ public class ViewUtil {
|
||||
|
||||
// Request the initial insets to be dispatched if the view is attached
|
||||
if (view.isAttachedToWindow()) {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
if (forceDispatch) {
|
||||
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view);
|
||||
if (insets != null) {
|
||||
ViewCompat.dispatchApplyWindowInsets(view, insets);
|
||||
}
|
||||
} else {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +411,7 @@ public class ViewUtil {
|
||||
* @param view The view to apply insets to
|
||||
*/
|
||||
public static void applyWindowInsets(@NonNull View view) {
|
||||
applyWindowInsets(view, true, true, true, true, false);
|
||||
applyWindowInsets(view, true, true, true, true, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,7 +426,20 @@ public class ViewUtil {
|
||||
* @param bottom Whether to apply bottom inset
|
||||
*/
|
||||
public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
applyWindowInsets(view, left, top, right, bottom, false);
|
||||
applyWindowInsets(view, left, top, right, bottom, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force applying window insets to a view by adding padding to avoid drawing elements behind system bars.
|
||||
*
|
||||
* @param view The view to apply insets to
|
||||
* @param left Whether to apply left inset
|
||||
* @param top Whether to apply top inset
|
||||
* @param right Whether to apply right inset
|
||||
* @param bottom Whether to apply bottom inset
|
||||
*/
|
||||
public static void forceApplyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom) {
|
||||
applyWindowInsets(view, left, top, right, bottom, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -425,8 +454,9 @@ public class ViewUtil {
|
||||
* @param right Whether to apply right inset
|
||||
* @param bottom Whether to apply bottom inset
|
||||
* @param consumeImeInsets Whether to consume IME insets so they don't propagate to child views
|
||||
* @param forceDispatch Force application of Insets, regardless if system think it shall dispatch
|
||||
*/
|
||||
public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom, boolean consumeImeInsets) {
|
||||
public static void applyWindowInsets(@NonNull View view, boolean left, boolean top, boolean right, boolean bottom, boolean consumeImeInsets, boolean forceDispatch) {
|
||||
// Only enable on API 30+ where WindowInsets APIs work correctly
|
||||
if (!isEdgeToEdgeSupported()) return;
|
||||
|
||||
@@ -469,7 +499,14 @@ public class ViewUtil {
|
||||
|
||||
// Request the initial insets to be dispatched if the view is attached
|
||||
if (view.isAttachedToWindow()) {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
if (forceDispatch) {
|
||||
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(view);
|
||||
if (insets != null) {
|
||||
ViewCompat.dispatchApplyWindowInsets(view, insets);
|
||||
}
|
||||
} else {
|
||||
ViewCompat.requestApplyInsets(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.ui.PlayerView;
|
||||
import com.google.android.exoplayer2.ui.StyledPlayerView;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
@@ -49,7 +49,7 @@ import org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory;
|
||||
|
||||
public class VideoPlayer extends FrameLayout {
|
||||
|
||||
@Nullable private final PlayerView exoView;
|
||||
@Nullable private final StyledPlayerView exoView;
|
||||
|
||||
@Nullable private SimpleExoPlayer exoPlayer;
|
||||
@Nullable private Window window;
|
||||
|
||||
@@ -18,50 +18,61 @@
|
||||
<org.thoughtcrime.securesms.components.RecentPhotoViewRail
|
||||
android:id="@+id/recent_photos"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="90dp"
|
||||
android:layout_height="160dp"
|
||||
android:padding="4dp"/>
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:weightSum="4">
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:scrollbars="horizontal">
|
||||
|
||||
<!-- first row -->
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/record_video_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/attach_record_video"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/video"
|
||||
app:circleColor="#00FFFFFF"/>
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/record_video_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/attach_record_video"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/video"
|
||||
app:circleColor="#00FFFFFF"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/video"/>
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/video"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/gallery_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
@@ -70,133 +81,141 @@
|
||||
android:contentDescription="@string/gallery"
|
||||
app:circleColor="@color/gallery_icon"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/gallery"/>
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/gallery"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/document_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_insert_drive_file_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/file"
|
||||
app:circleColor="@color/document_icon"/>
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/document_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_insert_drive_file_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/file"
|
||||
app:circleColor="@color/document_icon"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/file"/>
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/file"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/webxdc_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_apps_24"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/webxdc_app"
|
||||
app:circleColor="@color/apps_icon"
|
||||
/>
|
||||
app:circleColor="@color/apps_icon"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/webxdc_app"/>
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/webxdc_app"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:weightSum="4">
|
||||
|
||||
<!-- second row -->
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/contact_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_person_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/contact"
|
||||
app:circleColor="@color/contact_icon"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/contact"/>
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/contact_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_person_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:contentDescription="@string/contact"
|
||||
app:circleColor="@color/contact_icon"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/contact"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/location_linear_layout"
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/location_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_location_on_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:visibility="visible"
|
||||
android:contentDescription="@string/location"
|
||||
app:circleColor="@color/location_icon"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginTop="10dp"
|
||||
android:id="@+id/location_button_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible"
|
||||
android:gravity="center"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/location"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout android:id="@+id/location_linear_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.thoughtcrime.securesms.components.CircleColorImageView
|
||||
android:id="@+id/location_button"
|
||||
android:layout_width="53dp"
|
||||
android:layout_height="53dp"
|
||||
android:src="@drawable/ic_location_on_white_24dp"
|
||||
android:scaleType="center"
|
||||
android:visibility="visible"
|
||||
android:contentDescription="@string/location"
|
||||
app:circleColor="@color/location_icon"/>
|
||||
|
||||
<TextView android:layout_marginTop="10dp"
|
||||
android:id="@+id/location_button_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible"
|
||||
style="@style/AttachmentTypeLabel"
|
||||
android:text="@string/location"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- fill the gap -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:visibility="invisible">
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</HorizontalScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="org.thoughtcrime.securesms.components.AudioView">
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<LinearLayout android:id="@+id/audio_widget_container"
|
||||
android:orientation="vertical"
|
||||
@@ -12,39 +10,19 @@
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<org.thoughtcrime.securesms.components.AnimatingToggle
|
||||
android:id="@+id/control_toggle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView android:id="@+id/play"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/circle_touch_highlight_background"
|
||||
android:src="@drawable/ic_play_circle_fill_white_48dp"
|
||||
android:scaleType="centerInside"
|
||||
tools:visibility="gone"
|
||||
android:contentDescription="@string/menu_play"/>
|
||||
|
||||
<ImageView android:id="@+id/pause"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:visibility="gone"
|
||||
android:background="@drawable/circle_touch_highlight_background"
|
||||
android:src="@drawable/ic_pause_circle_fill_white_48dp"
|
||||
android:scaleType="centerInside"
|
||||
android:contentDescription="@string/menu_pause"/>
|
||||
|
||||
</org.thoughtcrime.securesms.components.AnimatingToggle>
|
||||
<ImageView android:id="@+id/play_pause"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:visibility="visible"
|
||||
android:background="@drawable/ic_circle_fill_white_48dp"
|
||||
android:backgroundTint="@color/audio_icon"
|
||||
android:src="@drawable/play_icon"
|
||||
android:scaleType="centerInside"
|
||||
android:contentDescription="@string/menu_play"/>
|
||||
|
||||
<LinearLayout android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
@@ -54,7 +32,11 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="2"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
android:layout_gravity="center_vertical"
|
||||
android:progressTint="@color/audio_icon"
|
||||
android:progressTintMode="src_in"
|
||||
android:thumbTint="@color/audio_icon"
|
||||
android:thumbTintMode="src_in"/>
|
||||
|
||||
<LinearLayout android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
app:minHeight="100dp"
|
||||
app:maxHeight="300dp" />
|
||||
|
||||
<org.thoughtcrime.securesms.components.AudioView
|
||||
<org.thoughtcrime.securesms.components.audioplay.AudioView
|
||||
android:id="@+id/attachment_audio"
|
||||
android:layout_width="230dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
/>
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_gravity="bottom"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.AudioView
|
||||
<org.thoughtcrime.securesms.components.audioplay.AudioView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="210dp"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.thoughtcrime.securesms.components.AudioView
|
||||
<org.thoughtcrime.securesms.components.audioplay.AudioView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="210dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -39,6 +39,24 @@
|
||||
</androidx.appcompat.widget.AppCompatEditText>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/chat_description_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/chat_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top|start"
|
||||
android:hint="@string/chat_description"
|
||||
android:inputType="textMultiLine"
|
||||
android:maxLines="3" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/chat_hints"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -47,6 +47,17 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/invitation_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="start"
|
||||
android:visibility="gone"
|
||||
android:textColor="@color/gray50" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/information_label"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.AudioView
|
||||
<org.thoughtcrime.securesms.components.audioplay.AudioView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/audio_view"
|
||||
|
||||
@@ -59,30 +59,4 @@
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/delete_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="72dp"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:contentDescription="@string/remove_transport"
|
||||
android:background="@drawable/touch_highlight_background"
|
||||
android:src="@drawable/ic_delete_white_24dp"
|
||||
app:tint="?attr/conversation_list_item_date_color" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/edit_button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="72dp"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:contentDescription="@string/edit_transport"
|
||||
android:background="@drawable/touch_highlight_background"
|
||||
android:src="@drawable/ic_create_white_24dp"
|
||||
app:tint="?attr/conversation_list_item_date_color" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.exoplayer2.ui.PlayerView
|
||||
<com.google.android.exoplayer2.ui.StyledPlayerView
|
||||
android:id="@+id/video_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:title="@string/edit_transport"
|
||||
android:id="@+id/menu_edit_relay"/>
|
||||
|
||||
<item android:title="@string/remove_transport"
|
||||
android:id="@+id/menu_delete_relay"/>
|
||||
|
||||
</menu>
|
||||
@@ -21,6 +21,7 @@
|
||||
<string name="back">العودة</string>
|
||||
<string name="close">إغلاق</string>
|
||||
<string name="forward">إعادة توجيه</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">حجب المكرفون.</string>
|
||||
<string name="ephemeral_messages">الرسائل المُختفية</string>
|
||||
<string name="save">حفظ</string>
|
||||
@@ -55,6 +56,7 @@
|
||||
<string name="image">صورة</string>
|
||||
<string name="gif">صورة GIF</string>
|
||||
<string name="images">الصور</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">الصوت</string>
|
||||
<string name="voice_message">رسالة صوتية</string>
|
||||
<string name="video">فيديو</string>
|
||||
@@ -163,6 +165,7 @@
|
||||
<string name="pref_your_name">اسمك</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">التوقيع</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">مفتاح الدخول يقوم بالإرسا</string>
|
||||
<string name="pref_vibrate">إهتز</string>
|
||||
<string name="pref_screen_security">تأمين الشاشة</string>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<string name="archive">Arxivləşmə</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Arxivdən çıxarma</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Səssiz</string>
|
||||
<string name="ephemeral_messages">Yox olan mesajlar</string>
|
||||
<string name="save">Saxla</string>
|
||||
@@ -87,6 +88,7 @@
|
||||
<string name="image">Şəkil</string>
|
||||
<string name="gif">Gif</string>
|
||||
<string name="images">Şəkillər</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Səsli mesaj</string>
|
||||
<string name="forwarded_message">Köçürülmüş mesaj</string>
|
||||
@@ -278,6 +280,7 @@
|
||||
<string name="pref_your_name">Adın</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Yazını mətni</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter açarı ilə göndərmək</string>
|
||||
<string name="pref_enter_sends_explain">Enter düyməsini basaraq mətn mesajları göndərəcək</string>
|
||||
<string name="pref_outgoing_media_quality">Göndərilən medianın keyfiyyatı</string>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<string name="archive">Архивиране</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Деархивиране</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Изключване на звука</string>
|
||||
<string name="ephemeral_messages">Изчезващи съобщения</string>
|
||||
<string name="ephemeral_messages_hint">Приложимо за всички членове на този чат, ако използват Delta Chat; в противен случай те пак могат да копират, записват и препращат съобщения или да използват други клиенти за електронна поща.</string>
|
||||
@@ -146,6 +147,7 @@
|
||||
<string name="add_stickers_instructions">За да добавите стикери, натиснете върху \"Отваряне на папка Стикери\", създайте подпапка за Вашия пакет от стикери и дърпайте файлове със стикери и изображения тук</string>
|
||||
<string name="open_sticker_folder">Отваряне на папка Стикери</string>
|
||||
<string name="images">Изображения</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Аудио</string>
|
||||
<string name="voice_message">Гласово съобщение</string>
|
||||
<string name="forwarded">Препратено</string>
|
||||
@@ -559,6 +561,7 @@
|
||||
<string name="pref_your_name">Вашето име</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Текст на подписа</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Клавишът Enter изпраща</string>
|
||||
<string name="pref_enter_sends_explain">Натискането на клавиша Enter ще изпраща текстовите съобщения</string>
|
||||
<string name="pref_outgoing_media_quality">Качество на изходящата медия</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">بایگۊوی</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">و در زیڌن ز بایگۊوی</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">بؽ دونگ</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">بؽ دونگ</string>
|
||||
<string name="ephemeral_messages">پیوما بؽڌارکۊنی</string>
|
||||
<string name="ephemeral_messages_hint">یو ری پوی منتورا ای گوفت وو لوفت، ٱر دلتا چت ن و کار بگرن ائمال ابۊ. ولی هنی ترن پیوما ن لف گیری، زفت وو فوروارد کونن.</string>
|
||||
@@ -163,6 +165,7 @@
|
||||
<string name="add_stickers_instructions">سی ٱووردن برچسب ری «گۊشیڌن دوبلگه برچسب» بزنین، ی لم دوبلگه ای سی کتن برچسب خوتووݩ وورکل کۊنین وو برچسبا ن و اوچو بکشین</string>
|
||||
<string name="open_sticker_folder">گۊشیڌن دوبلگه استیکر</string>
|
||||
<string name="images">شؽواتا</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">دونگ</string>
|
||||
<string name="voice_message">پیوم دونگ</string>
|
||||
<string name="forwarded">فوروارد وابیڌه</string>
|
||||
@@ -199,6 +202,7 @@
|
||||
<string name="games">بازی یل</string>
|
||||
<string name="tools">ٱوزار</string>
|
||||
<string name="app_size">هندا</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">تیجنیڌن</string>
|
||||
<string name="add_to_chat">ٱووردن و گوفت وو لوفت</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Arxiva</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Treu de l\'arxiu</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Silencia</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Silenciat</string>
|
||||
<string name="ephemeral_messages">Missatges efímers</string>
|
||||
<string name="ephemeral_messages_hint">Aquestes opcions s\'apliquen a tots els integrants del xat que utiltizen Delta Chat. Tot i així, poden copiar, desar o reenviar missatges o utilitzar altres clients de correu.</string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">Per a afegir adhesius: premeu \"Obre la carpeta d\'adhesius\", creeu una subcarpeta per a la vostra col·lecció d\'adhesius i arrossegueu-hi la imatge i els fitxers d\'adhesius.</string>
|
||||
<string name="open_sticker_folder">Obre la carpeta d\'adhesius</string>
|
||||
<string name="images">Imatges</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Àudio</string>
|
||||
<string name="voice_message">Missatge de veu</string>
|
||||
<string name="forwarded">Reenviat</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">Jocs</string>
|
||||
<string name="tools">Eines</string>
|
||||
<string name="app_size">Mida</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Publicat</string>
|
||||
<string name="add_to_chat">Afegeix al xat</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -380,12 +384,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Truca</string>
|
||||
<string name="start_audio_call">Trucada de veu</string>
|
||||
<string name="start_video_call">Videotrucada</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Respon</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Rebutja</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Trucada sortint</string>
|
||||
<string name="outgoing_audio_call">Trucada de veu sortint</string>
|
||||
<string name="outgoing_video_call">Videotrucada sortint</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Trucada entrant</string>
|
||||
<string name="incoming_audio_call">Trucada de veu entrant</string>
|
||||
<string name="incoming_video_call">Videotrucada entrant</string>
|
||||
<string name="declined_call">Trucada rebutjada</string>
|
||||
<string name="canceled_call">Trucada cancel·lada</string>
|
||||
<string name="missed_call">Trucada perduda</string>
|
||||
@@ -626,6 +638,7 @@
|
||||
<string name="welcome_chat_over_email">Xat segur i descentralitzat</string>
|
||||
<string name="scan_invitation_code">Escaneja el Codi d\'Invitació</string>
|
||||
<string name="login_title">Identifiqueu-vos</string>
|
||||
<string name="login_advanced_hint">Aquest inici de sessió és per a usuaris avançats:\n\n• No feu servir una adreça que utilitzeu a una altra app.\n\n• Les adreces de correu tradicional admeten xats sense xifratge d\'extrem a extrem, indicades amb una icona de correu.</string>
|
||||
<string name="login_inbox">Safata d\'entrada</string>
|
||||
<string name="login_imap_login">Nom d\'identificació IMAP</string>
|
||||
<string name="login_imap_server">Servidor IMAP</string>
|
||||
@@ -645,11 +658,13 @@
|
||||
<string name="proxy_add_url_hint">Introduïu l\'enllaç del servidor intermediari aquí</string>
|
||||
<string name="proxy_invalid">Servidor intermediari no compatible o invàlid</string>
|
||||
<string name="proxy_list_header">Proxies desats</string>
|
||||
<string name="proxy_delete">Esborra el proxy</string>
|
||||
<string name="proxy_delete">Esborra el servidor intermediari</string>
|
||||
<string name="proxy_delete_explain">Esteu segur de voler esborrar «%1$s»?</string>
|
||||
<string name="proxy_use_proxy_confirm">Voleu utilitzar el proxy \"%1$s\"?</string>
|
||||
<string name="proxy_use_proxy_confirm">Voleu utilitzar el servidor intermediari \"%1$s\"?</string>
|
||||
<string name="proxy_share_explain">Els vostres amics poden afegir aquest servidor intermediari escanejant el codi QR.</string>
|
||||
<string name="proxy_share_link">Comparteix l\'enllaç</string>
|
||||
<string name="proxy_enabled">Servidor intermediari activat</string>
|
||||
<string name="proxy_enabled_hint">Esteu fent servir un servidor intermediari. Si teniu problemes per a connectar-vos, proveu un servidor intermediari diferent.</string>
|
||||
<string name="login_certificate_checks">El certificat coincideix</string>
|
||||
<string name="login_error_mail">Si us plau poseu una adreça d\'email vàlida</string>
|
||||
<string name="login_error_server">Si us plau poseu un servidor / adreça IP vàlida</string>
|
||||
@@ -702,6 +717,7 @@
|
||||
<string name="pref_your_name">El vostre nom</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Signatura</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">La tecla «Retorn» envia</string>
|
||||
<string name="pref_enter_sends_explain">Els missatges s\'enviaran prement la tecla «Retorn»</string>
|
||||
<string name="pref_outgoing_media_quality">Qualitat del contingut multimèdia sortint</string>
|
||||
@@ -752,6 +768,7 @@
|
||||
<string name="pref_backup">Còpia de seguretat</string>
|
||||
<string name="pref_backup_explain">Copia els xats a un magatzem extern</string>
|
||||
<string name="pref_backup_export_explain">La còpia de seguretat és útil a l\'hora de reinstal·lar l\'aplicació en aquest dispositiu o en un altre.\n\nLa còpia tindrà tot els missatges, contactes i xats i la configuració d\'extrem a extrem d\'Autocrypt. Conserveu el fitxer de la còpia en un lloc segur o esborreu-lo tan aviat com pugueu.</string>
|
||||
<string name="pref_backup_export_this">Exporta aquest perfil</string>
|
||||
<!-- the placeholder will be replaced by the number of profiles to export; the number is always larger than 1 -->
|
||||
<string name="pref_backup_export_all">Exporta tots %1$d perfils</string>
|
||||
<string name="pref_backup_export_start_button">Inicia la còpia de seguretat</string>
|
||||
@@ -761,6 +778,10 @@
|
||||
<string name="pref_background_btn_default">Usa la imatge per defecte</string>
|
||||
<string name="pref_background_btn_gallery">Trieu de la galeria</string>
|
||||
<string name="pref_imap_folder_warn_disable_defaults">Si desactiveu aquesta opció, assegureu-vos que el vostre servidor i els altres programes estiguin configurats de la mateixa manera.\n\nAltrament podeu tenir problemes de funcionament.</string>
|
||||
<!-- No need to be literal here, you can also use "Use Multiple Devices", "Support Multiple Devices" or other fitting terms. However, it should fit to the wording or your language at https://delta.chat/help -->
|
||||
<string name="pref_multidevice">Mode multidispositiu</string>
|
||||
<string name="pref_multidevice_explain">Sincronitza els vostres missatges amb els vostres altres dispositius. Activat automàticament quan s\'afegeix un segon dispositiu.</string>
|
||||
<string name="pref_multidevice_change_warn">El mode multidispositiu ha d\'estar habilitat quan feu servir el mateix compte des de diferents perfils. Només desactiveu aquesta opció si heu suprimit aquest perfil de tots els vostres altres dispositius.\n\nDesactivar aquesta opció mentre es fa servir en el mateix perfil en múltiples dispositius farà que es perdin missatges i hi hagi altres problemes.</string>
|
||||
<string name="pref_auto_folder_moves">Moure automàticament a la carpeta de Delta Chat</string>
|
||||
<string name="pref_only_fetch_mvbox_title">Agafa només de la carpeta de DeltaChat</string>
|
||||
<string name="pref_show_emails">Mostra els correus clàssics</string>
|
||||
@@ -768,6 +789,7 @@
|
||||
<string name="pref_show_emails_accepted_contacts">Per a contactes acceptats</string>
|
||||
<string name="pref_show_emails_all">Tot</string>
|
||||
<string name="pref_experimental_features">Funcionalitats experimentals</string>
|
||||
<string name="pref_experimental_features_explain">Aquestes funcionalitats poden ser inestables i poden canviar o ser suprimides</string>
|
||||
<string name="pref_on_demand_location_streaming">Difusió de la ubicació sota demanda</string>
|
||||
<string name="pref_background_default">Imatge per defecte</string>
|
||||
<string name="pref_background_default_color">Color per defecte</string>
|
||||
@@ -784,6 +806,7 @@
|
||||
<string name="n_bytes_message">%1$s missatge</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Baixa el màxim disponible fins a %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Trieu Perfil</string>
|
||||
<string name="profile_image_select">Trieu la imatge de perfil</string>
|
||||
<string name="select_your_new_profile_image">Trieu la imatge nova de perfil</string>
|
||||
@@ -793,6 +816,14 @@
|
||||
<string name="disable_imap_idle">Desactiva IMAP IDLE</string>
|
||||
<string name="disable_imap_idle_explain">No usis l\'extensió IMAP IDLE encara que el servidor la permeti. Activar aquesta opció endarreria l\'obtenció de missatges, activeu-ho només per a proves.</string>
|
||||
<string name="send_stats_to_devs">Envia estadístiques als desenvolupadors del Delta Chat</string>
|
||||
<string name="stats_device_message">Voleu ajudar a millorar Delta Chat i donar suport a la recerca enviant estadístiques d\'ús anònimes setmanalment?\n\n👉 Feu clic aquí… 👈</string>
|
||||
<string name="stats_confirmation_dialog">Voleu ajudar a millorar Delta Chat i donar suport a la recerca enviant estadístiques d\'ús anònimes setmanalment?</string>
|
||||
<string name="stats_thanks">Moltes gràcies! Sempre podeu desactivar l\'enviament a «Preferències -> Avançat».\n\nTeniu 5 minuts addicionals per a participar en un estudi científic sobre Delta Chat?</string>
|
||||
<string name="stats_disable_dialog">L\'enviament d\'estadístiques ja està activat.\n\nVoleu desactivar-lo?</string>
|
||||
<string name="disable">Desactiva</string>
|
||||
<string name="stats_keep_sending">Continua enviant</string>
|
||||
<string name="stats_msg_body">El fitxer adjunt conté estadístiques d\'ús anònimes que ens ajuden a millorar el Delta Chat. Veieu https://delta.chat/help#statssending per a més informació. Gràcies!</string>
|
||||
|
||||
<!-- Emoji picker and categories -->
|
||||
<string name="emoji_search_results">Resultats de la cerca</string>
|
||||
<string name="emoji_not_found">No s\'ha trobat cap emoji</string>
|
||||
@@ -911,6 +942,7 @@
|
||||
<string name="ephemeral_timer_weeks_by_you">Heu definit el temporitzador dels missatges fonedissos a %1$s setmanes.</string>
|
||||
<!-- %1$s will be replaced by the number of weeks (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_weeks_by_other">%2$s ha definit el temporitzador dels missatges efímers a %1$s setmanes.</string>
|
||||
<string name="chat_unencrypted_explanation">Els missatges en aquest xat fan servir el correu electrònic tradicional i no estan xifrats d\'extrem a extrem.</string>
|
||||
<string name="chat_protection_enabled_tap_to_learn_more">Us garantim que a partir d\'ara els missatges són xifrats d\'extrem a extrem. Toqueu per a obtenir més informació.</string>
|
||||
<string name="chat_protection_enabled_explanation">Ara es garanteix que tots els missatges d\'aquest xat són xifrats d\'extrem a extrem.\n\nEl xifratge d\'extrem a extrem manté privats els missatges entre vós i els companys de xat. Ni tan sols el vostre proveïdor de correu electrònic pot llegir-los.</string>
|
||||
<string name="invalid_unencrypted_tap_to_learn_more">%1$srequereix xifratge d\'extrem a extrem, que encara no s\'ha configurat per a aquest xat. Toqueu per a obtenir més informació.</string>
|
||||
@@ -935,6 +967,7 @@
|
||||
<string name="qrscan_hint_desktop">Mou el codi QR a la càmera</string>
|
||||
<string name="qrscan_failed">No s\'ha pogut descodificar el codi QR</string>
|
||||
<string name="qrscan_ask_join_group">Voleu unir-vos al grup «%1$s»?</string>
|
||||
<string name="qrscan_ask_join_channel">Voleu unir-vos al canal \"%1$s\"?</string>
|
||||
<string name="qrscan_fingerprint_mismatch">L\'empremta escanejada no coincideix amb l\'última empremta de %1$s</string>
|
||||
<string name="qrscan_no_addr_found">Aquest codi QR conté una empremta digital, però no hi ha cap adreça de correu electrònic.\n\nPer a una verificació fora de banda, establiu primer una connexió xifrada amb el destinatari.</string>
|
||||
<string name="qrscan_contains_text">Text del codi QR escanejat:\n\n%1$s</string>
|
||||
@@ -942,6 +975,7 @@
|
||||
<string name="qrscan_fingerprint_label">Empremta</string>
|
||||
<string name="withdraw_verifycontact_explain">Altres persones que vulguin contactar amb vós poden escanejar aquest codi QR.\n\nPodeu reinicialitzar-lo, de manera que el codi QR o enllaç actual existent ja no servirà.</string>
|
||||
<string name="withdraw_verifygroup_explain">Altres poden escanejar aquest codi QR per a unir-se al grup «%1$s».\n\nPodeu reinicialitzar-lo, de manera que el codi QR existent, o l\'enllaç d\'invitació, deixarà de funcionar.</string>
|
||||
<string name="withdraw_joinbroadcast_explain">Altres poden escanejar aquest codi QR per a unir-se al canal «%1$s».\n\nPodeu reinicialitzar-lo, de manera que el codi QR existent, o l\'enllaç d\'invitació, deixarà de funcionar.</string>
|
||||
<string name="withdraw_qr_code">Reinicialitza el codi QR</string>
|
||||
<string name="revive_verifycontact_explain">Aquest codi QR s\'ha reinicialitzat i ja no és actiu.</string>
|
||||
<string name="revive_qr_code">Activa el codi QR</string>
|
||||
@@ -965,10 +999,13 @@
|
||||
<string name="qrlogin_ask_login">Voleu iniciar sessió a «%1$s»?</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_started">%1$s us ha convidat a unir-vos a aquest grup.\n\nS\'està esperant el dispositiu de %2$s per a respondre...</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_channel_started">%1$s us ha convidat a unir-vos a aquest canal.\n\nS\'està esperant que el dispositiu de %2$s respongui.</string>
|
||||
<!-- placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_replies">%1$s ha respost, espereu per a ser afegit al grup...</string>
|
||||
<string name="secure_join_wait">S\'està establint el xifratge d\'extrem a extrem garantit, espereu...</string>
|
||||
<string name="contact_verified">%1$s verificat.</string>
|
||||
<string name="contact_blocked">Heu blocat el contacte</string>
|
||||
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
|
||||
<string name="verified_by">Afegit per %1$s</string>
|
||||
<string name="verified_by_you">Afegit per mi</string>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="archive">ئەرشیڤ کردن</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">دەرهێنان لە ئەرشیڤ</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">بێدەنگ کردن</string>
|
||||
<string name="ephemeral_messages">ئەو پەیامانەی بزر دەبن</string>
|
||||
<string name="ephemeral_messages_hint">ئەم ڕێکخستنانە بۆ هەموو بەکارهێنەرانی دێڵتا چات دەبن. ئەگەرچی ئەوان دەتوانن پەیامەکان کۆپی بکەن، پاشەکەوتیان بکەن و بڵاویان بکەنەوە یان لە پۆستێکی ئەلیکترۆنی دیکە کەڵک بگرن.</string>
|
||||
@@ -104,6 +105,7 @@
|
||||
<string name="reply_noun">وەڵام دانەوە</string>
|
||||
<string name="gif">گیف</string>
|
||||
<string name="images">وێنەکان</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">دەنگ</string>
|
||||
<string name="voice_message">پەیامی دەنگی</string>
|
||||
<string name="forwarded_message">پەیامی هاوبەشکراو</string>
|
||||
@@ -346,6 +348,7 @@
|
||||
<string name="pref_your_name">ناو</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">دەقی واژۆ</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">کلیلی \"ئینتەر\" بنێرێت</string>
|
||||
<string name="pref_enter_sends_explain">دەستنان بە کلیلی \"ئینتەر\"دا، پەیامەکان دەنێرێت.</string>
|
||||
<string name="pref_outgoing_media_quality">چۆنێتی ڕەنگاڵە هەناردنییەکان</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Archivovat</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Vyjmout z archivu</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Ztlumit</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Ztlumeno</string>
|
||||
<string name="ephemeral_messages">Mizející zprávy</string>
|
||||
<string name="ephemeral_messages_hint">Volba platí pro všechny členy tohoto chatu, kteří používají Delta Chat; stále ale mohou kopírovat, ukládat a přeposílat zprávy nebo používat jiné e-mailové klienty, které tuto volbu nerespektují.</string>
|
||||
@@ -201,6 +203,7 @@
|
||||
<string name="add_stickers_instructions">Přejete-li si přidat nálepky, klepněte na „Otevřít složku nálepek“, vytvořte podsložku pro balíček nálepek a přetáhněte do ní soubory obrázků a nálepek</string>
|
||||
<string name="open_sticker_folder">Otevřít složku nálepek</string>
|
||||
<string name="images">Obrázky</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Zvukové záznamy</string>
|
||||
<string name="voice_message">Hlasová zpráva</string>
|
||||
<string name="forwarded">Přeposlané</string>
|
||||
@@ -237,6 +240,7 @@
|
||||
<string name="games">Hry</string>
|
||||
<string name="tools">Nástroje</string>
|
||||
<string name="app_size">Velikost</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Zveřejněno</string>
|
||||
<string name="add_to_chat">Přidat do chatu</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -408,7 +412,9 @@
|
||||
<string name="answer_call">Zvedni</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Pokles</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Odchozí hovor</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Příchozí hovor</string>
|
||||
<string name="declined_call">Odmítnutý hovor</string>
|
||||
<string name="canceled_call">Zrušený hovor</string>
|
||||
@@ -750,6 +756,7 @@
|
||||
<string name="pref_your_name">Vaše jméno</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Bio</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter odesílá</string>
|
||||
<string name="pref_enter_sends_explain">Stisk klávesy Enter odešle zprávu</string>
|
||||
<string name="pref_outgoing_media_quality">Kvalita odesílaných multimédií</string>
|
||||
@@ -838,6 +845,7 @@
|
||||
<string name="n_bytes_message">%1$s zpráva</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Stahovat dostupné maximum do %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Vyberte profil</string>
|
||||
<string name="profile_image_select">Vybrat profilový obrázek</string>
|
||||
<string name="select_your_new_profile_image">Vyberte si svůj nový profilový obrázek</string>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<string name="archive">Arkivér</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Fortryd arkivering</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Udsæt</string>
|
||||
<string name="ephemeral_messages">Beskeder med tidsudløb</string>
|
||||
<string name="ephemeral_messages_hint">Disse indstillinger gælder for alle deltagere der bruger Delta Chat. De kan dog kopiere, gemme og videresende beskeder eller bruge andre e-mail klienter. </string>
|
||||
@@ -114,6 +115,7 @@
|
||||
<!-- "Stickers" as known from other messengers; in some languages, the English "Sticker" is fine. -->
|
||||
<string name="sticker">Klistermærker</string>
|
||||
<string name="images">Billeder</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Lyd</string>
|
||||
<string name="voice_message">Tale besked</string>
|
||||
<string name="forwarded">Videresendt</string>
|
||||
@@ -401,6 +403,7 @@
|
||||
<string name="pref_your_name">Dit navn</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Underskrift tekst</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter tast sender</string>
|
||||
<string name="pref_enter_sends_explain">Tryk på enter tast vil sende tekst beskeden</string>
|
||||
<string name="pref_outgoing_media_quality">Udgående medie kvalitet</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Archivieren</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Dearchivieren</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Stumm</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Stumm</string>
|
||||
<string name="ephemeral_messages">Verschwindende Nachrichten</string>
|
||||
<string name="ephemeral_messages_hint">Gilt für alle Gruppenmitglieder, die Delta Chat verwenden. Nachrichten können kopiert, gespeichert oder weitergeleitet werden.</string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">Um Sticker hinzuzufügen, tippe auf \"Sticker-Ordner öffnen\", erstelle einen Unterordner für dein Sticker-Paket und ziehe Bild- und Sticker-Dateien dorthin.</string>
|
||||
<string name="open_sticker_folder">Sticker-Ordner öffnen</string>
|
||||
<string name="images">Bilder</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Sprachnachricht</string>
|
||||
<string name="forwarded">Weitergeleitet</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">Spiele</string>
|
||||
<string name="tools">Tools</string>
|
||||
<string name="app_size">Größe</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Veröffentlicht</string>
|
||||
<string name="add_to_chat">Zum Chat hinzufügen</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -381,12 +385,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Anrufen</string>
|
||||
<string name="start_audio_call">Sprachanruf</string>
|
||||
<string name="start_video_call">Videoanruf</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Annehmen</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Ablehnen</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Ausgehender Anruf</string>
|
||||
<string name="outgoing_audio_call">Ausgehender Sprachanruf</string>
|
||||
<string name="outgoing_video_call">Ausgehender Videoanruf</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Eingehender Anruf</string>
|
||||
<string name="incoming_audio_call">Eingehender Sprachanruf</string>
|
||||
<string name="incoming_video_call">Eingehender Videoanruf</string>
|
||||
<string name="declined_call">Abgelehnter Anruf</string>
|
||||
<string name="canceled_call">Abgebrochener Anruf</string>
|
||||
<string name="missed_call">Verpasster Anruf</string>
|
||||
@@ -717,6 +729,7 @@
|
||||
<string name="pref_your_name">Mein Name</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Signatur</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter-Taste sendet</string>
|
||||
<string name="pref_enter_sends_explain">Durch Drücken der Eingabetaste werden Textnachrichten gesendet.</string>
|
||||
<string name="pref_outgoing_media_quality">Medienqualität beim Senden</string>
|
||||
@@ -805,6 +818,7 @@
|
||||
<string name="n_bytes_message">%1$s Nachricht</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Download max. verfügbar bis %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Profil auswählen</string>
|
||||
<string name="profile_image_select">Profilbild auswählen</string>
|
||||
<string name="select_your_new_profile_image">Wählen dein Profilbild aus</string>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<string name="archive">Αρχειοθέτηση</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Αποαρχειοθ</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Σίγαση</string>
|
||||
<string name="ephemeral_messages">Μηνύματα που εξαφανίζονται</string>
|
||||
<string name="ephemeral_messages_hint">Ισχύει για όλα τα μέλη της συνομιλίας αν χρησιμοποιούν Delta Chat: έχουν την δυνατότητα αντιγραφής, αποθήκευσης, και κοινοποίησης μηνυμάτων ή χρήση άλλων e-mail πελατών.</string>
|
||||
@@ -132,6 +133,7 @@
|
||||
<!-- "Stickers" as known from other messengers; in some languages, the English "Sticker" is fine. -->
|
||||
<string name="sticker">Αυτοκόλλητο</string>
|
||||
<string name="images">Εικόνες</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Ήχοι</string>
|
||||
<string name="voice_message">Μήνυμα φωνής</string>
|
||||
<string name="forwarded">Κοινοποίηση</string>
|
||||
@@ -475,6 +477,7 @@
|
||||
<string name="pref_your_name">Το όνομά σου</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Υπογραφή</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Το Enter στέλνει</string>
|
||||
<string name="pref_enter_sends_explain">Τα μηνύματα θα στέλνονται με το πάτημα του Enter</string>
|
||||
<string name="pref_outgoing_media_quality">Ποιότητα Εξερχόμενων Μέσων</string>
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
<string name="archive">Arĥivi</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Malarĥivi</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Muta sciigoj</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Silentigita</string>
|
||||
<string name="ephemeral_messages">Memviŝontaj mesaĝoj</string>
|
||||
<string name="ephemeral_messages_hint">Aplikebla al ĉiuj anoj de tiu ĉi babilejo kiuj uzas Delta Chat; ili ankoraŭ povas kopii, konservi kaj plusendi mesaĝojn, kaj uzi aliajn retpoŝtajn klientojn.</string>
|
||||
@@ -169,6 +171,7 @@
|
||||
<!-- "Stickers" as known from other messengers; in some languages, the English "Sticker" is fine. -->
|
||||
<string name="sticker">Glumarko</string>
|
||||
<string name="images">Bildoj</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Sonaĵo</string>
|
||||
<string name="voice_message">Voĉmesaĝo</string>
|
||||
<string name="forwarded">Plusendita</string>
|
||||
@@ -399,6 +402,7 @@
|
||||
<string name="pref_profile_photo">Profilbildo</string>
|
||||
<string name="pref_blocked_contacts">Blokitaj kontaktoj</string>
|
||||
<string name="pref_your_name">Via nomo</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">La Eniga klavo kaŭzas sendon</string>
|
||||
<string name="pref_enter_sends_explain">Premado de la Eniga klavo sendos mesaĝojn</string>
|
||||
<string name="pref_vibrate">Vibrado</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Archivar</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Des-archivar</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Silenciar</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Silenciar</string>
|
||||
<string name="ephemeral_messages">Desaparición de mensajes</string>
|
||||
<string name="ephemeral_messages_hint">Estos ajustes se aplican a todos los participantes que usan Delta Chat. Sin embargo, pueden copiar, guardar y reenviar mensajes o usar otros clientes de correo</string>
|
||||
@@ -190,6 +192,7 @@
|
||||
<string name="add_stickers_instructions">Para añadir stickers, toca en \"Abrir carpeta de stickers\", crea una subcarpeta para tu colección de stickers y copia imágenes y stickers allí</string>
|
||||
<string name="open_sticker_folder">Abrir la carpeta de stickers</string>
|
||||
<string name="images">Imágenes</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Mensaje de voz</string>
|
||||
<string name="forwarded">Reenviado</string>
|
||||
@@ -226,6 +229,7 @@
|
||||
<string name="games">Juegos</string>
|
||||
<string name="tools">Herramientas</string>
|
||||
<string name="app_size">Tamaño</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Publicado</string>
|
||||
<string name="add_to_chat">Agregar al chat</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -392,12 +396,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Llamar</string>
|
||||
<string name="start_audio_call">Llamada</string>
|
||||
<string name="start_video_call">Videollamada</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Contestar</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Rechazar</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Llamada saliente</string>
|
||||
<string name="outgoing_audio_call">Llamada saliente</string>
|
||||
<string name="outgoing_video_call">Videollamada saliente</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Llamada entrante</string>
|
||||
<string name="incoming_audio_call">Llamada entrante</string>
|
||||
<string name="incoming_video_call">Videollamada entrante</string>
|
||||
<string name="declined_call">Llamada rechazada</string>
|
||||
<string name="canceled_call">Llamada cancelada</string>
|
||||
<string name="missed_call">Llamada perdida</string>
|
||||
@@ -733,6 +745,7 @@
|
||||
<string name="pref_your_name">Tu nombre</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Texto de firma</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Tecla Intro envía</string>
|
||||
<string name="pref_enter_sends_explain">La tecla Intro enviará tu mensaje</string>
|
||||
<string name="pref_outgoing_media_quality">Calidad de multimedia saliente</string>
|
||||
@@ -805,6 +818,7 @@ Desactiva este ajuste solo si has eliminado este perfil de todos tus demás disp
|
||||
<string name="pref_show_emails_accepted_contacts">Para contactos aceptados</string>
|
||||
<string name="pref_show_emails_all">Todos</string>
|
||||
<string name="pref_experimental_features">Características experimentales</string>
|
||||
<string name="pref_experimental_features_explain">Estas funciones pueden ser inestables y pueden ser modificadas o eliminadas</string>
|
||||
<string name="pref_on_demand_location_streaming">Transmisión de ubicación bajo demanda</string>
|
||||
<string name="pref_background_default">Fondo por defecto</string>
|
||||
<string name="pref_background_default_color">Color por defecto</string>
|
||||
@@ -821,6 +835,7 @@ Desactiva este ajuste solo si has eliminado este perfil de todos tus demás disp
|
||||
<string name="n_bytes_message">Mensaje de %1$s</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Descarga disponible hasta %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Seleccionar perfil</string>
|
||||
<string name="profile_image_select">Seleccionar imagen de perfil</string>
|
||||
<string name="select_your_new_profile_image">Seleccionar tu nueva imagen de perfil</string>
|
||||
@@ -830,6 +845,14 @@ Desactiva este ajuste solo si has eliminado este perfil de todos tus demás disp
|
||||
<string name="disable_imap_idle">Deshabilitar IMAP IDLE</string>
|
||||
<string name="disable_imap_idle_explain">No utilizar la extensión IMAP IDLE aunque el servidor la admita. Habilitar esta opción retrasará el recibo de mensajes, actívala solo para pruebas.</string>
|
||||
<string name="send_stats_to_devs">Enviar estadísticas a los desarrolladores de Delta Chat</string>
|
||||
<string name="stats_device_message">¿Quieres ayudar a mejorar Delta Chat y apoyar la investigación enviando estadísticas de uso anónimas semanales?\n\n👉 Pulsa aquí… 👈</string>
|
||||
<string name="stats_confirmation_dialog">¿Quieres ayudar a mejorar Delta Chat y apoyar la investigación enviando estadísticas de uso anónimas semanales?</string>
|
||||
<string name="stats_thanks">¡Gracias! Siempre puedes desactivar el envío en \"Configuración -> Avanzado\".\n\n¿Tienes 5 minutos adicionales para participar en un estudio científico sobre la seguridad de Delta Chat?</string>
|
||||
<string name="stats_disable_dialog">El envío de estadísticas ya está habilitado.\n\n¿Quieres deshabilitarlo?</string>
|
||||
<string name="disable">Desactivar</string>
|
||||
<string name="stats_keep_sending">Seguir enviando</string>
|
||||
<string name="stats_msg_body">El archivo adjunto contiene estadísticas de uso anónimas que nos ayudan a mejorar Delta Chat. Consulta https://delta.chat/help#statssending para más información. ¡Gracias!</string>
|
||||
|
||||
<!-- Emoji picker and categories -->
|
||||
<string name="emoji_search_results">Resultados de la búsqueda</string>
|
||||
<string name="emoji_not_found">No se encontraron emojis</string>
|
||||
@@ -1005,10 +1028,13 @@ Desactiva este ajuste solo si has eliminado este perfil de todos tus demás disp
|
||||
<string name="qrlogin_ask_login">¿Iniciar sesión en \"%1$s\"?</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_started">%1$s te invitó a unirte a este grupo.\n\nEsperando que el dispositivo de %2$s responda…</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_channel_started">%1$s te invitó a unirte a este canal.\n\nEsperando que el dispositivo de %2$s responda…</string>
|
||||
<!-- placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_replies">%1$s respondió, esperando ser agregado al grupo…</string>
|
||||
<string name="secure_join_wait">Estableciendo cifrado de extremo a extremo garantizado, por favor, espere...</string>
|
||||
<string name="contact_verified">%1$s verificado.</string>
|
||||
<string name="contact_blocked">Contacto bloqueado</string>
|
||||
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
|
||||
<string name="verified_by">Verificado por %1$s</string>
|
||||
<string name="verified_by_you">Verificado por ti</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Arhiveeri</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Tõsta arhiivist välja</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Summuta</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Summutatud</string>
|
||||
<string name="ephemeral_messages">Isekustuvad sõnumid</string>
|
||||
<string name="ephemeral_messages_hint">Kehtib kõikidele selles vestluses osalejatele - aga siiski saavad nad sõnumeid kopeerida, salvestada ja edastada.</string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">Kleepsude lisamiseks klõpsi valikut „Ava kleepsude kaust“, loo oma kleepsupaki jaoks sinna alamkaust ning lohista pildi- ja kleepsufailid sinna</string>
|
||||
<string name="open_sticker_folder">Ava kleepsude kaust</string>
|
||||
<string name="images">Pildid</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Heli</string>
|
||||
<string name="voice_message">Hääsõnum</string>
|
||||
<string name="forwarded">Edastatud</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">Mängud</string>
|
||||
<string name="tools">Tarvikud</string>
|
||||
<string name="app_size">Suurus</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Avaldatud</string>
|
||||
<string name="add_to_chat">Lisa vestlusele</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -380,12 +384,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Helista</string>
|
||||
<string name="start_audio_call">Häälkõne</string>
|
||||
<string name="start_video_call">Videokõne</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Vasta</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Keeldu</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Väljuv kõne</string>
|
||||
<string name="outgoing_audio_call">Väljuv häälkõne</string>
|
||||
<string name="outgoing_video_call">Väljuv videokõne</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Saabuv kõne</string>
|
||||
<string name="incoming_audio_call">Saabuv häälkõne</string>
|
||||
<string name="incoming_video_call">Saabuv videokõne</string>
|
||||
<string name="declined_call">Keeldutud kõne</string>
|
||||
<string name="canceled_call">katkestatud kõne</string>
|
||||
<string name="missed_call">Märkamata kõne</string>
|
||||
@@ -716,6 +728,7 @@
|
||||
<string name="pref_your_name">Sinu nimi</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Elulugu/allkiri/moto</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Sisestusklahv saadab sõnumi</string>
|
||||
<string name="pref_enter_sends_explain">Sisestusklahvi vajutamisega saadad sõnumi ära</string>
|
||||
<string name="pref_outgoing_media_quality">Saadetava meediumi kvaliteet</string>
|
||||
@@ -804,6 +817,7 @@
|
||||
<string name="n_bytes_message">Sõnum suurusega %1$s</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Allalaadimise ülempiir on saadaval kuni %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Vali profiil</string>
|
||||
<string name="profile_image_select">Vali profiilipilt</string>
|
||||
<string name="select_your_new_profile_image">Vali oma uus profiilipilt</string>
|
||||
|
||||
@@ -51,22 +51,27 @@
|
||||
<string name="archive">Artxibatu</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Berreskuratu artxibotik</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Isilarazi</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Isilarazia</string>
|
||||
<string name="ephemeral_messages">Mezuen desagerpena</string>
|
||||
<string name="ephemeral_messages_hint">Txat honetako kide guztiei aplikatzen zaie; mezuak kopiatu, gorde eta birbidali ahal izango dituzte oraindik ere.</string>
|
||||
<string name="save">Gorde</string>
|
||||
<string name="chat">Txata</string>
|
||||
<string name="media">Multimedia</string>
|
||||
<string name="profile">Profila</string>
|
||||
<string name="all_profiles">Profil guztiak</string>
|
||||
<string name="current_profile">Oraingo profila</string>
|
||||
<string name="apps_and_media">Aplikazioak eta multimedia</string>
|
||||
<string name="profile">Kontua</string>
|
||||
<string name="all_profiles">Kontu guztiak</string>
|
||||
<string name="current_profile">Oraingo kontua</string>
|
||||
<string name="main_menu">Menu nagusia</string>
|
||||
<string name="start_chat">Hasi txata</string>
|
||||
<string name="show_full_message">Erakutsi mezu osoa</string>
|
||||
<!-- Stay short here, say ~16 characters. The source string could also be "All Read", maybe that hint can make translations easier :) -->
|
||||
<string name="mark_all_as_read">Ezarri denak irakurri gisa</string>
|
||||
<string name="mark_as_read">Ezarri irakurri gisa</string>
|
||||
<!-- Shortest text for "Mark as being read". In english, this could be "Read" (past tense of "to read"), in german, this could be "Gelesen". -->
|
||||
<string name="mark_as_read_short">Markatu irakurrita</string>
|
||||
<!-- Placeholder text when something is loading -->
|
||||
<string name="loading">Kargatzen...</string>
|
||||
<string name="hide">Ezkutatu</string>
|
||||
@@ -176,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">Stickerretara gehitzeko, klik egin \"Ireki sticker karpeta\" aukeran, sortu azpikarpeta bat zure sticker multzoarentzat eta arrastatu irudi eta sticker fitxategiak bertara.</string>
|
||||
<string name="open_sticker_folder">Ireki sticker karpeta</string>
|
||||
<string name="images">Irudiak</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audioa</string>
|
||||
<string name="voice_message">Ahots-mezua</string>
|
||||
<string name="forwarded">Birbidalia</string>
|
||||
@@ -185,7 +191,10 @@
|
||||
<string name="video">Bideoa</string>
|
||||
<string name="documents">Dokumentuak</string>
|
||||
<string name="contact">Kontaktua</string>
|
||||
<string name="bot">Bot</string>
|
||||
<string name="camera">Kamera</string>
|
||||
<!-- As in "start a video recording" or "take a photo"; eg. the description of the "shutter button" in cameras -->
|
||||
<string name="capture">Harrapatu</string>
|
||||
<string name="switch_camera">Aldatu kamera</string>
|
||||
<string name="toggle_fullscreen">Aldatu pantaila osoa modua</string>
|
||||
<string name="location">Kokalekua</string>
|
||||
@@ -202,11 +211,14 @@
|
||||
<string name="webxdc_app">Aplikazioa</string>
|
||||
<!-- plural of "App"; used to present "Webxdc App" (https://webxdc.org) in a user friendly way. Please stay close to the original term and keep it short (it is used in menus with few screen space). -->
|
||||
<string name="webxdc_apps">Aplikazioak</string>
|
||||
<string name="webxdc_store_url">Aplikazio-hautatzailearen URL-a</string>
|
||||
<string name="webxdc_store_url_explain">Ezarriz gero, URL hori erabiliko da aplikazio-hautatzaile gisa, lehenetsitakoaren ordez.</string>
|
||||
<string name="webxdc_draft_hint">Sakatu \"Bidali\" partekatzeko</string>
|
||||
<string name="home">Hasiera</string>
|
||||
<string name="games">Jokoak</string>
|
||||
<string name="tools">Tresnak</string>
|
||||
<string name="app_size">Tamaina</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Argitaratua</string>
|
||||
<string name="add_to_chat">Gehitu txatera</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -235,6 +247,7 @@
|
||||
<!-- menu labels (or icon, buttons...) -->
|
||||
<string name="menu_new_contact">Kontaktu berria</string>
|
||||
<string name="menu_new_classic_contact">Gehitu kontaktua eskuz</string>
|
||||
<string name="new_classic_contact_explain">Eskuz gehitutako kontaktuak eposta helbide klasikoetara idazteko erabil daitezke, eta ez da bermatzen muturretik muturrera zifratuta egotea.</string>
|
||||
<string name="menu_new_chat">Txat berria</string>
|
||||
<string name="menu_new_group">Talde berria</string>
|
||||
<!-- "Chat" is a verb here, "Message to" would also fit. the string might be used in the "New Chat" screen above the contact list -->
|
||||
@@ -273,32 +286,67 @@
|
||||
<string name="menu_message_details">Mezuaren xehetasunak</string>
|
||||
<string name="menu_copy_to_clipboard">Kopiatu arbelera</string>
|
||||
<string name="share_invite_link">Partekatu gonbidapen esteka</string>
|
||||
<string name="share_invite_link_explain">Esteka hau duen edonork ikus dezake zure profila eta txat bat hasi zurekin. Partekatu konfiantzazko pertsonekin bakarrik.</string>
|
||||
<string name="invite_friends">Gonbidatu lagunak</string>
|
||||
<!-- %1$s is replaced by the user's invitation link ("https://i.delta.chat/...") -->
|
||||
<string name="invite_friends_text">Jarri nirekin harremanetan Delta Chat bidez:\n%1$s</string>
|
||||
<string name="menu_copy_selection_to_clipboard">Kopiatu hautaketa</string>
|
||||
<string name="menu_copy_link_to_clipboard">Kopiatu esteka</string>
|
||||
<string name="menu_copy_text_to_clipboard">Kopiatu testua</string>
|
||||
<string name="menu_copy_image_to_clipboard">Kopiatu irudia</string>
|
||||
<string name="menu_copy_email_to_clipboard">Kopiatu eposta</string>
|
||||
<string name="paste_from_clipboard">Kopiatu arbeletik</string>
|
||||
<string name="ask_copy_unopenable_link_to_clipboard">\"%1$d\" esteka ezin da web arakatzailean ireki. Esteka arbelean kopiatu nahi duzu horren ordez?</string>
|
||||
<string name="menu_forward">Birbidali mezua</string>
|
||||
<string name="menu_reply">Erantzun mezuari</string>
|
||||
<string name="menu_mute">Mututu jakinarazpenak</string>
|
||||
<string name="menu_unmute">Utzi mututzeari</string>
|
||||
<string name="menu_export_attachment">Esportatu eranskina</string>
|
||||
<string name="menu_export_attachments">Esportatu eranskinak</string>
|
||||
<string name="menu_all_media">Multimedia guztia</string>
|
||||
<string name="all_apps_and_media">Aplikazio guztiak eta multimedia</string>
|
||||
<!-- Command to jump to the original message corresponding to a gallery image or document -->
|
||||
<string name="show_in_chat">Erakutsi txatean</string>
|
||||
<string name="show_app_in_chat">Erakutsi aplikazioa txatean</string>
|
||||
<string name="menu_share">Partekatu</string>
|
||||
<!-- Verb "to block sth." usually a mailing list or a contact, not a noun -->
|
||||
<string name="block">Bloketau</string>
|
||||
<string name="menu_block_contact">Blokeatu kontaktuak</string>
|
||||
<string name="menu_unblock_contact">Desblokeatu kontaktua</string>
|
||||
<string name="accept">Onartu</string>
|
||||
<string name="menu_play">Erreproduzitu</string>
|
||||
<string name="menu_pause">Pausatu</string>
|
||||
<string name="menu_scroll_to_bottom">Korritu behealdera</string>
|
||||
<string name="menu_scroll_to_top">Korritu goialdera</string>
|
||||
<string name="menu_help">Laguntza</string>
|
||||
<!-- use the same term for "Apps" as elsewhere -->
|
||||
<string name="what_is_webxdc">Aplikazioei buruz</string>
|
||||
<string name="privacy_policy">Pribatutasun politika</string>
|
||||
<string name="menu_select_all">Hautatu guztiak</string>
|
||||
<string name="select_chat">Aukeratu txata</string>
|
||||
<string name="select_more">Aukeratu gehiago</string>
|
||||
<string name="menu_edit_name">Editatu izena</string>
|
||||
<!-- The placeholder will be replaced by the name the contact gave themself -->
|
||||
<string name="edit_name_explain">Ezarri \"%1$s\" ordez ikusiko duzun ezizena. Utzi hutsik kontaktuak aukeratutako izena erabiltzeko.</string>
|
||||
<!-- The placeholder will be replaced by the name the contact gave themself -->
|
||||
<string name="edit_name_placeholder">\"%1$s\"(r)en ezizena</string>
|
||||
<string name="menu_settings">Ezarpenak</string>
|
||||
<string name="menu_advanced">Aurreratua</string>
|
||||
<string name="menu_view_profile">Ikusi profila</string>
|
||||
<string name="menu_view_profile">Ikusi kontua</string>
|
||||
<string name="menu_zoom_in">Hurbildu zooma</string>
|
||||
<string name="menu_zoom_out">Urrundu zooma</string>
|
||||
<string name="menu_save_log">Gorde egunkaria</string>
|
||||
<string name="menu_more_options">Aukera gehiago</string>
|
||||
<string name="menu_learn_spelling">Ikasi ortografia</string>
|
||||
<string name="jump_to_message">Joan mezura</string>
|
||||
<string name="jump_to_original_message">Joan jatorrizko mezura</string>
|
||||
<string name="copy_json">Kopiatu JSON</string>
|
||||
<string name="replace_draft">Ordeztu zirriborroa</string>
|
||||
<string name="title_share_location">Partekatu kokalekua taldeko kide guztiak</string>
|
||||
<string name="device_talk">Gailuaren mezuak</string>
|
||||
<string name="device_talk_subtitle">Lokalki sortutako mezuak</string>
|
||||
<string name="device_talk_explain">Txat honetako mezuak zure Delta Chat aplikazioak sortu ditu lokalki. Egileek aplikazioaren eguneraketei buruz eta erabileran arazoei buruz informatzeko erabiltzen dute.</string>
|
||||
<string name="device_talk_welcome_message2">Jarri harremanetan!\n\n🙌 Sakatu \"QR kodea\" bi gailuen pantaila nagusian. Hautatu \"Eskaneatu QR kodea\" gailu batean eta zuzendu bestera\n\n🌍 Gela berean ez bazaudete, eskaneatu bideo-dei baten bidez edo partekatu gonbidapen-esteka bat \"Eskaneatu QR kodea\" ataletik\n\nOndoren: Gozatu mezulari deszentralizatuaren esperientziaz. Ezagunagoak diren beste aplikazio batzuek ez bezala, kontrol zentralik gabe eta zu, zure lagunak, lankideak edo familia erakunde handiei jarraitu edo saldu gabe.</string>
|
||||
<string name="edit_contact">Editatu kontaktua</string>
|
||||
<!-- Verb "to pin", making something sticky, not a noun or abbreviation for "pin number". -->
|
||||
<string name="pin_chat">Finkatu txata</string>
|
||||
@@ -308,6 +356,14 @@
|
||||
<string name="pin">Finkatu</string>
|
||||
<!-- Opposite of "Pin chat", removing the sticky-state from a chat. -->
|
||||
<string name="unpin">Desfinkatu</string>
|
||||
<string name="ConversationFragment_quoted_message_not_found">Ez da jatorrizko mezua aurkitu</string>
|
||||
<string name="reply_privately">Erantzun modu pribatuan</string>
|
||||
<string name="source_code">Iturburu kodea</string>
|
||||
<!-- Menu item beside an app/chat that adds an icon to the system's home screen. If the user taps that icon, the app/chat is opened directly. -->
|
||||
<string name="add_to_home_screen">Gehitu hasierako pantailan</string>
|
||||
<string name="donate">Egin dohaintza</string>
|
||||
<string name="donate_device_msg">❤️ Badirudi Delta Chat-ekin gozatzen ari zarela!\n\nMesedez, pentsatu dohaintza bat egitea Delta Chat guztiontzat doakoa izan dadin laguntzeko.\n\nDelta Chat-en erabilera doakoa eta kode irekikoa den arren, garapenak dirua balio du. Lagundu iezaguzu Delta Chat independente mantentzen eta etorkizunean are hobea egiten.\n\nhttps://delta.chat/donate</string>
|
||||
|
||||
<string name="mute_for_one_hour">Mututu ordubete</string>
|
||||
<string name="mute_for_eight_hours">Mututu 8 ordu</string>
|
||||
<string name="mute_for_one_day">Mututu egun bat</string>
|
||||
@@ -320,9 +376,49 @@
|
||||
<string name="share_location_for_two_hours">2 orduz</string>
|
||||
<string name="share_location_for_six_hours">6 orduz</string>
|
||||
|
||||
<plurals name="ask_send_following_n_files_to">
|
||||
<item quantity="one">Bidali hurrengo fitxategia %s-(e)ra?</item>
|
||||
<item quantity="other">Bidali hurrengo %d fitxategiak %s(e)ra?</item>
|
||||
</plurals>
|
||||
<string name="file_saved_to">Fitxategia \"%1$s\" helbidean gordeta</string>
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Deitu</string>
|
||||
<string name="start_audio_call">Audio deia</string>
|
||||
<string name="start_video_call">Bideo deia</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Erantzun</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Ukatu</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Irteerako deia</string>
|
||||
<string name="outgoing_audio_call">Irteerako audio deia</string>
|
||||
<string name="outgoing_video_call">Irteerako bideo deia</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Sarrerako deia</string>
|
||||
<string name="incoming_audio_call">Sarrerako audio deia</string>
|
||||
<string name="incoming_video_call">Sarrerako bideo deia</string>
|
||||
<string name="declined_call">Ukatutako deia</string>
|
||||
<string name="canceled_call">Bertan behera utzitako deia</string>
|
||||
<string name="missed_call">Galdutako deia</string>
|
||||
<!-- the first placeholder will be replaced by a date, the second placeholder by duration, example: "Thu, 08:12 pm, 2 minutes" -->
|
||||
<string name="call_date_and_duration">%1$s, %2$s</string>
|
||||
|
||||
<!-- get confirmations -->
|
||||
<!-- confirmation for leaving groups or channels. If a subject is needed, "Are you sure you want to leave the chat?" would work as well -->
|
||||
<string name="ask_leave_group">Ziur irten nahi duzula?</string>
|
||||
<plurals name="ask_delete_chat">
|
||||
<item quantity="one">Ezabatu txat %d?</item>
|
||||
<item quantity="other">Ezabatu %d txat?</item>
|
||||
</plurals>
|
||||
<string name="ask_delete_named_chat">Ezabatu \"%1$s\" txata?</string>
|
||||
<string name="ask_delete_message">Ezabatu mezu hau?</string>
|
||||
<plurals name="ask_delete_messages">
|
||||
<item quantity="one">Ezabatu mezu %d?</item>
|
||||
<item quantity="other">Ezabatu %d mezu?</item>
|
||||
</plurals>
|
||||
<string name="ask_forward">Birbidali mezuak %1$s erabiltzaileari?</string>
|
||||
<string name="ask_forward_multiple">Bidali mezuak %1$d txatetara?</string>
|
||||
<string name="ask_export_attachment">Esportatu eranskina? Eranskinak esportatzeak zure beste gailuko beste aplikazioek atzitzea ahalbidetuko du.\n\nJarraitu?</string>
|
||||
<string name="ask_block_contact">Blokeatu kontaktu hau? Ez dituzu kontaktu honen mezu gehiago jasoko.</string>
|
||||
<string name="ask_unblock_contact">Desblokeatu kontaktu hau? Berriro jaso ahal izango dituzu kontaktu honen mezuak.</string>
|
||||
@@ -331,6 +427,11 @@
|
||||
<string name="ask_start_chat_with">Txateatu %1$s erabiltzailearekin?</string>
|
||||
<!-- %1$s is replaced by a comma-separated list of names -->
|
||||
<string name="ask_remove_members">Kendu %1$s taldetik?</string>
|
||||
<!-- %1$s is replaced by a comma-separated list of names -->
|
||||
<string name="ask_remove_from_channel">Ezabatu %1$s kanaletik?</string>
|
||||
<string name="open_url_confirmation">Esteka hau ireki nahi duzu?</string>
|
||||
|
||||
|
||||
<!-- contact list -->
|
||||
<string name="contacts_title">Kontaktuak</string>
|
||||
<string name="contacts_type_email_above">Idatzi e-mail helbidea goian</string>
|
||||
@@ -353,6 +454,10 @@
|
||||
<item quantity="one">Mezu berri %d</item>
|
||||
<item quantity="other">%d mezu berri</item>
|
||||
</plurals>
|
||||
<!-- The placeholder will be replaced by the name of the recipient in a one-to-one chat. -->
|
||||
<string name="chat_new_one_to_one_hint">Bidali mezu bat %1$s(r)i.</string>
|
||||
<!-- consider keeping the term "channel" as in WhatsApp or Telegram -->
|
||||
<string name="chat_new_channel_hint">Kanalak zure mezuak jende askori aldi berean helarazteko tresnak dira.</string>
|
||||
<string name="chat_new_group_hint">Idatzi lehen mezua, besteek taldera erantzutea baimenduz\n\n• Ez du axola denek ez badute Delta Chat erabiltzen.\n\n• Lehen mezua bidaltzeko denbora bat behar daiteke.</string>
|
||||
<string name="chat_record_slide_to_cancel">Irristatu ezeztatzeko</string>
|
||||
<string name="chat_record_explain">Sakatu eta mantendu ahots-mezu bat grabatzeko, askatu bidaltzeko.</string>
|
||||
@@ -361,32 +466,78 @@
|
||||
<string name="chat_share_with_title">Partekatu honekin</string>
|
||||
<string name="chat_input_placeholder">Mezua</string>
|
||||
<string name="chat_archived_label">Artxibatuta</string>
|
||||
<string name="chat_request_label">Eskaera</string>
|
||||
<string name="chat_request_label_explain">Sartu eskaerak kontagailuetan eta jakinarazpenetan</string>
|
||||
<string name="chat_no_messages">Mezurik ez.</string>
|
||||
<string name="chat_self_talk_subtitle">Nire buruari bidalitako mezuak</string>
|
||||
<string name="archive_empty_hint">Artxibatutako txatak hemen agertuko dira.</string>
|
||||
<!-- Action to add a message to "Saved Messages". The longer form (instead of "Save" only) is needed esp. on desktop to make clear this is not about saving a file to disk -->
|
||||
<string name="save_message">Gorde</string>
|
||||
<string name="saved_messages">Gordetako mezuak</string>
|
||||
<string name="saved_messages_explain">• Birbidali mezuak hona eskura izateko\n\n• Hartu oharrak edo ahots mezuak\n\n• Gehitu multimedia horietara</string>
|
||||
<!-- Should match "Saved" from "Saved messages" -->
|
||||
<string name="saved">Gordeta</string>
|
||||
<string name="save_as">Gorde honela</string>
|
||||
<string name="retry_send">Saiatu berriro mezua bidaltzen</string>
|
||||
<string name="cannot_display_unsuported_file_type">Ezin da fitxategi-mota hau bistaratu: %s</string>
|
||||
<string name="attachment_failed_to_load">Eranskina kargatzean huts egin du</string>
|
||||
<!-- For recording Voice messages: Description for the "Lock" button allowing to lift the thumb from the record button while recording continues -->
|
||||
<string name="lock_recording">Blokeatu grabazioa</string>
|
||||
|
||||
<!-- mailing lists -->
|
||||
<string name="mailing_list">Mailin zerrenda</string>
|
||||
|
||||
<!-- webxdc -->
|
||||
<!-- "Start..." button for an app -->
|
||||
<string name="start_app">Hasi...</string>
|
||||
<!-- this is a warning that is shown when one tries to send something to a chat that is not yet accepted. -->
|
||||
<string name="accept_request_first">Onartu txat-eskaera lehenik, mesedez.</string>
|
||||
<!-- title shown above a list of chats where one should be selected (eg. when sharing files from a webxdc). the placeholder will be replaced by a file name -->
|
||||
<string name="send_file_to">Bidali \"%1$s\" honi...</string>
|
||||
<!-- title shown above a list contacts where one should be selected (eg. when a webxdc attempts to send a message to a chat) -->
|
||||
<string name="send_message_to">Bidali mezua honi...</string>
|
||||
<string name="enable_realtime">Denbora errealeko aplikazioak</string>
|
||||
<string name="enable_realtime_explain">Gaitu denbora errealeko konexioak txatei atxikitako aplikazioentzat. Gaituz gero, baliteke txat-kideek zure IP helbidea ezagutu ahal izatea aplikazio bat abiarazten duzunean.</string>
|
||||
|
||||
<!-- map -->
|
||||
<string name="filter_map_on_time">Erakutsi kokalekuak denbora markoan</string>
|
||||
<string name="show_location_traces">Erakutsi lorratzak</string>
|
||||
<string name="add_poi">Bidali interesezko puntua</string>
|
||||
|
||||
|
||||
<!-- punycode warning / labeled links -->
|
||||
<!-- placeholder is domain/hostname that should be trusted -->
|
||||
<string name="open_external_url_trust_domain">Ez galdetu berriro honengatik: %1$s</string>
|
||||
<string name="puny_code_warning_header">Esteka susmagarria atzeman da</string>
|
||||
<!-- placeholder contains the hostname converted to ascii -->
|
||||
<string name="puny_code_warning_question">Ziur zaude %1$s bisitatu nahi duzula?</string>
|
||||
<!-- this message is shown whenever a link with non-latin characters is clicked. first placeholder is original hostname with special chars, second placeholder is hostname encoded in ascii -->
|
||||
<string name="puny_code_warning_description">Lotura honek alfabeto desberdinetako antzeko itxura duten karaktereak nahas ditzake. %1$s izeneko esteka jarraitzeak %2$s(e)ra eramango zaitu, eta hori ohikoa da ez-latindar karaktereentzat. Karaktere horiek espero ez bazenituen, esteka hau kaltegarria izan daitezke.</string>
|
||||
|
||||
|
||||
<!-- search -->
|
||||
<string name="search">Bilatu</string>
|
||||
<string name="search_in_chat">Bilatu txatetan</string>
|
||||
<string name="search_files">Bilatu fitxategiak</string>
|
||||
<string name="search_explain">Bilatu txatak, kontaktuak, eta mezuak.</string>
|
||||
<string name="search_no_result_for_x">Ez da emaitzarik aurkitu \"%s\" bilaketarentzat</string>
|
||||
<!-- Adjective, as in "Show Unread Messages" -->
|
||||
<string name="search_unread">Irakurri gabe</string>
|
||||
|
||||
|
||||
<!-- create/edit groups, contact/group profile -->
|
||||
<string name="group_name">Taldearen izena</string>
|
||||
<string name="group_avatar">Taldearen abatarra</string>
|
||||
<string name="remove_group_image">Ezabatu taldearen irudia</string>
|
||||
<string name="change_group_image">Aldatu taldearen irudia</string>
|
||||
<string name="group_create_button">Sortu taldea</string>
|
||||
<string name="group_please_enter_group_name">Idatzi izen bat taldearentzat.</string>
|
||||
<string name="group_add_members">Gehitu kideak</string>
|
||||
<string name="group_self_not_in_group">Taldeko kidea izan behar zara ekintza hau burutzeko.</string>
|
||||
<string name="profile_encryption">Zifratzea</string>
|
||||
<string name="profile_shared_chats">Partekatutako txatak</string>
|
||||
<!-- Separator between the list of actual members and past members -->
|
||||
<string name="past_members">Kide izandakoak</string>
|
||||
<string name="tab_contact">Kontaktua</string>
|
||||
<string name="tab_group">Taldea</string>
|
||||
<string name="tab_gallery">Galeria</string>
|
||||
@@ -395,10 +546,99 @@
|
||||
<string name="tab_map">Mapa</string>
|
||||
<string name="tab_gallery_empty_hint">Txat honetan partekatutako irudi eta bideoak agertuko dira hemen</string>
|
||||
<string name="tab_docs_empty_hint">Txat honetan partekatutako dokumentuak, musika, eta bestelako fitxategiak agertuko dira hemen</string>
|
||||
<string name="tab_image_empty_hint">Txat honi erantsitako irudiak hemen agertuko dira.</string>
|
||||
<string name="tab_video_empty_hint">Txat honi erantsitako bideoak hemen agertuko dira.</string>
|
||||
<string name="tab_audio_empty_hint">Txat honi erantsitako fitxategiak eta audio mezuak hemen agertuko dira.</string>
|
||||
<string name="tab_webxdc_empty_hint">Txat honi erantsitako aplikazioak hemen agertuko dira.</string>
|
||||
<string name="tab_all_media_empty_hint">Edozein txati erantsitako multimedia-fitxategiak hemen agertuko dira.</string>
|
||||
<string name="all_files_empty_hint">Edozein txati erantsitako dokumentuak eta bestelako fitxategiak hemen agertuko dira.</string>
|
||||
<string name="all_apps_empty_hint">Edozein txati erantsitako aplikazioak hemen agertuko dira.</string>
|
||||
<string name="media_preview">Multimediaren aurrebista</string>
|
||||
<!-- option to show images in the gallery with the correct width/height aspect (instead of square); other gallery apps may be a source of inspiration for translation :) -->
|
||||
<string name="aspect_ratio_grid">Proportzio-sareta</string>
|
||||
<!-- option to show images in the gallery as square (instead of using correct width/height) -->
|
||||
<string name="square_grid">Lauki-sareta</string>
|
||||
<string name="send_message">Bidali mezua</string>
|
||||
|
||||
<!-- Multi Device -->
|
||||
<!-- "Second Device" can also be translated as "Another Device", if that is catchier in the destination language. However, make sure to use the term consistently. -->
|
||||
<string name="multidevice_title">Gehitu bigarren gailua</string>
|
||||
<string name="multidevice_same_network_hint">Ziurtatu gailu biak Wi-Fi edo sare berera konektatuta daudela.</string>
|
||||
<string name="multidevice_this_creates_a_qr_code">Honek QR kode bat sortuko du, bigarren gailuak eskaneatu eta profila kopiatu dezan.\n\nZiurtatu zuk nahi ez duzun inork ez ezein kamerak ezin duela ondorengo pantaila ikusi.</string>
|
||||
<string name="multidevice_install_dc_on_other_device">Instalatu Delta Chat zure beste gailuan (https://get.delta.chat)</string>
|
||||
<!-- "I Already Have a Profile / Add as Second Device” should be the same text as defined by the keys onboarding_alternative_logins and multidevice_receiver_title -->
|
||||
<string name="multidevice_tap_scan_on_other_device">Abiarazi Delta Chat, sakatu “Badut profil bat / Gehitu bigarren gailu gisa” eta eskaneatu hemen agertzen den kodea.</string>
|
||||
<!-- Shown inside a "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the profile name eg. "Scan to set up second device for Alice" -->
|
||||
<string name="multidevice_qr_subtitle">Eskaneatu %1$s(r)entzat bigarren gailu bat konfiguratzeko</string>
|
||||
<string name="multidevice_receiver_title">Gehitu bigarren gailu gisa</string>
|
||||
<string name="multidevice_open_settings_on_other_device">Lehenengo gailuan, abiarazi Delta Chat, joan hona: “Ezarpenak / Gehitu bigarren gailua“, eta eskaneatu bertan agertzen den kodea.</string>
|
||||
<string name="multidevice_receiver_scanning_ask">Kopiatu kontua beste gailutik gailu honetara?</string>
|
||||
<string name="multidevice_receiver_needs_update">Inportatu nahi duzun kontua Delta Chat-en bertsio berriago batena da.\n\nBigarren gailua konfiguratzen jarraitzeko, mesedez, eguneratu gailu hau Delta Chat-en azken bertsiora.</string>
|
||||
<string name="multidevice_abort">Bertan behera utzi bigarren gailuaren konfigurazioa?</string>
|
||||
<string name="multidevice_abort_will_invalidate_copied_qr">Honek arbelean kopiatutako QR kodea baliogabetuko du.</string>
|
||||
<string name="multidevice_transfer_done_devicemsg">ℹ️ Kontua zure bigarren gailura transferitu da.</string>
|
||||
<!-- Shown beside progress bar, stay short -->
|
||||
<string name="preparing_account">Kontua prestatzen...</string>
|
||||
<!-- Shown beside progress bar, stay short -->
|
||||
<string name="transferring">Transferitzen...</string>
|
||||
<string name="troubleshooting">Arazoak konpontzea</string>
|
||||
|
||||
<!-- Connectivity -->
|
||||
<!-- Headline for the "Inbox" eg. in the "Connectivity" view -->
|
||||
<string name="incoming_messages">Sarrerako mezuak</string>
|
||||
<!-- Headline for the "Outbox" eg. in the "Connectivity" view -->
|
||||
<string name="outgoing_messages">Irteerako mezuak</string>
|
||||
<!-- deprecated -->
|
||||
<string name="storage_on_domain">%1$s(e)ko biltegiratzea</string>
|
||||
<string name="connectivity">Konexioa</string>
|
||||
<!-- Shown in the title bar if the app is "Not connected"; prefer short strings. -->
|
||||
<string name="connectivity_not_connected">Konektatu gabe</string>
|
||||
<!-- Shown in the title bar if the app is "Connecting"; prefer short strings. The ellipsis is a single character (…), not three (...) -->
|
||||
<string name="connectivity_connecting">Konektatzen...</string>
|
||||
<!-- Shown in the title bar if the app is "Updating" (eg. getting new/old message, sync things); prefer short strings. The ellipsis is a single character (…), not three (...) -->
|
||||
<string name="connectivity_updating">Eguneratzen...</string>
|
||||
<!-- Shown in the setting if the app is "Connected" -->
|
||||
<string name="connectivity_connected">Konektatuta</string>
|
||||
<string name="sending">Bidaltzen...</string>
|
||||
<string name="last_msg_sent_successfully">Azken mezua ondo bidali da.</string>
|
||||
<string name="not_supported_by_provider">Zure hornitzaileak ez du onartzen.</string>
|
||||
<!-- Subtitle in quota context of "Connectivity" view. Should be be plural always, no number is prefixed. -->
|
||||
<string name="messages">Mezuak</string>
|
||||
<!-- Used for describing resource usage, resulting string will be eg. "1.2 GiB of 3 GiB used" -->
|
||||
<string name="part_of_total_used">%2$setik %1$s erabilita</string>
|
||||
|
||||
|
||||
<!-- welcome and login -->
|
||||
<!-- Primary button on the welcome screen, allows to create an instant profile -->
|
||||
<string name="onboarding_create_instant_account">Sortu kontu berria</string>
|
||||
<!-- Secondary button on the welcome screen, allows to "Add as Second Device", "Restore from Backup" -->
|
||||
<string name="onboarding_alternative_logins">Badut kontu bat</string>
|
||||
<!-- This is a button and a title, allowing to use existing, classic email, setting ports, passwords and so on -->
|
||||
<string name="manual_account_setup_option">Erabili eposta klasikoa errele gisa</string>
|
||||
<!-- Instant onboarding title (there is not more to do than to set name and avatar) -->
|
||||
<string name="instant_onboarding_title">Zure kontua</string>
|
||||
<!-- The placeholder will be replaced by the default onboarding server -->
|
||||
<string name="instant_onboarding_agree_default2">%1$s(r)en pribatutasun-politika</string>
|
||||
<!-- The placeholder will be replaced by instance name, the whole text will link to the instance page -->
|
||||
<string name="instant_onboarding_agree_instance">%1$s(e)ko kontuei buruz</string>
|
||||
<!-- Confirmation button on the instant onboarding screen -->
|
||||
<string name="instant_onboarding_create">Ados eta sortu kontua</string>
|
||||
<!-- Secondary, link-like button to open a page with other possible instances -->
|
||||
<string name="instant_onboarding_show_more_instances">Erabili beste zerbitzari bat</string>
|
||||
<string name="instant_onboarding_other_server">Zerrendatu txatmail zerbitzariak</string>
|
||||
<!-- Hint about what happens when "Create Profile" button in pressed; the placeholder will be replaced by the group name -->
|
||||
<string name="instant_onboarding_group_info">Sortu kontu bat \"%1$s\" taldean sartzeko.</string>
|
||||
<!-- Hint about what happens when "Create Profile" button in pressed; the placeholder will be replaced by contact name -->
|
||||
<string name="instant_onboarding_contact_info">Sortu profil bat %1$s-(r)ekin txateatzeko.</string>
|
||||
<!-- Question shown when another user's QR code is scanned from onboarding screen -->
|
||||
<string name="instant_onboarding_confirm_contact">Sortu kontu berri bat eta hasi %1$s(r)ekin txateatzen?</string>
|
||||
<!-- Question shown when group's/channel's QR code is scanned from onboarding screen -->
|
||||
<string name="instant_onboarding_confirm_group">Sortu profil berri bat eta sartu \"%1$s\"(e)n?</string>
|
||||
|
||||
<string name="welcome_chat_over_email">Txat deszentralizatu segurua</string>
|
||||
<string name="scan_invitation_code">Eskaneatu gonbidapen kodea</string>
|
||||
<string name="login_title">Hasi saioa</string>
|
||||
<string name="login_advanced_hint">Saio-hasiera hau erabiltzaile aurreratuentzat da:\n\n• Ez erabili beste aplikazio batean erabiltzen ari zaren helbiderik.\n\n• Posta elektronikoko zerbitzari klasikoak txatak baimentzen ditu, muturretik muturrera zifratu gabe, posta-ikono batek markatuta.</string>
|
||||
<string name="login_inbox">Sarrera ontzia</string>
|
||||
<string name="login_imap_login">IMAP erabiltzaile-izena</string>
|
||||
<string name="login_imap_server">IMAP zerbitzaria</string>
|
||||
@@ -410,25 +650,70 @@
|
||||
<string name="login_smtp_server">SMTP zerbitzaria</string>
|
||||
<string name="login_smtp_port">SMTP ataka</string>
|
||||
<string name="login_smtp_security">SMTP segurtasuna</string>
|
||||
<!-- the word "Proxy" might be left untranslated unless the destination language has a well-known term for a "Proxy Server", acting intermediary between the app and the server -->
|
||||
<string name="proxy_settings">Proxya</string>
|
||||
<string name="proxy_use_proxy">Erabili proxya</string>
|
||||
<string name="proxy_add">Gehitu proxya</string>
|
||||
<string name="proxy_add_explain">Onartutako proxy motak: HTTP(S), SOCKS5 eta Shadowsocks.</string>
|
||||
<string name="proxy_add_url_hint">Sartu proxyaren esteka hemen</string>
|
||||
<string name="proxy_invalid">Proxy baliogabea edo ez-bateragarria</string>
|
||||
<string name="proxy_list_header">Gordetako proxyak</string>
|
||||
<string name="proxy_delete">Ezabatu proxya</string>
|
||||
<string name="proxy_delete_explain">Ziur zaude \"%1$s\" ezabatu nahi duzula?</string>
|
||||
<string name="proxy_use_proxy_confirm">\"%1$s\" proxia erabili nahi duzu?</string>
|
||||
<string name="proxy_share_explain">Zure lagunek QR kodea eskaneatuta gehitu dezakete proxy hau.</string>
|
||||
<string name="proxy_share_link">Partekatu esteka</string>
|
||||
<string name="proxy_enabled">Proxya gaitu da</string>
|
||||
<string name="proxy_enabled_hint">Proxy bat erabiltzen ari zara. Konektatzeko arazoak badituzu, probatu beste proxy bat.</string>
|
||||
<!-- "Relay" refers to the relay servers used; please chose a common term in your language, no need to be literal. If in doubt, stay with "Relay" -->
|
||||
<string name="transports">Erreleak</string>
|
||||
<string name="add_transport">Gehitu errelea</string>
|
||||
<string name="remove_transport">Ezabatu errelea</string>
|
||||
<string name="edit_transport">Editatu errelea</string>
|
||||
<!-- shown if a QR code was scanned that can be used as a relay -->
|
||||
<string name="confirm_add_transport">Gehitu errelea?</string>
|
||||
<string name="invalid_transport_qr">Eskaneatutako QR kodeak ez dauka baliozko errelerik.</string>
|
||||
<!-- placeholder will be replaced by a relay server name -->
|
||||
<string name="confirm_remove_transport">\"%1$s\" errelea kendu?\n\nZure kontaktuak soilik jar daitezke zurekin harremanetan aurretik beste errele baten bidez haiekin harremanetan jarri bazara.\n\nZalantzarik baduzu, kendu errelea geroago.</string>
|
||||
|
||||
<string name="login_certificate_checks">Ziurtagiri-egiaztaketak</string>
|
||||
<string name="login_error_mail">Sartu baliozko e-mail helbide bat</string>
|
||||
<string name="login_error_server">Sartu baliozko zerbitzari / IP helbide bat</string>
|
||||
<string name="login_error_port">Sartu baliozko ataka bat (1–65535)</string>
|
||||
<string name="login_error_required_fields">Sartu baliozko e-mail helbidea eta pasahitza</string>
|
||||
<string name="import_backup_title">Inportatu babes-kopia</string>
|
||||
<string name="import_backup_ask">Babes-kopia aurkitu da: \"%1$s\".\n\nInportatu nahi duzu eta bertako datu eta ezarpenak erabili?</string>
|
||||
<string name="import_backup_no_backup_found">Ez da babes-kopiarik aurkitu.\n\nKopiatu babes-kopia \"%1$s\" karpetan eta saiatu berriro.</string>
|
||||
<string name="import_backup_title">Inportatu babeskopia</string>
|
||||
<string name="import_backup_ask">Babeskopia aurkitu da: \"%1$s\".\n\nInportatu nahi duzu eta bertako datu eta ezarpenak erabili?</string>
|
||||
<string name="import_backup_no_backup_found">Ez da babeskopiarik aurkitu.\n\nKopiatu babeskopia \"%1$s\" karpetan eta saiatu berriro.</string>
|
||||
<!-- %1$s will be replaced by the failing address -->
|
||||
<string name="login_error_cannot_login">Ezin da \"%1$s\" bezala saioa hasi. Egiaztatu E-mail helbidea eta pasahitza zuzenak diren.</string>
|
||||
<!-- TLS certificate checks -->
|
||||
<string name="accept_invalid_certificates">Onartu ziurtagiri baliogabeak</string>
|
||||
<string name="switch_account">Aldatu kontua</string>
|
||||
<string name="add_account">Gehitu kontua</string>
|
||||
<!-- for translations, you can also think of "Profile Tag" or "Profile Description" as the source string -->
|
||||
<string name="profile_tag">Kontuaren etiketa</string>
|
||||
<string name="profile_tag_hint">Adib. Lana, Familia</string>
|
||||
<string name="profile_tag_explain">Ezarri etiketa bat zuretzat bakarrik ikusgai egongo dena; zure kotuen artean bereizten lagunduko dizu.</string>
|
||||
<!-- Menu entry to sort an item to the beginning of a list. Only "To Top" may do as well in some translations, if that helps to stay shorter. -->
|
||||
<string name="move_to_top">Mugitu gora</string>
|
||||
<string name="delete_account">Ezabatu kontua</string>
|
||||
<string name="delete_account_ask">Ziur al zaude zure kontuaren datuak ezabatu nahi dituzula?</string>
|
||||
<string name="delete_account_explain_with_name">Gailu honetako \"%s\" profilaren datu guztiak ezabatuko dira, zifratze-konfigurazioa, kontaktuak, txatak, mezuak eta multimedia barne. Ekintza hau ezin da desegin.</string>
|
||||
<string name="unconfigured_account">Konfiguratu gabeko kontua</string>
|
||||
<string name="unconfigured_account_hint">Ireki kontua konfiguratzeko.</string>
|
||||
<string name="try_connect_now">Saiatu orain konektatzen</string>
|
||||
<string name="sync_all">Sinkronizatu guztiak</string>
|
||||
<!-- Translations: %1$s will be replaced by a more detailed error message -->
|
||||
<string name="configuration_failed_with_error">Konfigurazioak huts egin du. Errorea: %1$s</string>
|
||||
|
||||
<!-- share and forward messages -->
|
||||
<!-- Translators: shown above a chat/contact list when selecting recipients to forward messages -->
|
||||
<string name="forward_to">Birbidali honi …</string>
|
||||
<!-- first placeholder is replaced by the number of files (always 2 or more); second placeholder is replaced by a chat name -->
|
||||
<string name="ask_send_files_to_chat">Bidali %1$d fitxategiak \"%2$s\"(e)ra?</string>
|
||||
<string name="ask_send_files_to_selected_chats">Bidali %1$d fitxategia(k) %2$d txatetara?</string>
|
||||
<string name="videos_sent_without_recoding">(Bideoak jatorrizko fitxategi handi gisa bidaltzen dira. Bideoak fitxategi txikiago gisa bidaltzeko, erantsi itzazu bereizita)</string>
|
||||
<string name="share_text_multiple_chats">Bidali testua hau %1$d txatetara?\n\n\"%2$s\"</string>
|
||||
<string name="share_abort">Partekatzea eten da baimenak falta direlako.</string>
|
||||
|
||||
|
||||
@@ -438,23 +723,30 @@
|
||||
<string name="pref_profile_info_headline">Zure profileko informazioa</string>
|
||||
<string name="pref_profile_photo">Profileko argazkia</string>
|
||||
<string name="pref_blocked_contacts">Blokeatutako kontaktuak</string>
|
||||
<string name="blocked_empty_hint">Blokeatutako kontaktuak hemen agertuko dira.</string>
|
||||
<string name="pref_who_can_see_profile_explain">Zure profileko argazkia eta izena zure mezuekin batera erakutsiko dira beste erabiltzaileekin komunikatzen zarenean. Informazioa behin bidalita ezin da ezabatu edo kendu.</string>
|
||||
<string name="pref_your_name">Zure izena</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Sinaduraren testua</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter teklarekin bidali</string>
|
||||
<string name="pref_enter_sends_explain">Enter tekla sakatzeak mezua bidaliko du</string>
|
||||
<string name="pref_outgoing_media_quality">Bidalitako multimediaren kalitatea</string>
|
||||
<string name="pref_outgoing_balanced">Orekatua</string>
|
||||
<string name="pref_outgoing_worse">Kalitate txarragoa, tamaina txikia</string>
|
||||
<string name="pref_vibrate">Bibratu</string>
|
||||
<string name="pref_screen_security">Pantaila segurtasuna</string>
|
||||
<string name="pref_screen_security">Pantaila-segurtasuna</string>
|
||||
<!-- Translators: Must indicate that there is no guarantee as the system may not honor our request. -->
|
||||
<string name="pref_screen_security_explain">Eskatu pantaila-argazkiak blokeatzea azkenak zerrendan eta aplikazio barruan.</string>
|
||||
<string name="pref_screen_security_please_restart_hint">Pantailaren segurtasun ezarpenak aplikatzeko berrabiarazi aplikazioa.</string>
|
||||
<string name="pref_screen_security_explain">Eskatu pantaila-argazkiak blokeatzea azkenen zerrendan eta aplikazio barruan.</string>
|
||||
<string name="pref_screen_security_please_restart_hint">Pantailaren segurtasun-ezarpenak aplikatzeko berrabiarazi aplikazioa.</string>
|
||||
<string name="pref_notifications">Jakinarazpenak</string>
|
||||
<string name="pref_mention_notifications">Aipamenak</string>
|
||||
<string name="pref_mention_notifications_explain">Mutututako taldeetan, jaso zuretzat diren mezuen jakinarazpenak, hala nola erantzunak edo erreakzioak</string>
|
||||
<string name="pref_notifications_show">Erakutsi</string>
|
||||
<string name="pref_notifications_priority">Lehentasuna</string>
|
||||
<string name="pref_notifications_explain">Gaitu sistemaren jakinarazpenak mezu berrientzat</string>
|
||||
<string name="pref_show_notification_content">Erakutsi mezuaren edukia jakinarazpenean</string>
|
||||
<string name="pref_show_notification_content_explain">Erakutsi bidaltzailea eta mezuaren lehen hitza jakinarazpenetan</string>
|
||||
<string name="pref_led_color">LED kolorea</string>
|
||||
<string name="pref_sound">Soinua</string>
|
||||
<string name="pref_silent">Isila</string>
|
||||
@@ -468,52 +760,128 @@
|
||||
<string name="pref_appearance">Itxura</string>
|
||||
<string name="pref_theme">Azala</string>
|
||||
<string name="pref_language">Hizkuntza</string>
|
||||
<string name="pref_use_system_ui_font">Erabili sistemaren letra-mota</string>
|
||||
<string name="pref_incognito_keyboard">Teklatu pribatua</string>
|
||||
<!-- Translators: Must indicate that there is no guarantee as the system may not honor our request. -->
|
||||
<string name="pref_incognito_keyboard_explain">Eskatu teklatuari pertsonalizatutako ikasketa desgaitzea</string>
|
||||
<string name="pref_read_receipts">Irakurragiriak</string>
|
||||
<string name="pref_read_receipts_explain">Irakurragiriak desgaituta badaude, ezin izango dituzu besteen irakurragiriak ikusi.</string>
|
||||
<string name="pref_server">Zerbitzaria</string>
|
||||
<string name="pref_encryption">Zifratua</string>
|
||||
<string name="pref_manage_keys">Kudeatu gakoak</string>
|
||||
<string name="pref_chats">Txatak</string>
|
||||
<string name="pref_in_chat_sounds">Txat bitarteko soinuak</string>
|
||||
<string name="pref_in_chat_sounds">Txat barruko soinuak</string>
|
||||
<string name="pref_view_log">Ikusi egunkaria</string>
|
||||
<string name="pref_saved_log">Egunkaria deskargen karpetan gorde da</string>
|
||||
<string name="pref_save_log_failed">Huts egin du egunkaria gordetzean</string>
|
||||
<string name="pref_log_header">Egunkaria</string>
|
||||
<string name="pref_other">Bestelakoa</string>
|
||||
<string name="pref_backup">Babeskopia</string>
|
||||
<string name="pref_backup_explain">Egin txaten babes-kopia kanpo biltegian</string>
|
||||
<string name="pref_backup_export_explain">Babes-kopia batek instalazio berri bat ezartzen laguntzen dizu, bai gailu honetan zein beste batean.\n\nBabes-kopiak mezu guztiak, kontaktuak eta txatak, eta zure Autocrypt ezarpena daramatza. Gorde babes-kopiaren fitxategia toki seguruan edo ezabatu ahalik eta lasterren.</string>
|
||||
<string name="pref_backup_export_start_button">Hasi babes-kopia</string>
|
||||
<string name="pref_backup_written_to_x">Babes-kopia ongi idatzi da hemen: %1$s</string>
|
||||
<string name="pref_backup_explain">Egin txaten babeskopia kanpo biltegian</string>
|
||||
<string name="pref_backup_export_explain">Babeskopia batek instalazio berri bat ezartzen laguntzen dizu, bai gailu honetan zein beste batean.\n\nBabeskopiak mezu guztiak, kontaktuak eta txatak, eta zure Autocrypt ezarpena daramatza. Gorde babeskopiaren fitxategia toki seguruan edo ezabatu ahalik eta lasterren.</string>
|
||||
<string name="pref_backup_export_this">Esportatu kontu hau</string>
|
||||
<!-- the placeholder will be replaced by the number of profiles to export; the number is always larger than 1 -->
|
||||
<string name="pref_backup_export_all">Esportatu %1$d kontu guztiak</string>
|
||||
<string name="pref_backup_export_start_button">Hasi babeskopia</string>
|
||||
<string name="pref_backup_written_to_x">Babeskopia ongi idatzi da hemen: %1$s</string>
|
||||
<!-- No need to translate "Wallpaper" literally. Chose what is common in your language for a "Wallpaper" or a "Background". Avoid adding the term "image" here, as the "Wallpaper" may also be just a single color. -->
|
||||
<string name="pref_background">Atzealdea</string>
|
||||
<string name="pref_background_btn_default">Erabili lehenetsitako irudia</string>
|
||||
<string name="pref_background_btn_default">Erabili irudi lehenetsia</string>
|
||||
<string name="pref_background_btn_gallery">Hautatu galeriatik</string>
|
||||
<string name="pref_imap_folder_warn_disable_defaults">Aukera hau desaktibatuz gero, egiaztatu zure zerbitzaria eta beste bezeroen konfigurazioa bat datorrela.\n\nBestela agian gauzak ez dabiltza.</string>
|
||||
<!-- No need to be literal here, you can also use "Use Multiple Devices", "Support Multiple Devices" or other fitting terms. However, it should fit to the wording or your language at https://delta.chat/help -->
|
||||
<string name="pref_multidevice">Gailu anitzeko modua</string>
|
||||
<string name="pref_multidevice_explain">Sinkronizatu zure mezuak zure beste gailuekin. Automatikoki gaitzen da bigarren gailu bat gehitzean.</string>
|
||||
<string name="pref_multidevice_change_warn">Gailu anitzeko moduak gaituta egon behar du kontu bera hainbat gailutan erabiltzean. Desaktibatu ezarpen hau soilik kontu hau beste gailu guztietatik kendu baduzu.\n\nGailu anitzeko modua desaktibatzeak kontua hainbat gailutan erabiltzen ari den bitartean, mezuak galtzea eta bestelako arazoak eragingo ditu.</string>
|
||||
<string name="pref_auto_folder_moves">Automatikoki mugitzen du DeltaChat karpetara</string>
|
||||
<string name="pref_only_fetch_mvbox_title">Delta Chat karpetatik soilik berreskuratu</string>
|
||||
<string name="pref_show_emails">Erakutsi ohiko e-mailak</string>
|
||||
<string name="pref_show_emails_no">Ez, txatak besterik ez</string>
|
||||
<string name="pref_show_emails_accepted_contacts">Onartutako kontaktuena</string>
|
||||
<string name="pref_show_emails_all">Denak</string>
|
||||
<string name="pref_experimental_features">Ezaugarri esperimentalak</string>
|
||||
<string name="pref_on_demand_location_streaming">Eskaera bidezko kokalekuaren hedapena</string>
|
||||
<string name="pref_background_default">Lehenetsitako atzealdea</string>
|
||||
<string name="pref_background_default_color">Lehenetsitako kolorea</string>
|
||||
<string name="pref_experimental_features_explain">Baliteke ezaugarri hauek ezegonkorrak izatea eta gerora aldatzea edo kentzea.</string>
|
||||
<string name="pref_on_demand_location_streaming">Eskaripeko kokapena zuzenean partekatzea</string>
|
||||
<string name="pref_background_default">Atzealde lehenetsia</string>
|
||||
<string name="pref_background_default_color">Kolore lehenetsia</string>
|
||||
<string name="pref_background_custom_image">Irudi pertsonalizatua</string>
|
||||
<string name="pref_background_custom_color">Kolore pertsonalizatua</string>
|
||||
<string name="export_aborted">Esportazioa bertan behera geratu da.</string>
|
||||
<string name="auto_download_messages">Deskargatu mezuak automatikoki</string>
|
||||
<!-- %1$s will be replaced by a human-readable number of bytes, eg. 32 KiB, 1 MiB -->
|
||||
<string name="up_to_x">%1$s arte</string>
|
||||
<string name="up_to_x_most_worse_quality_images">%1$s arte: kalitate txarreneko irudiak</string>
|
||||
<string name="up_to_x_most_balanced_quality_images">%1$s arte: kalitate orekatueneko irudiak</string>
|
||||
<string name="download_failed">Deskargak huts egin du</string>
|
||||
<!-- %1$s will be replaced by a human-readable number of bytes, eg. 32 KiB, 1 MiB. Resulting string eg. "1 MiB message" -->
|
||||
<string name="n_bytes_message">%1$s mezu</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Deskargatu eskuragarri dagoen gehienezkoa %1$s arte</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Aukeratu kontua</string>
|
||||
<string name="profile_image_select">Aukeratu abatarra</string>
|
||||
<string name="select_your_new_profile_image">Aukeratu zure abatar berria</string>
|
||||
<string name="profile_image_delete">Ezabatu abatarra</string>
|
||||
<string name="pref_show_tray_icon">Erakutsi sistema-erretilu ikonoa</string>
|
||||
<string name="pref_edit_profile">Editatu kontua</string>
|
||||
<string name="disable_imap_idle">Desgaitu IMAP IDLE</string>
|
||||
<string name="disable_imap_idle_explain">Ez erabili IMAP IDLE luzapena, zerbitzariak onartzen badu ere. Aukera hau gaitzeak mezuen berreskuratzea atzeratuko du, gaitu ezazu probak egiteko soilik.</string>
|
||||
<string name="send_stats_to_devs">Bidali estatistikak Delta Chat-eko garatzaileei</string>
|
||||
<string name="stats_device_message">Delta Chat hobetzen lagundu eta ikerketa babestu nahi duzu astero erabilera-estatistika anonimoak bidalita?\n\n👉 Sakatu hemen… 👈</string>
|
||||
<string name="stats_confirmation_dialog">Delta Chat hobetzen lagundu eta ikerketa babestu nahi duzu astero erabilera-estatistika anonimoak bidalita?</string>
|
||||
<string name="stats_thanks">Eskerrik asko! Bidalketa edozein unetan desgaitu dezakezu \"Ezarpenak -> Aurreratua\" atalean.\n\nBestalde, Delta Chat-en segurtasunari buruzko ikerketa zientifiko batean parte hartzeko 5 minutu dituzu?</string>
|
||||
<string name="stats_disable_dialog">Estatistiken bidalketa gaituta dago jada.\n\nDesaktibatu nahi duzu?</string>
|
||||
<string name="disable">Desgaitu</string>
|
||||
<string name="stats_keep_sending">Bidaltzen jarraitu</string>
|
||||
<string name="stats_msg_body">Eranskinak erabilera-estatistika anonimoak ditu, Delta Chat hobetzen laguntzen digutenak. Ikusi https://delta.chat/help#statssending informazio gehiago lortzeko. Eskerrik asko!</string>
|
||||
|
||||
<!-- Emoji picker and categories -->
|
||||
<string name="emoji_search_results">Bilatu emaitzak</string>
|
||||
<string name="emoji_not_found">Ez da emojirik aurkitu</string>
|
||||
<string name="emoji_recent">Azkenaldian erabiliak</string>
|
||||
<string name="emoji_people">Pertsonak eta gorputza</string>
|
||||
<string name="emoji_nature">Animaliak eta natura</string>
|
||||
<string name="emoji_foods">Janaria eta edaria</string>
|
||||
<string name="emoji_activity">Aktibitatea</string>
|
||||
<string name="emoji_places">Bidaiak eta lekuak</string>
|
||||
<string name="emoji_objects">Objetuak</string>
|
||||
<string name="emoji_symbols">Sinboloak</string>
|
||||
<string name="emoji_flags">Banderak</string>
|
||||
|
||||
<!-- Reactions -->
|
||||
<string name="reactions">Erreakzioak</string>
|
||||
<!-- Verb, the action of adding a "Reaction" to a message. Used eg. in context menus, similar to "Reply" or "Forward" -->
|
||||
<string name="react">Erreakzionatu</string>
|
||||
<!-- %1$s will be replaced by an emoji. %2$s will be replaced by message summary (the summary is often long and whole string gets truncated; words after %2$s will often not being visible). Eg. 'You reacted 👍 to "Found my suitcase"'. Use less than 20 characters, otherwise the string will be truncated too soon and too few information are shown. Do not try to translate "reacted to" too strict. Depending on the language, "added 👍 to" or "gave 👍 to" or just "👍 to" may be shorter and/or clearer and work as well. -->
|
||||
<string name="reaction_by_you">%1$s erreakzionatu zenion \"%2$s\"(e)ri.</string>
|
||||
<!-- %1$s will be replaced a name. %2$s will be replaced by an emoji. %3$s will be replaced by message summary (the summary is often long and whole string gets truncated; words after %3$s will often not being visible). Eg. 'Alice reacted 👍 to "Nice photos"'. Use less than 20 characters, otherwise the string will be truncated too soon and too few information are shown. Do not try to translate "reacted to" too strict. Depending on the language, "added 👍 to" or "gave 👍 to" or just "👍 to" may be shorter and/or clearer work as well. -->
|
||||
<string name="reaction_by_other">%1$s(e)k %2$s erreakzionatu zion \"%3$s\"(e)ri</string>
|
||||
|
||||
<!-- automatically delete message -->
|
||||
<string name="delete_old_messages">Ezabatu mezu zaharrak</string>
|
||||
<string name="autodel_device_title">Ezabatu mezuak gailutik</string>
|
||||
<string name="autodel_server_title">Ezabatu mezuak zerbitzaritik</string>
|
||||
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
|
||||
<string name="autodel_device_ask">%1$d mezu ezabatu nahi dituzu orain eta \"%2$s\" etorkizunean jasotako mezuak ere?\n\n• Honek multimedia ere barne hartzen du\n\n• Mezuak ikusi ala ez ezabatuko dira\n\n• \"Gordetako mezuak\" ez dira lokalki ezabatuko</string>
|
||||
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
|
||||
<string name="autodel_server_ask">%1$d mezu ezabatu nahi dituzu orain eta \"%2$s\" etorkizunean jasotako mezuak ere?\n\n⚠️ Honek mezu elektronikoak, multimedia eta \"Gordetako mezuak\" barne hartzen ditu zerbitzariko karpeta guztietan\n\n⚠️ Ez erabili funtzio hau datuak zerbitzarian gorde nahi badituzu edo posta bezero klasikoak ere erabiltzen badituzu</string>
|
||||
<!-- shown below enabled autodel_server-option, should be a summary of autodel_server_ask and remind about the impact -->
|
||||
<string name="autodel_server_enabled_hint">Honek barne hartzen ditu mezu elektronikoak, multimedia eta \"Gordetako mezuak\" zerbitzariko karpeta guztietan. Ez erabili funtzio hau datuak zerbitzarian gorde nahi badituzu edo mezu elektronikoen bezero klasikoak ere erabiltzen badituzu.</string>
|
||||
<string name="autodel_server_warn_multi_device_title">Berehalako ezabatzea aktibatu</string>
|
||||
<string name="autodel_server_warn_multi_device">Berehalako ezabaketa gaitzen baduzu, ezin izango dituzu gailu anitz erabili profil honetan.</string>
|
||||
<string name="autodel_confirm">Ulertzen dut, ezabatu mezuk guzti hauek</string>
|
||||
<!-- "At once" in the meaning of "Immediately", without any intervening time. -->
|
||||
<string name="autodel_at_once">Berehala</string>
|
||||
<string name="after_5_minutes">5 minutu eta gero</string>
|
||||
<string name="autodel_after_1_hour">Ordubete eta gero</string>
|
||||
<string name="autodel_after_1_day">Egun bat eta gero</string>
|
||||
<string name="autodel_after_1_week">Aste bat eta gero</string>
|
||||
<string name="after_5_weeks">5 aste eta gero</string>
|
||||
<string name="autodel_after_1_year">Urtebete eta gero</string>
|
||||
|
||||
<!-- system messages -->
|
||||
<string name="systemmsg_subject_for_new_contact">%1$s(r)en mezua</string>
|
||||
<string name="systemmsg_failed_sending_to">Huts egin du %1$s(r)i mezua bidaltzean.</string>
|
||||
<!-- %1$s will be replaced by the old group name, %2$s will be replaced by the new group name -->
|
||||
<string name="group_name_changed_by_you">Nik: Taldearen izena \"%1$s\" izatetik \"%2$s\" izatera aldatu da</string>
|
||||
<!-- %1$s will be replaced by the old group name, %2$s will be replaced by the new group name, %3$s will be replaced by name and address of the contact who did the action. -->
|
||||
@@ -522,26 +890,106 @@
|
||||
<!-- %1$s will be replaced by name of the contact who did the action -->
|
||||
<string name="group_image_changed_by_other">%1$s(e)k: Taldearen irudia aldatuta</string>
|
||||
<!-- %1$s will be replaced by name of the contact added to the group -->
|
||||
<string name="add_member_by_you">Nik: %1$s kidea gehituta</string>
|
||||
<string name="member_x_added">%1$s kidea gehitu da.</string>
|
||||
<!-- %1$s will be replaced by name of the contact added to the group -->
|
||||
<string name="add_member_by_you">Nik: %1$s kidea gehitu dut</string>
|
||||
<!-- %1$s will be replaced by name of the contact added to the group, %2$s will be replaced by name of the contact who did the action -->
|
||||
<string name="add_member_by_other">%2$s(e)k: %1$s kidea gehituta</string>
|
||||
<string name="add_member_by_other">%2$s(e)k: %1$s kidea gehitu du</string>
|
||||
<!-- %1$s will be replaced by name of the contact removed from the group -->
|
||||
<string name="remove_member_by_you">Nik: %1$s kidea kenduta</string>
|
||||
<!-- %1$s will be replaced by name of the contact removed from the group, %2$s will be replaced by name of the contact who did the action -->
|
||||
<string name="remove_member_by_other">%2$s(e)k: %1$s kidea kenduta</string>
|
||||
<!-- %1$s will be replaced by name of the contact removed from the group; this string is used when it's unclear who did the action -->
|
||||
<string name="member_x_removed">%1$s kidea kenduta.</string>
|
||||
<!-- "left" in the meaning of "exited". -->
|
||||
<string name="group_left_by_you">Taldetik atera zara</string>
|
||||
<!-- "left" in the meaning of "exited". -->
|
||||
<string name="channel_left_by_you">Kanaletik atera zara.</string>
|
||||
<string name="you_joined_the_channel">Kanalera batu zara.</string>
|
||||
<!-- "left" in the meaning of "exited"; %1$s will be replaced by name of the contact leaving the group -->
|
||||
<string name="group_left_by_other">%1$s(e)k taldea utzi du.</string>
|
||||
<string name="group_image_deleted_by_you">Nik: Taldearen irudia ezabatuta</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="group_image_deleted_by_other">%1$s(e)k: Taldearen irudia ezabatuta</string>
|
||||
<string name="location_enabled_by_you">Kokapena zuzenean partekatzea aktibatu duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="location_enabled_by_other">%1$s(e)k kokapena zuzenean partekatzea aktibatu du.</string>
|
||||
<string name="ephemeral_timer_disabled_by_you">Mezuen desagerpen-denbora desgaitu duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_disabled_by_other">%1$s(e)k mezuen desagerpen-denbora desgaitu du.</string>
|
||||
<!-- %1$s will be replaced by the number of seconds (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_seconds_by_you">Mezuen desagerpen-denbora %1$s segundotan ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by the number of seconds (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_seconds_by_other">%2$s(e)k mezuen desagerpen-denbora %1$s segundotan ezarri du.</string>
|
||||
<!-- deprecated, usage needs to be removed in core -->
|
||||
<string name="ephemeral_timer_1_minute_by_you">Mezuen desagerpen-denbora 1 minutakoa dela ezarri duzu.</string>
|
||||
<!-- deprecated, usage needs to be removed in core -->
|
||||
<string name="ephemeral_timer_1_minute_by_other">%1$s(e)k mezuen desagerpen-denbora 1 minutukoa dela ezarri du.</string>
|
||||
<string name="ephemeral_timer_1_hour_by_you">Mezuen desagerpen-denbora 1 ordukoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_hour_by_other">%1$s(e)k mezuen desagerpen-denbora 1 ordukoa dela ezarri du.</string>
|
||||
<string name="ephemeral_timer_1_day_by_you">Mezuen desagerpen-denbora 1 egunekoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_day_by_other">%1$s(e)k mezuen desagerpen-denbora 1 egunekoa dela ezarri du.</string>
|
||||
<string name="ephemeral_timer_1_week_by_you">Mezuen desagerpen-denbora 1 astekoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_week_by_other">%1$s-(e)k mezuen desagerpen-denbora 1 astekoa dela ezarri du.</string>
|
||||
<string name="ephemeral_timer_1_year_by_you">Mezuen desagerpen-denbora 1 urtekoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_year_by_other">%1$s(e)k mezuen desagerpen-denbora 1 urtekoa dela ezarri du.</string>
|
||||
<!-- %1$s will be replaced by the number of minutes (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_minutes_by_you">Mezuen desagerpen-denbora %1$s minutukoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by the number of minutes (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_minutes_by_other">%2$s(e)k mezuen desagerpen-denbora %1$s minutukoa dela ezarri du.</string>
|
||||
<!-- %1$s will be replaced by the number of hours (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_hours_by_you">Mezuen desagerpen-denbora %1$s ordukoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by the number of hours (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_hours_by_other">%2$s(e)k mezuen desagerpen-denbora %1$s ordukoa dela ezarri du.</string>
|
||||
<!-- %1$s will be replaced by the number of days (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_days_by_you">Mezuen desagerpen-denbora %1$s egunekoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by the number of days (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_days_by_other">%2$s(e)k mezuen desagerpen-denbora %1$s egunekoa dela ezarri du.</string>
|
||||
<!-- %1$s will be replaced by the number of weeks (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_weeks_by_you">Mezuen desagerpen-denbora %1$s astekoa dela ezarri duzu.</string>
|
||||
<!-- %1$s will be replaced by the number of weeks (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_weeks_by_other">%2$s(e)k mezuen desagerpen-denbora %1$s astekoa dela ezarri du.</string>
|
||||
<string name="chat_unencrypted_explanation">Txat honetako mezuek ohiko eposta helbidea erabiltzen dute eta ez daude muturretik muturrera zifratuta.</string>
|
||||
<string name="chat_protection_enabled_tap_to_learn_more">Mezuak muturretik muturrera zifratuta daude. Sakatu gehiago jakiteko.</string>
|
||||
<string name="chat_protection_enabled_explanation">Txat honetako mezu guztiak muturretik muturrera zifratuta daude.\n\nMuturretik muturrera zifratzeak mezuak pribatu mantentzen ditu zure eta zure txat kideen artean. Zerbitzariek, hornitzaileek edo erreleek ere ezin dituzte irakurri.</string>
|
||||
<string name="invalid_unencrypted_tap_to_learn_more">⚠️ %1$s(e)k muturretik muturrera zifratzea behar du, eta txat honetan oraindik ez dago konfiguratuta. Sakatu gehiago jakiteko.</string>
|
||||
<string name="invalid_unencrypted_explanation">Muturretik muturrera zifratzeko, kontaktuekin aurrez aurre elkartu zaitezke eta haien QR kodea eskaneatu dezakezu elkar egiaztatzeko.</string>
|
||||
<string name="learn_more">Ikasi gehiago</string>
|
||||
|
||||
<string name="devicemsg_self_deleted">\"Gordetako mezuak\" txata ezabatu duzu.\n\nℹ️ \"Gordetako mezuak\" funtzioa berriro erabiltzeko, sortu txat berri bat zure buruarekin.</string>
|
||||
<!-- %1$s will be replaced by the amount of storage already used, sth. as '500 MB'. If you want to use a percentage sign, type in two of them, eg. %1$s %% -->
|
||||
<string name="devicemsg_storage_exceeding">⚠️ Zure hornitzailearen biltegiratzea agortzear dago: %%-tik %1$s erabili dituzu dagoeneko.\n\nLitekeena da mezuak jaso ezin izatea biltegiratzea beteta badago.\n\n👉 Mesedez, egiaztatu datu zaharrak hornitzailearen web-interfazean ezaba ditzakezun eta kontuan hartu \"Ezarpenak / Txatak / Ezabatu mezu zaharrak\" aukera aktibatzea. Zure uneko biltegiratze-erabilera edozein unetan egiaztatu dezakezu \"Ezarpenak / Konektibitatea\" atalean.</string>
|
||||
<!-- %1%s will be replaced by date and time in some human-readable format -->
|
||||
<string name="devicemsg_bad_time">⚠️ Zure gailuko data edo ordua okerra dela dirudi (%1$s).\n\nEgokitu zure erlojua ⏰🔧 zure mezuak zuzen jasotzen direla ziurtatzeko.</string>
|
||||
<string name="devicemsg_update_reminder">⚠️ Zure Delta Chat bertsioa zaharkituta egon daiteke.\n\nHorrek arazoak sor ditzake zure txat-kideek bertsio berriagoak erabiltzen dituztelako - eta azken funtzioak falta dituzulako 😳\nMesedez, egiaztatu https://get.delta.chat edo zure aplikazio-denda eguneratzeak ikusteko.</string>
|
||||
|
||||
<!-- Some options as "Add Second Device" or "Backup" may require the system PIN/Fingerprint/Gesture/Etc. to be entered in a system dialog. This hint is added to the system dialog, below a title as "Add Second Device" or "Backup". -->
|
||||
<string name="enter_system_secret_to_continue">Desblokeatu jarraitzeko</string>
|
||||
|
||||
<!-- qr code stuff -->
|
||||
<string name="qr_code">QR kodea</string>
|
||||
<string name="load_qr_code_as_image">Kargatu QR kodea irudi gisa</string>
|
||||
<string name="qrscan_title">Eskaneatu QR kodea</string>
|
||||
<string name="qrscan_hint">Kokatu zure kamera QR kodearen gainean</string>
|
||||
<string name="qrscan_hint_desktop">Hurbildu QR kodea kamerara</string>
|
||||
<string name="qrscan_failed">Ezin izan da QR kodea deszifratu</string>
|
||||
<string name="qrscan_ask_join_group">\"%1$s\" taldera elkartu nahi duzu?</string>
|
||||
<string name="qrscan_ask_join_channel">\"%1$s\" kanalera batu nahi duzu?</string>
|
||||
<string name="qrscan_fingerprint_mismatch">Eskaneatutako hatz-marka eta %1$s erabiltzaileari ikusitako azken hatz-marka ez datoz bat.</string>
|
||||
<string name="qrscan_no_addr_found">QR kode honek hatz-marka bat du baina ez e-mail helbidea.\n\nBandaz kanpoko egiaztaketa baterako, ezarri zifratutako konexio bat hartzailearekin aurretik.</string>
|
||||
<string name="qrscan_contains_text">Eskaneatutako QR kodearen testua:\n\n%1$s</string>
|
||||
<string name="qrscan_contains_url">Eskaneatutako QR kodearen URL-a:\n\n%1$s</string>
|
||||
<string name="qrscan_fingerprint_label">Hatz-marka</string>
|
||||
<string name="withdraw_verifycontact_explain">QR kode hau beste batzuek eskaneatu dezakete zurekin harremanetan jartzeko.\n\nBerrezarri egin dezakezu, lehendik dagoen QR kodeak edo gonbidapen-estekak gehiago funtziona ez dezan.</string>
|
||||
<string name="withdraw_verifygroup_explain">QR kode hau beste batzuek eskaneatu dezakete \"%1$s\" taldera batzeko.\n\nBerrezarri egin dezakezu, lehendik dagoen QR kodeak edo gonbidapen-estekak gehiago funtziona ez dezan.</string>
|
||||
<string name="withdraw_joinbroadcast_explain">QR kode hau beste batzuek eskaneatu dezakete \"%1$s\" kanalera batzeko.\n\nBerrezarri egin dezakezu, lehendik dagoen QR kodeak edo gonbidapen-estekak gehiago funtziona ez dezan.</string>
|
||||
<string name="withdraw_qr_code">Berrezarri QR kodea</string>
|
||||
<string name="revive_verifycontact_explain">QR kode hau berrezarri da eta aurrerantzean ez da aktibo egongo.</string>
|
||||
<string name="revive_qr_code">Aktibatu QR kodea</string>
|
||||
<string name="qrshow_title">QR gonbidapen-kodea</string>
|
||||
<string name="qrshow_x_joining">%1$s elkartu da.</string>
|
||||
<string name="qrshow_x_verified">%1$s egiaztatuta.</string>
|
||||
@@ -549,13 +997,37 @@
|
||||
<string name="qrshow_join_group_title">QR gonbidapen-kodea</string>
|
||||
<!-- This text is shown inside the "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the group name, eg. "Scan to join group \"Testing group\"" -->
|
||||
<string name="qrshow_join_group_hint">Eskaneatu hau \"%1$s\" taldera elkartzeko.</string>
|
||||
<string name="qrshow_join_channel_hint">Eskaneatu \"%1$s\" kanalera batzeko</string>
|
||||
<string name="qrshow_join_contact_title">QR gonbidapen-kodea</string>
|
||||
<!-- This text is shown inside the "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the profile name eg. "Scan to chat with Alice" -->
|
||||
<string name="qrshow_join_contact_hint">Eskaneatu hau %1$s erabiltzailearen kontaktua ezartzeko</string>
|
||||
<string name="qrshow_join_contact_no_connection_toast">Ez dago Internet konexiorik, ezin da QR kode bidezko ezarpena aplikatu</string>
|
||||
<string name="qraccount_ask_create_and_login">Sortu kontu berria \"%1$s\" zerbitzarian eta saioa han hasi?</string>
|
||||
<string name="set_name_and_avatar_explain">Ezarri zure kontaktuak ezagutuko duten izen bat. Abatar bat ere ezar dezakezu.</string>
|
||||
<string name="please_enter_name">Mesedez, sartu izen bat.</string>
|
||||
<string name="qraccount_qr_code_cannot_be_used">Eskaneatutako QR kodea ezin da kontu berri bat ezartzeko erabili.</string>
|
||||
<!-- the placeholder will be replaced by the address of the profile -->
|
||||
<string name="qrlogin_ask_login">Hasi saioa \"%1$s\"(e)n?</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_started">%1$s(e)k talde honetara batzeko gonbidapena egin dizu. \n\n%2$s(r)en gailuak erantzun dezan itxaroten…</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_channel_started">%1$s(e)k kanal honetara batzeko gonbidapena egin dizu. \n\n%2$s(r)en gailuak erantzun dezan itxaroten…</string>
|
||||
<!-- placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_replies">%1$s(e)k erantzun du, taldera gehitzekoa zain...</string>
|
||||
<string name="secure_join_wait">Konexioa ezartzen, itxaron mesedez...</string>
|
||||
<string name="contact_verified">%1$s egiaztatuta.</string>
|
||||
<string name="contact_blocked">Kontaktua blokeatu duzu</string>
|
||||
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
|
||||
<string name="verified_by">%1$s(e)k egiaztatuta</string>
|
||||
<string name="verified_by_you">Nik egiaztatuta</string>
|
||||
<string name="verified_by_unknown">Egiaztatuta</string>
|
||||
<!-- deprecated -->
|
||||
<string name="verified_contact_required_explain">Muturretik muturrera zifratzea bermatzeko, marka berdea duten kontaktuak soilik gehitu ditzakezu talde honetara.\n\nKontaktuekin aurrez aurre elkartu zaitezke eta haien QR kodea eskaneatu dezakezu elkar egiaztatzeko.</string>
|
||||
<string name="mailto_dialog_header_select_chat">Aukeratu txat bat mezua bidaltzeko</string>
|
||||
<!-- first placeholder is the name of the chat -->
|
||||
<string name="confirm_replace_draft">%1$s(e)k zirriborro bat du dagoeneko, ordezkatu nahi duzu?</string>
|
||||
<string name="mailto_link_could_not_be_decoded"> mailto esteka ezin izan da deszifratu: %1$s </string>
|
||||
|
||||
<!-- notifications -->
|
||||
<string name="notify_reply_button">Erantzun</string>
|
||||
<string name="notify_new_message">Mezu berria</string>
|
||||
@@ -565,6 +1037,14 @@
|
||||
<string name="notify_name_and_message">Izena eta mezua</string>
|
||||
<string name="notify_name_only">Izena besterik ez</string>
|
||||
<string name="notify_no_name_or_message">Izenik edo mezurik ez</string>
|
||||
<string name="notifications_disabled">Jakinarazpenak desgaituta</string>
|
||||
<string name="unreliable_bg_notifications">Aktibatu “Behartu atzeko planoko konexioa” jakinarazpenak jasotzea ziurtatzeko.</string>
|
||||
<string name="new_messages">Mezu berriak</string>
|
||||
<!-- Body text for a generic "New messages" notification. Shown if we do not have more information about a new messages. Note, that the string is also referenced at https://github.com/deltachat/notifiers -->
|
||||
<string name="new_messages_body">Mezu berriak dituzu</string>
|
||||
<string name="n_messages_in_m_chats">%1$d mezu %2$d txatetan</string>
|
||||
|
||||
|
||||
<!-- permissions -->
|
||||
<string name="perm_required_title">Baimena behar da</string>
|
||||
<string name="perm_continue">Jarraitu</string>
|
||||
@@ -573,6 +1053,21 @@
|
||||
<string name="perm_explain_access_to_mic_denied">Delta Chat-ek mikrofonoa erabiltzeko baimena behar du ahots-mezuak bidali ahal izateko, baina behin betiko ukatu zaio. Joan aplikazioaren ezarpenetara, hautatu \"Baimenak\" eta gaitu \"Mikrofonoa\".</string>
|
||||
<string name="perm_explain_access_to_storage_denied">Delta Chat-ek biltegiratze baimena behar du argazkiak, bideoak edo audioa erantsi edo esportatzeko, baina behin betiko ukatu zaio. Joan aplikazioaren ezarpen menura, hautatu \"baimenak\", eta gaitu \"Biltegiratzea\"</string>
|
||||
<string name="perm_explain_access_to_location_denied">Delta Chat-ek kokaleku aatzitzeko baimena behar du kokalekua eransteko, baina behin betiko ukatu zaio. Joan aplikazioaren ezarpen menura, hautatu \"baimenak\", eta gaitu \"Kokalekua\".</string>
|
||||
<string name="perm_explain_access_to_notifications_denied">Jakinarazpenak jasotzeko, hona jo \"Sistemaren ezarpenak / Aplikazioak / Delta Chat\" eta gaitu \"Jakinarazpenak\".</string>
|
||||
|
||||
<!-- ImageEditorHud -->
|
||||
<string name="ImageEditorHud_draw_anywhere_to_blur">Marraztu edonon lausotzeko</string>
|
||||
<string name="ImageEditorHud_add_text">Gehitu testua</string>
|
||||
<string name="ImageEditorHud_blur">Lausotu</string>
|
||||
<string name="ImageEditorHud_brush_marker">Markatzailea</string>
|
||||
<string name="ImageEditorHud_brush_highlight">Azpimarratzailea</string>
|
||||
<string name="ImageEditorHud_crop">Ezabatu</string>
|
||||
<string name="ImageEditorHud_flip">Irauli</string>
|
||||
<string name="ImageEditorHud_rotate">Biratu</string>
|
||||
|
||||
<!-- strings introduced on desktop. we want to share strings between the os, in general, please do not add generic strings here -->
|
||||
<string name="about_offical_app_desktop">Hau Delta Chat Desktop aplikazio ofiziala da.</string>
|
||||
<string name="about_licensed_under_desktop">Software honek GNU GPL 3 bertsioaren lizentziapean dago eta iturburu-kodea GitHub-en dago eskuragarri.</string>
|
||||
<string name="welcome_desktop">Ongi etorri Delta Chat-era</string>
|
||||
<string name="global_menu_preferences_language_desktop">Hautatu hizkuntza...</string>
|
||||
<string name="global_menu_file_desktop">Fitxategia</string>
|
||||
@@ -588,8 +1083,12 @@
|
||||
<string name="global_menu_view_developer_desktop">Garatzailea</string>
|
||||
<string name="global_menu_view_developer_tools_desktop">Garatzaile-tresnak</string>
|
||||
<string name="global_menu_help_desktop">Laguntza</string>
|
||||
<string name="delta_chat_homepage">Delta Chat-en hasiera orria</string>
|
||||
<string name="contribute">Lagundu</string>
|
||||
<string name="global_menu_help_report_desktop">Eman arazo baten berri</string>
|
||||
<string name="global_menu_help_about_desktop">Delta Chat-i buruz</string>
|
||||
<string name="global_menu_file_open_desktop">Ireki Delta Chat</string>
|
||||
<string name="global_menu_minimize_to_tray">Txikitu</string>
|
||||
<string name="no_chat_selected_suggestion_desktop">Hautatu txat bat edo sortu txat berri bat</string>
|
||||
<string name="write_message_desktop">Idatzi mezu bat</string>
|
||||
<string name="encryption_info_title_desktop">Zifratzeari buruzko informazioa</string>
|
||||
@@ -598,13 +1097,30 @@
|
||||
<string name="timestamp_format_m_desktop">MMM D</string>
|
||||
<string name="remove_desktop">Kendu</string>
|
||||
<string name="save_desktop">Gorde</string>
|
||||
<!-- Opposite of "Save". Undo a "Save" action. Similar to "Unmute", "Unpin". Could also be worded as "Save no longer" or so. -->
|
||||
<string name="unsave">Gorde gabe utzi</string>
|
||||
<string name="name_desktop">Izena</string>
|
||||
<string name="select_group_image_desktop">Hautatu taldearen irudia</string>
|
||||
<string name="export_backup_desktop">Esportatu babes-kopia</string>
|
||||
<string name="export_backup_desktop">Esportatu babeskopia</string>
|
||||
<string name="message_detail_sent_desktop">bidalita</string>
|
||||
<string name="message_detail_received_desktop">jasota</string>
|
||||
<string name="menu.view.developer.open.log.folder">Ireki egunkarien karpeta</string>
|
||||
<string name="menu.view.developer.open.current.log.file">Ireki uneko egunkari-fitxategia</string>
|
||||
<string name="explain_desktop_minimized_disabled_tray_pref" tools:ignore="TypographyDashes">Erretiluko ikonoa ezin da desgaitu, Delta Chat --minimized aukerarekin abiarazi baita.</string>
|
||||
<string name="no_spellcheck_suggestions_found">Ez dago ortografia-iradokizunik.</string>
|
||||
<string name="show_window">Erakutsi leihoa</string>
|
||||
|
||||
<!-- title of the "keybindings" dialog (for the keybindings names as such, where possible the normal command strings are used) -->
|
||||
<string name="keybindings">Tekla-konbinazioak</string>
|
||||
<string name="switch_between_chats">Aldatu txaten artean</string>
|
||||
<string name="scroll_messages">Korritu mezuak</string>
|
||||
<!-- command to put the cursor to the search input field -->
|
||||
<string name="focus_search_input">Fokuratu bilaketa</string>
|
||||
<!-- command to put the cursor to the message input field -->
|
||||
<string name="focus_message_input">Fokuratu mezua idazteko eremua</string>
|
||||
<string name="force_refresh_network">Behartu sarea eguneratzera</string>
|
||||
<string name="insert_newline">Txertatu lerro-jauzia</string>
|
||||
|
||||
<!-- accessibility, the general idea is to use the normal strings for accessibility hints wherever possible -->
|
||||
<string name="a11y_delivery_status_error">Bidalketa-egoera: Errorea</string>
|
||||
<string name="a11y_delivery_status_sending">Bidalketa-egoera: Bidaltzen</string>
|
||||
@@ -614,12 +1130,61 @@
|
||||
<string name="a11y_delivery_status_invalid">Bidalketa-egoera baliogabea</string>
|
||||
<string name="a11y_message_context_menu_btn_label">Mezu-ekintzak</string>
|
||||
<string name="a11y_background_preview_label">Atzealdearen aurrebista</string>
|
||||
<string name="a11y_disappearing_messages_activated">Desagertzen diren mezuak aktibatu dira</string>
|
||||
|
||||
<!-- iOS specific strings, developers: please take care to remove strings that are no longer used! -->
|
||||
<string name="stop_sharing_location">Utzi kokapena partekatzeari</string>
|
||||
<string name="a11y_voice_message_hint_ios">Grabatu ondoren, sakatu bi aldiz bidaltzeko. Grabazioa baztertzeko, pasatu bi hatz gainetik.</string>
|
||||
<string name="a11y_connectivity_hint">Klik bikoitza konexio xehetasunak ikusteko.</string>
|
||||
<string name="login_error_no_internet_connection">Ez dago Internet konexiorik, saio-hasierak huts egin du.</string>
|
||||
<string name="share_account_not_configured">Kontua ez dago konfiguratuta</string>
|
||||
<string name="cannot_play_audio_file">Ezin da audio-fitxategia erreproduzitu.</string>
|
||||
<!-- iOS camera permission alert -->
|
||||
<string name="perm_ios_explain_access_to_camera_denied">Argazkiak ateratzeko, bideoak grabatzeko edo QR kodeen eskanerra erabiltzeko, ireki sistemaren ezarpenak eta gaitu \"Kamera\".</string>
|
||||
<string name="open_settings">Ireki ezarpenak</string>
|
||||
<!-- iOS device contact alert -->
|
||||
<string name="import_device_contacts">Inportatu gailuko kontaktuak</string>
|
||||
<string name="import_device_contacts_hint">Zure gailuko kontaktuekin txateatzeko, ireki ezarpenak eta gaitu \"Kontaktuak\".</string>
|
||||
<!-- iOS notification settings -->
|
||||
<string name="disabled_in_dc">Desgaitu Delta Chat-en</string>
|
||||
<string name="disabled_in_system_settings">Desgaitu sistemaren ezarpenetan</string>
|
||||
<string name="bg_app_refresh_disabled">\"Atzeko planoko aplikazioak freskatzea\" desgaituta dago sistemaren ezarpenetan</string>
|
||||
<string name="notifications_avg_minutes">Batez beste, %1$d minutuan behin</string>
|
||||
<string name="notifications_avg_hours">Batez beste, %1$d orduan behin</string>
|
||||
<string name="last_check_at">Noiz egiaztatua: %1$s</string>
|
||||
<string name="system_settings">Sistemaren ezarpenak</string>
|
||||
<!-- shown below the button "System Settings" on the notification screen. this is a hint about what can be edited on System Settings' Notification page - eg. the notification type (banner, lock screen, notification centre), sound, badges and so on. no need to be exhaustive here, it is only to give the user an idea. -->
|
||||
<string name="system_settings_notify_explain_ios">Editatu mota, bereizgarriak, aurrebista eta gehiago</string>
|
||||
<!-- iOS shortcut widget -->
|
||||
<!-- use the same translation for "Shortcuts" as the system is using, often the term "Shortcut" stays untranslated; check eg. how the "Shortcuts" system app is called in your locale -->
|
||||
<string name="shortcuts_widget_title">Lasterbideak</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
<string name="shortcuts_widget_description">Erabili Delta Chat-en \"Gehitu widget-era\" elementuak gehitzeko</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
<string name="remove_from_widget">Kendu widget-etik</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
<string name="add_to_widget">Gehitu widget-era</string>
|
||||
<!-- iOS permissions, copy from "deltachat-ios/Info.plist", which is used on missing translations in "deltachat-ios/LANG.lproj/InfoPlist.strings" -->
|
||||
<string name="InfoPlist_NSCameraUsageDescription">Kamera atzitzeko baimena emateak argazkiak eta bideoak ateratzea ahalbidetzen dizu.</string>
|
||||
<string name="InfoPlist_NSLocationAlwaysAndWhenInUseUsageDescription">Delta Chat-ek zure kokapena partekatzeko baimena behar du, kokapena partekatzea aktibatuta duzun denbora-tartean.</string>
|
||||
<string name="InfoPlist_NSLocationWhenInUseUsageDescription">Delta Chat-ek zure kokapena partekatzeko baimena behar du, kokapena partekatzea aktibatuta duzun denbora-tartean.</string>
|
||||
<string name="InfoPlist_NSMicrophoneUsageDescription">Mikrofonoa atzitzeko baimena emateak audioa grabatzea ahalbidetzen dizu.</string>
|
||||
<string name="InfoPlist_NSPhotoLibraryUsageDescription">Argazkien bilduma atzitzeko baimena emateak bertatik argazkiak igotzea ahalbidetzen dizu.</string>
|
||||
<string name="InfoPlist_NSPhotoLibraryAddUsageDescription">Delta Chat-ek zure argazki galerian irudiak gorde nahi ditu.</string>
|
||||
<string name="InfoPlist_NSFaceIDUsageDescription">Delta Chat-ek Face ID erabil dezake zure tokiko profila, babeskopien sorkuntza eta bigarren gailu baten konfigurazioa babesteko.</string>
|
||||
|
||||
<!-- android specific strings, developers: please take care to remove strings that are no longer used! -->
|
||||
<string name="pref_instant_delivery">Berehalako bidalketa</string>
|
||||
<string name="pref_background_notifications">Erabili atzeko planoko konexioa</string>
|
||||
<string name="pref_background_notifications_explain">Bateriaren optimizazioa alde batera utziko du. Erabili hau jakinarazpenak garaiz iristen ez badira.</string>
|
||||
<string name="pref_reliable_service">Behartu atzeko planoko konexioa</string>
|
||||
<string name="pref_reliable_service_explain">Jakinarazpen iraunkorra sortzen du</string>
|
||||
|
||||
<string name="pref_background_notifications_rationale">Konexioari eutsi eta mezuak atzeko planoan jasotzeko, baztertu bateriaren optimizazioak hurrengo urratsean.\n\nDelta Chat-ek baliabide gutxi erabiltzen ditu eta kontu handiz jokatzen du bateria ez agortzeko.</string>
|
||||
<!-- disabling "Reliable service" will hide a the maybe annoying permanent-notification with the drawback that new-message-notifications get potentially unreliable -->
|
||||
<string name="perm_enable_bg_reminder_title">Sakatu hemen mezuak jasotzeko Delta Chat bigarren planoan dagoenean.</string>
|
||||
<string name="perm_enable_bg_already_done">Dagoeneko baimendu diozu Delta Chat aplikazioari bigarren planoan mezuak jasotzea,\n\nOraindik ere mezuak heltzen ez badira, egiaztatu ere zure sistemaren ezarpenak.</string>
|
||||
|
||||
</resources>
|
||||
<!-- device messages for updates -->
|
||||
<string name="update_2_0">Zer berri?\n\n💯 Muturretik muturrerako zifratze fidagarria eta betirakoa da orain. Sarrailak 🔒 joan dira!\n\n✉️ Muturretik muturrerako zifratzerik gabeko posta elektroniko klasikoa gutun-azal ikur batekin markatuta dago\n\n😻 Kontuaren pantaila berria zure kontaktu guztientzat\n\n🔲 Txat batean erabilitako aplikazioetara azkar sartzeko botoi berria\n\n❤️ Mesedez, egin dohaintza independente jarraitzen laguntzeko eta hobekuntzak ekartzen jarraitzeko: %1$s</string>
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||
<string name="description">Deskribapena</string>
|
||||
<string name="could_not_open_file">Ezin izan da fitxategia ireki</string>
|
||||
<string name="menu_export_image">Esportatu irudia</string>
|
||||
<!-- the word "or" to separate blocks in the user interface that are mutually exclusive -->
|
||||
<string name="or_separator">edo</string>
|
||||
<string name="online">online</string>
|
||||
<string name="pink">Arrosa</string>
|
||||
<string name="gray">Grisa</string>
|
||||
<string name="share_location_for_12_hours">12 orduz</string>
|
||||
|
||||
<!-- device messages for updates -->
|
||||
<!-- when translating the sentence about the ArcaneChat channel, clarify that the channel is in English -->
|
||||
<string name="device_welcome_message">🔮 Ongi etorri ArcaneChat-era ✨\n\nLagunekin harremanetan jartzeko:\n\n🤳🏻 Sakatu \"QR kodea\" bi gailuen pantaila nagusian. Aukeratu \"Eskaneatu QR kodea\" gailu batean, eta zuzendu beste gailurantz\n\n🔗 Gela berean ez bazaudete, gonbidapen-esteka parteka dezakezu menuko \"Gonbidatu lagunak\" atalean\n\n📢 Bat egin [ArcaneChat Kanal Ofiziala]rekin (%1$s) (ingelesez) garapen-egoerari buruzko berri guztiak izateko.</string>
|
||||
|
||||
<string name="update_2_33">🔮 Zer berri?\n\n★ Android 16 helburu\n\n★ Hobetu pantaila osoko euskarria\n\n★ Aldatu mezuetako esteken kolorea\n\n★ Metadatuen babesa: babestu mezuen hartzaileak\n\n★ Konponduta: saihestu atzeko planoan izoztuta geratzea\n\n★ Bideo-grabaketaren kudeaketa hobetu da\n\n★ Beste hainbat konponketa eta hobekuntza txiki\n\n\n💜 Mesedez, egin dohaintza bat independente izaten eta hobekuntzak ekartzen jarraitzeko: %1$s</string>
|
||||
</resources>
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">بایگانی</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">خروج از بایگانی</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">سکوت</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">بیصدا</string>
|
||||
<string name="ephemeral_messages">پیامهای ناپدید شونده</string>
|
||||
<string name="ephemeral_messages_hint">شامل همه کسانی که در این گفتگو حضور دارند میشود. آنها همچنان میتوانند پیامها را هدایت و ذخیره کرده یا از آنها رونوشت بگیرند. </string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">برای اضافه کردن برچسب روی «بازکردن پوشهٔ برچسب» بزنید، یک زیرپوشه برای دستهٔ برچسب خود درست کنید و برچسبها را به آنجا بکشید</string>
|
||||
<string name="open_sticker_folder">بازکردن پوشه استیکر</string>
|
||||
<string name="images">تصاویر</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">صدا</string>
|
||||
<string name="voice_message">پیام صوتی</string>
|
||||
<string name="forwarded">هدایت</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">بازیها</string>
|
||||
<string name="tools">ابزار</string>
|
||||
<string name="app_size">اندازه</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">انتشار</string>
|
||||
<string name="add_to_chat">افزودن به گفتگو</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -382,12 +386,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">تماس</string>
|
||||
<string name="start_audio_call">تماس صوتی</string>
|
||||
<string name="start_video_call">تماس تصویری</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">جواب دادن</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">رد کردن</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">تماس خروجی</string>
|
||||
<string name="outgoing_audio_call">تماس صوتی خروجی</string>
|
||||
<string name="outgoing_video_call">تماس تصویری خروجی</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">تماس ورودی</string>
|
||||
<string name="incoming_audio_call">تماس صوتی ورودی</string>
|
||||
<string name="incoming_video_call">تماس تصویری ورودی</string>
|
||||
<string name="declined_call">تماس رد شده</string>
|
||||
<string name="canceled_call">تماس لغو شده</string>
|
||||
<string name="missed_call">تماس از دست رفته</string>
|
||||
@@ -721,6 +733,7 @@
|
||||
<string name="pref_your_name">اسم شما</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">متن امضا</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">ورود کلیدهای ارسال</string>
|
||||
<string name="pref_enter_sends_explain">فشاردادن کلید اینتر پیامها را ارسال میکند</string>
|
||||
<string name="pref_outgoing_media_quality">کیفیت رسانه خروجی</string>
|
||||
@@ -809,6 +822,7 @@
|
||||
<string name="n_bytes_message">پیام %1$s </string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">سقف دانلود تا %1$s فعال خواهد بود</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">انتخاب نمایه</string>
|
||||
<string name="profile_image_select">انتخاب تصویر نمایه</string>
|
||||
<string name="select_your_new_profile_image">تصویر نمایهٔ جدیدتان را برگزینید</string>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<string name="archive">Arkistoi</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Poista arkistosta</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Mykistä</string>
|
||||
<string name="ephemeral_messages">Katoavat viestit</string>
|
||||
<string name="ephemeral_messages_hint">Nämä asetukset pätevät kaikkiin Delta Chat -käyttäjiin. He voivat kuitenkin kopioida, tallentaa ja välittää viestejä tai käyttää toisia sähköpostisovelluksia.</string>
|
||||
@@ -146,6 +147,7 @@
|
||||
<string name="add_stickers_instructions">Saat lisättyä tarroja valitsemalla \"Avaa tarrakansio\", luomalla alikansion tarrakokoelmallesi ja raahaamalla tarratiedostosi sinne</string>
|
||||
<string name="open_sticker_folder">Avaa tarrakansio</string>
|
||||
<string name="images">Kuvat</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Äänite</string>
|
||||
<string name="voice_message">Ääniviesti</string>
|
||||
<string name="forwarded">Välitetty</string>
|
||||
@@ -563,6 +565,7 @@
|
||||
<string name="pref_your_name">Nimesi</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Bio</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Lähetä Enter -näppäimellä</string>
|
||||
<string name="pref_enter_sends_explain">Enter-näppäimen painaminen lähettää viestin</string>
|
||||
<string name="pref_outgoing_media_quality">Lähtevän median laatu</string>
|
||||
|
||||
+238
-224
@@ -51,17 +51,19 @@
|
||||
<string name="archive">Archiver</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Désarchiver</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Sourdine</string>
|
||||
<string name="muted">Muet</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">En sourdine</string>
|
||||
<string name="ephemeral_messages">Messages éphémères</string>
|
||||
<string name="ephemeral_messages_hint">Ces paramètres s\'appliquent à tous les participants utilisant Delta Chat; ils peuvent copier, enregistrer et faire suivre des messages ou utiliser un autre client de e-mail.</string>
|
||||
<string name="save">Sauvegarder</string>
|
||||
<string name="ephemeral_messages_hint">S\'applique à tous les membres de cette discussion. Ils pourront toujours copier, enregistrer et transférer les messages.</string>
|
||||
<string name="save">Enregistrer</string>
|
||||
<string name="chat">Discussion</string>
|
||||
<string name="media">Média</string>
|
||||
<string name="apps_and_media">Applis & Médias</string>
|
||||
<string name="apps_and_media">Applis & fichiers multimédias</string>
|
||||
<string name="profile">Profil</string>
|
||||
<string name="all_profiles">Tous les profils</string>
|
||||
<string name="current_profile">Profil courant</string>
|
||||
<string name="current_profile">Profil actuel</string>
|
||||
<string name="main_menu">Menu principal</string>
|
||||
<string name="start_chat">Commencer la discussion</string>
|
||||
<string name="show_full_message">Montrer le message complet...</string>
|
||||
@@ -69,7 +71,7 @@
|
||||
<string name="mark_all_as_read">Marquer tout comme lu</string>
|
||||
<string name="mark_as_read">Marquer comme lu</string>
|
||||
<!-- Shortest text for "Mark as being read". In english, this could be "Read" (past tense of "to read"), in german, this could be "Gelesen". -->
|
||||
<string name="mark_as_read_short">Lu</string>
|
||||
<string name="mark_as_read_short">Marquer comme lu</string>
|
||||
<!-- Placeholder text when something is loading -->
|
||||
<string name="loading">Chargement...</string>
|
||||
<string name="hide">Cacher</string>
|
||||
@@ -167,9 +169,9 @@
|
||||
<item quantity="other">%d membres</item>
|
||||
</plurals>
|
||||
<plurals name="n_recipients">
|
||||
<item quantity="one">%d destinataire</item>
|
||||
<item quantity="many">%d destinataires</item>
|
||||
<item quantity="other">%d destinataires</item>
|
||||
<item quantity="one">%d abonné⋅e</item>
|
||||
<item quantity="many">%d abonné⋅es</item>
|
||||
<item quantity="other">%d abonné⋅es</item>
|
||||
</plurals>
|
||||
<!-- Short form for "N Items Selected" -->
|
||||
<plurals name="n_selected">
|
||||
@@ -177,7 +179,7 @@
|
||||
<item quantity="many">%d Sélectionnés</item>
|
||||
<item quantity="other">%d Sélectionnés</item>
|
||||
</plurals>
|
||||
<string name="selected_colon">Sélectionné:</string>
|
||||
<string name="selected_colon">Sélection :</string>
|
||||
<string name="self">Moi</string>
|
||||
<string name="draft">Brouillon</string>
|
||||
<string name="image">Image</string>
|
||||
@@ -190,7 +192,8 @@
|
||||
<string name="add_stickers_instructions">Pour ajouter des vignettes, appuyez sur \"Ouvrir le dossier Vignettes\", créez un sous-dossier pour votre paquet de vignettes et faites-y glisser vos fichiers image ou vignette </string>
|
||||
<string name="open_sticker_folder">Ouvrir le dossier Vignettes</string>
|
||||
<string name="images">Images</string>
|
||||
<string name="audio">Son</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Message vocal</string>
|
||||
<string name="forwarded">Transféré</string>
|
||||
<string name="forwarded_message">Message transféré</string>
|
||||
@@ -211,22 +214,23 @@
|
||||
<string name="images_and_videos">Images et vidéos</string>
|
||||
<string name="file">Fichier</string>
|
||||
<string name="files">Fichiers</string>
|
||||
<string name="files_attach_hint">Envoyer les fichiers au format original et les images en non compressé</string>
|
||||
<string name="files_attach_hint">Envoyer les fichiers au format original et les images non compressées</string>
|
||||
<!-- "Files" here means the "Files Selector App" or "Files Manager App" -->
|
||||
<string name="choose_from_files">Choisir depuis vos fichiers</string>
|
||||
<string name="choose_from_gallery">Choisir depuis la gallerie</string>
|
||||
<string name="choose_from_gallery">Choisir depuis la galerie</string>
|
||||
<!-- "App" is used to present "Webxdc App" (https://webxdc.org) in a user friendly way. Please stay close to the original term and keep it short (it is used in menus with few screen space). -->
|
||||
<string name="webxdc_app">Appli</string>
|
||||
<!-- plural of "App"; used to present "Webxdc App" (https://webxdc.org) in a user friendly way. Please stay close to the original term and keep it short (it is used in menus with few screen space). -->
|
||||
<string name="webxdc_apps">Applis</string>
|
||||
<string name="webxdc_store_url">URL du catalogue des apps </string>
|
||||
<string name="webxdc_store_url_explain">Si elle est définit l\'URL sera utilisée à la place de l\'URL par défaut.</string>
|
||||
<string name="webxdc_draft_hint">Appuyez \"Envoyer\" pour partager</string>
|
||||
<string name="webxdc_store_url">URL du catalogue d\'applis</string>
|
||||
<string name="webxdc_store_url_explain">Si elle est définie, l\'URL sera utilisée comme catalogue d\'applis à la place de l\'URL par défaut.</string>
|
||||
<string name="webxdc_draft_hint">Appuyez sur \"Envoyer\" pour partager</string>
|
||||
<string name="home">Accueil</string>
|
||||
<string name="games">Jeux</string>
|
||||
<string name="tools">Outils</string>
|
||||
<string name="app_size">Taille</string>
|
||||
<string name="app_date_published">Publié</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Publiée</string>
|
||||
<string name="add_to_chat">Ajouter à la discussion</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
<string name="browse">Explorer</string>
|
||||
@@ -253,8 +257,8 @@
|
||||
|
||||
<!-- menu labels (or icon, buttons...) -->
|
||||
<string name="menu_new_contact">Nouveau contact</string>
|
||||
<string name="menu_new_classic_contact">Ajouter le contact à la main</string>
|
||||
<string name="new_classic_contact_explain">Les contacts ajoutés à la main peuvent être contactés par e-mail classique. Le chiffrement de bout en bout n\'est pas garanti.</string>
|
||||
<string name="menu_new_classic_contact">Ajouter un contact manuellement</string>
|
||||
<string name="new_classic_contact_explain">Les contacts ajoutés manuellement peuvent être contactés par courriel classique. Le chiffrement de bout en bout n\'est pas garanti.</string>
|
||||
<string name="menu_new_chat">Nouvelle discussion</string>
|
||||
<string name="menu_new_group">Nouveau groupe</string>
|
||||
<!-- "Chat" is a verb here, "Message to" would also fit. the string might be used in the "New Chat" screen above the contact list -->
|
||||
@@ -267,7 +271,7 @@
|
||||
<!-- consider keeping the term "channel" as in WhatsApp or Telegram -->
|
||||
<string name="new_channel">Nouveau canal</string>
|
||||
<!-- deprecated -->
|
||||
<string name="add_recipients">Ajouter des destinataires</string>
|
||||
<string name="add_recipients">Ajouter des abonné⋅es</string>
|
||||
<!-- consider keeping the term "channel" as in WhatsApp or Telegram -->
|
||||
<string name="channel_name">Nom du canal</string>
|
||||
<string name="email">Courriel</string>
|
||||
@@ -293,25 +297,25 @@
|
||||
<string name="menu_message_details">Détails du message</string>
|
||||
<string name="menu_copy_to_clipboard">Copier vers presse-papiers</string>
|
||||
<string name="share_invite_link">Partager un lien d\'invitation</string>
|
||||
<string name="share_invite_link_explain">Tous les utilisateurs disposant du lien peuvent voir votre profil et démarrer une discussion avec vous. Ne le partagez qu\'à des personnes en qui vous avez confiance.</string>
|
||||
<string name="share_invite_link_explain">Toute personne disposant de ce lien peut voir votre profil et démarrer une discussion avec vous. Ne le partagez qu\'avec des personnes en qui vous avez confiance.</string>
|
||||
<string name="invite_friends">Inviter des amis</string>
|
||||
<!-- %1$s is replaced by the user's invitation link ("https://i.delta.chat/...") -->
|
||||
<string name="invite_friends_text">Contactez-moi sur Delta Chat:\n%1$s</string>
|
||||
<string name="invite_friends_text">Contactez-moi sur Delta Chat :\n%1$s</string>
|
||||
<string name="menu_copy_selection_to_clipboard">Copier la sélection</string>
|
||||
<string name="menu_copy_link_to_clipboard">Copier le lien</string>
|
||||
<string name="menu_copy_text_to_clipboard">Copier le texte</string>
|
||||
<string name="menu_copy_image_to_clipboard">Copier l\'image</string>
|
||||
<string name="menu_copy_email_to_clipboard">Copier l\'adresse de courriel</string>
|
||||
<string name="menu_copy_email_to_clipboard">Copier l\'adresse courriel</string>
|
||||
<string name="paste_from_clipboard">Coller depuis le presse-papiers</string>
|
||||
<string name="ask_copy_unopenable_link_to_clipboard">Le lien \"%1$d\" ne peut pas être ouvert dans le navigateur, souhaitez-vous le copier dans le presse-papier à la place ?</string>
|
||||
<string name="menu_forward">Faire suivre le message</string>
|
||||
<string name="menu_reply">Répondre au message</string>
|
||||
<string name="menu_mute">Désactiver les notifications</string>
|
||||
<string name="menu_unmute">Réactiver</string>
|
||||
<string name="menu_export_attachment">Exporter le fichier joint</string>
|
||||
<string name="menu_export_attachments">Exporter les pièces-jointes</string>
|
||||
<string name="menu_all_media">Tous les médias</string>
|
||||
<string name="all_apps_and_media">Toutes les applis & médias</string>
|
||||
<string name="menu_mute">Mettre en sourdine</string>
|
||||
<string name="menu_unmute">Désactiver la sourdine</string>
|
||||
<string name="menu_export_attachment">Exporter la pièce jointe</string>
|
||||
<string name="menu_export_attachments">Exporter les pièces jointes</string>
|
||||
<string name="menu_all_media">Tous les fichiers multimédias</string>
|
||||
<string name="all_apps_and_media">Toutes les applis & et fichiers multimédias</string>
|
||||
<!-- Command to jump to the original message corresponding to a gallery image or document -->
|
||||
<string name="show_in_chat">Montrer dans la discussion</string>
|
||||
<string name="show_app_in_chat">Montrer l\'appli dans la discussion</string>
|
||||
@@ -327,14 +331,14 @@
|
||||
<string name="menu_scroll_to_top">Faire défiler jusqu\'en haut</string>
|
||||
<string name="menu_help">Aide</string>
|
||||
<!-- use the same term for "Apps" as elsewhere -->
|
||||
<string name="what_is_webxdc">Qu\'est-ce qu\'une appli Webxdc ?</string>
|
||||
<string name="what_is_webxdc">À propos des applis</string>
|
||||
<string name="privacy_policy">Politique de confidentialité</string>
|
||||
<string name="menu_select_all">Tout sélectionner</string>
|
||||
<string name="select_chat">Sélectionnez une discussion</string>
|
||||
<string name="select_more">Sélectionner plus</string>
|
||||
<string name="menu_edit_name">Modifier le nom</string>
|
||||
<!-- The placeholder will be replaced by the name the contact gave themself -->
|
||||
<string name="edit_name_explain">Choisir un surnom qui s\'affichera à la place de « %1$s ». Laisser cet espace vide pour utiliser le nom choisi par le contact.</string>
|
||||
<string name="edit_name_explain">Choisir un surnom qui s\'affichera à la place de « %1$s ». Laisser ce champ vide pour utiliser le nom choisi par le contact.</string>
|
||||
<!-- The placeholder will be replaced by the name the contact gave themself -->
|
||||
<string name="edit_name_placeholder">Surnom de \"%1$s\"</string>
|
||||
<string name="menu_settings">Paramètres</string>
|
||||
@@ -342,18 +346,18 @@
|
||||
<string name="menu_view_profile">Voir le profil</string>
|
||||
<string name="menu_zoom_in">Zoom avant</string>
|
||||
<string name="menu_zoom_out">Zoom arrière</string>
|
||||
<string name="menu_save_log">Sauvegarder le journal</string>
|
||||
<string name="menu_save_log">Enregistrer le journal</string>
|
||||
<string name="menu_more_options">Plus d\'options</string>
|
||||
<string name="menu_learn_spelling">Ajouter au dictionnaire</string>
|
||||
<string name="jump_to_message">Aller au message</string>
|
||||
<string name="jump_to_original_message">Voir le message original</string>
|
||||
<string name="jump_to_original_message">Aller au message original</string>
|
||||
<string name="copy_json">Copier le JSON</string>
|
||||
<string name="replace_draft">Remplacer le brouillon</string>
|
||||
<string name="title_share_location">Partager la position avec tous les membres du groupe</string>
|
||||
<string name="device_talk">Messages de l\'appareil</string>
|
||||
<string name="device_talk_subtitle">Messages générés localement</string>
|
||||
<string name="device_talk_explain">Les messages dans cette discussion sont générés localement par votre application Delta Chat. Cela vous permet de recevoir des informations concernant les mises à jour et problèmes rencontrés à l\'utilisation.</string>
|
||||
<string name="device_talk_welcome_message2">Entrez en contact !\n\n🙌 Cliquez sur « code QR » sur la page d\'accueil des deux appareils. Sélectionnez « Scanner le code QR » sur un des appareils et positionnez les deux appareils l\'un vers l\'autre\n\n🌍 Si vous n\'êtes pas dans la même pièce, vous pouvez scanner le code QR pendant un appel vidéo ou partager un lien d\'invitation à partir de « Scanner le code QR »\n\n Profitez ensuite de votre expérience de messagerie sur le plus grand réseau décentralisé du monde : les emails. Contrairement aux autres applications populaires, tout cela se fait sans contrôle centralisé, suivi ou revente de vos données, celles de vos amis, collègues ou famille à de grandes entreprises.</string>
|
||||
<string name="device_talk_welcome_message2">Entrez en contact !\n\n🙌 Appuyez sur « code QR » sur l\'écran principal des deux appareils. Sélectionnez « Scanner le code QR » sur l\'un des appareils et positionnez les deux appareils l\'un vers l\'autre\n\n🌍 Si vous n\'êtes pas dans la même pièce, vous pouvez scanner le code QR pendant un appel vidéo ou partager un lien d\'invitation à partir de « Scanner le code QR ».\n\nEnsuite, profitez de votre expérience de messagerie décentralisée ! Contrairement aux autres applications populaires, tout cela sans contrôle centralisé, suivi ou revente à de grandes entreprises de vos données, ni de celles de vos amis, de vos collègues ou de votre famille .</string>
|
||||
<string name="edit_contact">Mettre à jour le contact</string>
|
||||
<!-- Verb "to pin", making something sticky, not a noun or abbreviation for "pin number". -->
|
||||
<string name="pin_chat">Épingler la discussion</string>
|
||||
@@ -369,13 +373,13 @@
|
||||
<!-- Menu item beside an app/chat that adds an icon to the system's home screen. If the user taps that icon, the app/chat is opened directly. -->
|
||||
<string name="add_to_home_screen">Ajouter à l\'écran d\'accueil</string>
|
||||
<string name="donate">Faire un don</string>
|
||||
<string name="donate_device_msg">❤️ On dirait que vous aimez bien Delta Chat!\n\nMerci de considérer une donation à Delta Chat afin d\'assurer qu\'il reste libre et gratuit pour tout le monde.\n\nBien que Delta Chat soit gratuit à l\'utilisation et un logiciel libre, le développer coûte de l\'argent. Aidez-nous à garder Delta Chat indépendant et le rendre encore plus incroyable dans le futur.\n\nhttps://delta.chat/donate</string>
|
||||
<string name="donate_device_msg">❤️ On dirait que vous aimez bien Delta Chat !\n\nNous vous serions reconnaissants d\'envisager de nous faire un don pour aider Delta Chat à rester libre et gratuit pour tout le monde.\n\nBien que Delta Chat soit gratuit et open source, son développement coûte de l\'argent. Aidez-nous à garder Delta Chat indépendant et à le rendre encore plus génial à l\'avenir.\n\nhttps://delta.chat/fr/donate</string>
|
||||
|
||||
<string name="mute_for_one_hour">Désactiver pour 1 heure</string>
|
||||
<string name="mute_for_eight_hours">Désactiver pour 8 heures</string>
|
||||
<string name="mute_for_one_day">Désactiver pour 1 jour</string>
|
||||
<string name="mute_for_seven_days">Désactiver pour 7 jours</string>
|
||||
<string name="mute_forever">Désactiver pour toujours</string>
|
||||
<string name="mute_for_one_hour">Sourdine pendant 1 heure</string>
|
||||
<string name="mute_for_eight_hours">Sourdine pendant 8 heures</string>
|
||||
<string name="mute_for_one_day">Sourdine pendant 1 jour</string>
|
||||
<string name="mute_for_seven_days">Sourdine pendant 7 jours</string>
|
||||
<string name="mute_forever">Sourdine pour toujours</string>
|
||||
|
||||
<string name="share_location_for_5_minutes">pour 5 minutes</string>
|
||||
<string name="share_location_for_30_minutes">pour 30 minutes</string>
|
||||
@@ -389,17 +393,25 @@
|
||||
<item quantity="many">Envoyer les %d fichiers suivants à %s ?</item>
|
||||
<item quantity="other">Envoyer les %d fichiers suivants à %s ?</item>
|
||||
</plurals>
|
||||
<string name="file_saved_to">Fichier enregistré dans \"%1$s\".</string>
|
||||
<string name="file_saved_to">Fichier enregistré dans « %1$s ».</string>
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Appeler</string>
|
||||
<string name="start_audio_call">Appel audio</string>
|
||||
<string name="start_video_call">Appel vidéo</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Décrocher</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Raccrocher</string>
|
||||
<string name="end_call">Refuser</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Appel sortant</string>
|
||||
<string name="outgoing_audio_call">Appel audio sortant</string>
|
||||
<string name="outgoing_video_call">Appel vidéo sortant</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Appel entrant</string>
|
||||
<string name="declined_call">Appel rejeté</string>
|
||||
<string name="incoming_audio_call">Appel audio entrant</string>
|
||||
<string name="incoming_video_call">Appel vidéo entrant</string>
|
||||
<string name="declined_call">Appel refusé</string>
|
||||
<string name="canceled_call">Appel annulé</string>
|
||||
<string name="missed_call">Appel manqué</string>
|
||||
<!-- the first placeholder will be replaced by a date, the second placeholder by duration, example: "Thu, 08:12 pm, 2 minutes" -->
|
||||
@@ -407,37 +419,37 @@
|
||||
|
||||
<!-- get confirmations -->
|
||||
<!-- confirmation for leaving groups or channels. If a subject is needed, "Are you sure you want to leave the chat?" would work as well -->
|
||||
<string name="ask_leave_group">Êtes-vous sûr de vouloir quitter la discussion ?</string>
|
||||
<string name="ask_leave_group">Voulez-vous vraiment quitter la discussion ?</string>
|
||||
<plurals name="ask_delete_chat">
|
||||
<item quantity="one">Supprimer %d discussion ?</item>
|
||||
<item quantity="many">Supprimer %d discussions ?</item>
|
||||
<item quantity="other">Supprimer %d discussions ?</item>
|
||||
</plurals>
|
||||
<string name="ask_delete_named_chat">Supprimer la conversation \"%1$s\" de tous vos appareils ?</string>
|
||||
<string name="ask_delete_message">Supprimer ce message de tous vos appareils ?</string>
|
||||
<string name="ask_delete_named_chat">Supprimer la discussion \"%1$s\" ?</string>
|
||||
<string name="ask_delete_message">Supprimer ce message ?</string>
|
||||
<plurals name="ask_delete_messages">
|
||||
<item quantity="one">Effacer %d message ici et sur le serveur ?</item>
|
||||
<item quantity="many">Effacer %d messages ici et sur le serveur ?</item>
|
||||
<item quantity="other">Effacer %d messages ici et sur le serveur ?</item>
|
||||
<item quantity="one">Supprimer %d message ?</item>
|
||||
<item quantity="many">Supprimer %d messages ?</item>
|
||||
<item quantity="other">Supprimer %d messages ?</item>
|
||||
</plurals>
|
||||
<string name="ask_forward">Faire suivre les messages à %1$s ?</string>
|
||||
<string name="ask_forward_multiple">Faire suivre les messages à %1$d discussions ?</string>
|
||||
<string name="ask_export_attachment">Exporter une pièce jointe ? L\'exportation des pièces jointes permettra à toute autre application sur votre appareil d\'y accéder. Continuer ?</string>
|
||||
<string name="ask_block_contact">Bloquer ce contact ? Vous ne recevrez plus ses messages.</string>
|
||||
<string name="ask_unblock_contact">Débloquer ce contact ? Vous recevrez à nouveau ses messages.</string>
|
||||
<string name="ask_delete_contacts">Supprimer les contacts ?\n\nLes contacts avec qui vous avez des discussions en cours et ceux issus du carnet d\'adresses du système ne peuvent pas être supprimés définitivement.</string>
|
||||
<string name="ask_delete_contact">Supprimer le contact %1$s ?\n\nLes contacts avec qui vous avez des discussions en cours et ceux issus du carnet d\'adresses du système ne peuvent pas être supprimés définitivement.</string>
|
||||
<string name="ask_export_attachment">Exporter des pièces jointes permettra aux autres applications sur votre appareil d\'y accéder.\n\nContinuer ?</string>
|
||||
<string name="ask_block_contact">Bloquer ce contact ?\n\nVous ne verrez plus les messages directs ou les groupes créés par un contact bloqué.\n\nVous continuerez à voir les messages des contacts bloqués dans les autres groupes.</string>
|
||||
<string name="ask_unblock_contact">Débloquer ce contact ?</string>
|
||||
<string name="ask_delete_contacts">Supprimer les contacts ?\n\nLes contacts avec qui vous avez des discussions en cours ne peuvent pas être supprimés définitivement.</string>
|
||||
<string name="ask_delete_contact">Supprimer le contact %1$s ?\n\nLes contacts avec qui vous avez des discussions en cours ne peuvent pas être supprimés définitivement.</string>
|
||||
<string name="ask_start_chat_with">Discuter avec %1$s ?</string>
|
||||
<!-- %1$s is replaced by a comma-separated list of names -->
|
||||
<string name="ask_remove_members">Retirer %1$s du groupe ?</string>
|
||||
<!-- %1$s is replaced by a comma-separated list of names -->
|
||||
<string name="ask_remove_from_channel">Retirer %1$s du canal ?</string>
|
||||
<string name="ask_remove_from_channel">Retirer %1$s du canal ?</string>
|
||||
<string name="open_url_confirmation">Voulez-vous ouvrir ce lien ?</string>
|
||||
|
||||
|
||||
<!-- contact list -->
|
||||
<string name="contacts_title">Contacts</string>
|
||||
<string name="contacts_type_email_above">Saisir l\'adresse de courriel au-dessus</string>
|
||||
<string name="contacts_type_email_above">Saisir l\'adresse de courriel ci-dessus</string>
|
||||
|
||||
|
||||
<!-- chatlist and chat view -->
|
||||
@@ -461,29 +473,29 @@
|
||||
<item quantity="other">%d nouveaux messages</item>
|
||||
</plurals>
|
||||
<!-- The placeholder will be replaced by the name of the recipient in a one-to-one chat. -->
|
||||
<string name="chat_new_one_to_one_hint">Envoyez un message. Il n\'y a pas de problème si %1$s n\'utilise pas Delta Chat.</string>
|
||||
<string name="chat_new_one_to_one_hint">Envoyez un message à %1$s.</string>
|
||||
<!-- consider keeping the term "channel" as in WhatsApp or Telegram -->
|
||||
<string name="chat_new_channel_hint">Les canaux sont un outil parmi d\'autres pour diffuser vos communications.</string>
|
||||
<string name="chat_new_channel_hint">Les canaux sont un outil vous permettant de diffuser vos messages selon un modèle à origine unique et destinations multiples.</string>
|
||||
<string name="chat_new_group_hint">Les autres participants ne verront ce groupe qu\'après que vous avez envoyé un premier message.</string>
|
||||
<string name="chat_record_slide_to_cancel">Glisser pour annuler</string>
|
||||
<string name="chat_record_explain">Appuyer et maintenir pour enregistrer un message vocal, relâcher pour l’envoyer</string>
|
||||
<string name="chat_no_chats_yet_title">Boîte de réception vide. Appuyer sur \"+\" pour commencer une nouvelle discussion.</string>
|
||||
<string name="chat_no_chats_yet_title">Aucune discussion.\nAppuyez sur \"+\" pour commencer une nouvelle discussion.</string>
|
||||
<string name="chat_all_archived">Toutes les discussions sont archivées.\nAppuyer sur \"+\" pour commencer une nouvelle discussion.</string>
|
||||
<string name="chat_share_with_title">Partager avec</string>
|
||||
<string name="chat_share_with_title">Partager avec…</string>
|
||||
<string name="chat_input_placeholder">Message</string>
|
||||
<string name="chat_archived_label">Archivé</string>
|
||||
<string name="chat_request_label">Invitation</string>
|
||||
<string name="chat_request_label_explain">Inclure les messages d\'invitations dans les compteurs et notifications</string>
|
||||
<string name="chat_request_label_explain">Inclure les invitations dans les compteurs et les notifications</string>
|
||||
<string name="chat_no_messages">Aucun message.</string>
|
||||
<string name="chat_self_talk_subtitle">Messages envoyés à moi-même</string>
|
||||
<string name="archive_empty_hint">Les discussions archivées apparaîtront ici.</string>
|
||||
<!-- Action to add a message to "Saved Messages". The longer form (instead of "Save" only) is needed esp. on desktop to make clear this is not about saving a file to disk -->
|
||||
<string name="save_message">Sauvegarder</string>
|
||||
<string name="saved_messages">Messages sauvegardés</string>
|
||||
<string name="saved_messages_explain">• Transférez les messages ici pour un accès facile\n\n• Prenez des notes, des mémos vocaux\n\n• Joignez des fichiers pour les sauvegarder</string>
|
||||
<string name="save_message">Enregistrer le message</string>
|
||||
<string name="saved_messages">Messages enregistrés</string>
|
||||
<string name="saved_messages_explain">• Transférez les messages ici pour les retrouver facilement\n\n• Prenez des notes ou enregistrez des vocaux\n\n• Ajoutez des fichiers multimédias en pièces jointes pour les sauvegarder</string>
|
||||
<!-- Should match "Saved" from "Saved messages" -->
|
||||
<string name="saved">Sauvegardés</string>
|
||||
<string name="save_as">Sauvegarder</string>
|
||||
<string name="saved">Enregistrés</string>
|
||||
<string name="save_as">Enregistrer sous</string>
|
||||
<string name="retry_send">Réessayer d\'envoyer le message</string>
|
||||
<string name="cannot_display_unsuported_file_type">Impossible d\'afficher ce type de fichier : %s</string>
|
||||
<string name="attachment_failed_to_load">Échec du chargement de la pièce jointe</string>
|
||||
@@ -502,8 +514,8 @@
|
||||
<string name="send_file_to">Envoyer \"%1$s\" à</string>
|
||||
<!-- title shown above a list contacts where one should be selected (eg. when a webxdc attempts to send a message to a chat) -->
|
||||
<string name="send_message_to">Envoyer un message à</string>
|
||||
<string name="enable_realtime">Applications temps réel</string>
|
||||
<string name="enable_realtime_explain">Activez les connexions temps réel pour les applications partagées dans les discussions. Les interlocuteurs pourront voir votre adresse IP lorsque vous lancerez l\'app. </string>
|
||||
<string name="enable_realtime">Applications en temps réel</string>
|
||||
<string name="enable_realtime_explain">Activez les connexions en temps réel pour les applications rattachées à vos discussions. Il est alors possible que vos interlocuteurs aient accès à votre adresse IP lorsque vous lancerez une appli. </string>
|
||||
|
||||
<!-- map -->
|
||||
<string name="filter_map_on_time">Afficher les positions pour une période</string>
|
||||
@@ -528,7 +540,7 @@
|
||||
<string name="search_explain">Rechercher des discussions, des contacts ou des messages</string>
|
||||
<string name="search_no_result_for_x">Aucun résultat trouvé pour \"%s\"</string>
|
||||
<!-- Adjective, as in "Show Unread Messages" -->
|
||||
<string name="search_unread">Non-lus</string>
|
||||
<string name="search_unread">Non lus</string>
|
||||
|
||||
|
||||
<!-- create/edit groups, contact/group profile -->
|
||||
@@ -541,7 +553,7 @@
|
||||
<string name="group_add_members">Ajouter des participants</string>
|
||||
<string name="group_self_not_in_group">Vous devez être membre du groupe pour effectuer cette action.</string>
|
||||
<string name="profile_encryption">Chiffrement</string>
|
||||
<string name="profile_shared_chats">Discussions partagées</string>
|
||||
<string name="profile_shared_chats">Discussions en commun</string>
|
||||
<!-- Separator between the list of actual members and past members -->
|
||||
<string name="past_members">Anciens membres</string>
|
||||
<string name="tab_contact">Contact</string>
|
||||
@@ -550,16 +562,16 @@
|
||||
<string name="tab_docs">Documents</string>
|
||||
<string name="tab_links">Liens</string>
|
||||
<string name="tab_map">Carte</string>
|
||||
<string name="tab_gallery_empty_hint">Les images et vidéos partagées dans cette discussion seront affichées ici.</string>
|
||||
<string name="tab_docs_empty_hint">Les documents, musiques et autres fichiers partagés dans ce chat seront affichés ici.</string>
|
||||
<string name="tab_image_empty_hint">Les images partagées dans cette discussion seront affichées ici.</string>
|
||||
<string name="tab_video_empty_hint">Les vidéos partagées dans cette discussion seront affichées ici.</string>
|
||||
<string name="tab_audio_empty_hint">Les fichiers audio et messages vocaux partagés dans cette discussion seront affichés ici.</string>
|
||||
<string name="tab_webxdc_empty_hint">Les applis partagées dans cette discussion seront affichées ici.</string>
|
||||
<string name="tab_all_media_empty_hint">Les fichiers multimédias partagés dans une discussion apparaissent ici.</string>
|
||||
<string name="all_files_empty_hint">Les documents et autres partagés dans les discussions vont être affichés ici.</string>
|
||||
<string name="all_apps_empty_hint">Les applications envoyées ou reçues dans une discussion apparaissent ici.</string>
|
||||
<string name="media_preview">Prévisualiser le fichier multimédia</string>
|
||||
<string name="tab_gallery_empty_hint">Les images et vidéos partagées dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_docs_empty_hint">Les documents et autres fichiers partagés dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_image_empty_hint">Les images partagées dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_video_empty_hint">Les vidéos partagées dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_audio_empty_hint">Les fichiers audio et messages vocaux partagés dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_webxdc_empty_hint">Les applis partagées dans cette discussion apparaîtront ici.</string>
|
||||
<string name="tab_all_media_empty_hint">Les fichiers multimédias partagés dans n\'importe quelle discussion apparaîtront ici.</string>
|
||||
<string name="all_files_empty_hint">Les documents et autres fichiers partagés dans n\'importe quelle discussion apparaîtront ici.</string>
|
||||
<string name="all_apps_empty_hint">Les applications partagées dans n\'importe quelle discussion apparaîtront ici.</string>
|
||||
<string name="media_preview">Aperçu du fichier multimédia</string>
|
||||
<!-- option to show images in the gallery with the correct width/height aspect (instead of square); other gallery apps may be a source of inspiration for translation :) -->
|
||||
<string name="aspect_ratio_grid">Grille de proportions</string>
|
||||
<!-- option to show images in the gallery as square (instead of using correct width/height) -->
|
||||
@@ -570,21 +582,21 @@
|
||||
<!-- "Second Device" can also be translated as "Another Device", if that is catchier in the destination language. However, make sure to use the term consistently. -->
|
||||
<string name="multidevice_title">Ajouter un deuxième appareil</string>
|
||||
<string name="multidevice_same_network_hint">Vérifiez que les deux appareils sont bien connectés au même Wi-Fi ou réseau.</string>
|
||||
<string name="multidevice_this_creates_a_qr_code">Crée un code QR que vous pouvez scanner avec le deuxième appareil pour copier le compte.</string>
|
||||
<string name="multidevice_this_creates_a_qr_code">Crée un code QR que vous pouvez scanner avec le deuxième appareil pour copier le profil.\n\nAssurez-vous qu\'aucun observateur ou caméra indésirable ne puisse voir la fenêtre suivante.</string>
|
||||
<string name="multidevice_install_dc_on_other_device">Installer Delta Chat sur votre autre appareil (https://get.delta.chat)</string>
|
||||
<!-- "I Already Have a Profile / Add as Second Device” should be the same text as defined by the keys onboarding_alternative_logins and multidevice_receiver_title -->
|
||||
<string name="multidevice_tap_scan_on_other_device">Lancez Delta Chat, appuyez sur \"Ajouter comme deuxième appareil\" et scannez le code affiché ici.</string>
|
||||
<string name="multidevice_tap_scan_on_other_device">Lancez Delta Chat, appuyez sur « J\'ai déjà un profil/Ajouter comme deuxième appareil » et scannez le code affiché ici.</string>
|
||||
<!-- Shown inside a "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the profile name eg. "Scan to set up second device for Alice" -->
|
||||
<string name="multidevice_qr_subtitle">Scanner pour configurer un deuxième appareil pour %1$s</string>
|
||||
<string name="multidevice_receiver_title">Ajouter comme deuxième appareil</string>
|
||||
<string name="multidevice_open_settings_on_other_device">Sur le premier appareil, allez dans \"Paramètres / Ajouter un deuxième appareil\" et scannez le code qui s\'affiche</string>
|
||||
<string name="multidevice_receiver_scanning_ask">Copier le compte de l\'autre appareil sur celui-ci ?</string>
|
||||
<string name="multidevice_receiver_needs_update">Le profil que vous voulez importer vient d\'une version plus récente de Delta Chat.\n\nPour continuer la mise en place d\'un second appareil, veuillez mettre à jour Delta Chat.</string>
|
||||
<string name="multidevice_open_settings_on_other_device">Sur le premier appareil, ouvrez Delta Chat, allez dans « Paramètres/Ajouter un deuxième appareil » et scannez le code qui s\'affiche</string>
|
||||
<string name="multidevice_receiver_scanning_ask">Copier le profil de l\'autre appareil sur celui-ci ?</string>
|
||||
<string name="multidevice_receiver_needs_update">Le profil que vous voulez importer provient d\'une version plus récente de Delta Chat.\n\nPour continuer la configuration du deuxième appareil, mettez Delta Chat à jour.</string>
|
||||
<string name="multidevice_abort">Abandonner la configuration du deuxième appareil ?</string>
|
||||
<string name="multidevice_abort_will_invalidate_copied_qr">Révoque le code QR copié dans le presse-papiers.</string>
|
||||
<string name="multidevice_transfer_done_devicemsg">ℹ️ Compte transféré sur votre deuxième appareil.</string>
|
||||
<string name="multidevice_transfer_done_devicemsg">ℹ️ Profil transféré sur votre deuxième appareil.</string>
|
||||
<!-- Shown beside progress bar, stay short -->
|
||||
<string name="preparing_account">Préparation du compte...</string>
|
||||
<string name="preparing_account">Préparation du profil...</string>
|
||||
<!-- Shown beside progress bar, stay short -->
|
||||
<string name="transferring">Transfert...</string>
|
||||
<string name="troubleshooting">Dépannage</string>
|
||||
@@ -616,35 +628,35 @@
|
||||
|
||||
<!-- welcome and login -->
|
||||
<!-- Primary button on the welcome screen, allows to create an instant profile -->
|
||||
<string name="onboarding_create_instant_account">Créer un nouveau compte</string>
|
||||
<string name="onboarding_create_instant_account">Créer un nouveau profil</string>
|
||||
<!-- Secondary button on the welcome screen, allows to "Add as Second Device", "Restore from Backup" -->
|
||||
<string name="onboarding_alternative_logins">Je possède déjà un compte</string>
|
||||
<string name="onboarding_alternative_logins">J\'ai déjà un profil</string>
|
||||
<!-- This is a button and a title, allowing to use existing, classic email, setting ports, passwords and so on -->
|
||||
<string name="manual_account_setup_option">Authentification par email classique</string>
|
||||
<string name="manual_account_setup_option">Utiliser le courriel classique comme relais</string>
|
||||
<!-- Instant onboarding title (there is not more to do than to set name and avatar) -->
|
||||
<string name="instant_onboarding_title">Votre compte</string>
|
||||
<string name="instant_onboarding_title">Votre profil</string>
|
||||
<!-- The placeholder will be replaced by the default onboarding server -->
|
||||
<string name="instant_onboarding_agree_default2">Conditions générales et politique de confidentialité pour %1$s</string>
|
||||
<!-- The placeholder will be replaced by instance name, the whole text will link to the instance page -->
|
||||
<string name="instant_onboarding_agree_instance">À propos des profils sur %1$s</string>
|
||||
<string name="instant_onboarding_agree_instance">Informations concernant les profils sur %1$s</string>
|
||||
<!-- Confirmation button on the instant onboarding screen -->
|
||||
<string name="instant_onboarding_create">Accepter et créer le compte</string>
|
||||
<string name="instant_onboarding_create">Accepter et créer le profil</string>
|
||||
<!-- Secondary, link-like button to open a page with other possible instances -->
|
||||
<string name="instant_onboarding_show_more_instances">Utiliser un autre serveur</string>
|
||||
<string name="instant_onboarding_other_server">Lister les serveurs de discussions</string>
|
||||
<string name="instant_onboarding_other_server">Liste des serveurs chatmail</string>
|
||||
<!-- Hint about what happens when "Create Profile" button in pressed; the placeholder will be replaced by the group name -->
|
||||
<string name="instant_onboarding_group_info">Crée un profil pour rejoindre le groupe \"%1$s\".</string>
|
||||
<string name="instant_onboarding_group_info">Créez un profil pour rejoindre le groupe « %1$s ».</string>
|
||||
<!-- Hint about what happens when "Create Profile" button in pressed; the placeholder will be replaced by contact name -->
|
||||
<string name="instant_onboarding_contact_info">Crée un profil pour discuter avec %1$s.</string>
|
||||
<string name="instant_onboarding_contact_info">Créez un profil pour discuter avec %1$s.</string>
|
||||
<!-- Question shown when another user's QR code is scanned from onboarding screen -->
|
||||
<string name="instant_onboarding_confirm_contact">Voulez-vous créer un profil et commencer à discuter avec %1$s ?</string>
|
||||
<string name="instant_onboarding_confirm_contact">Voulez-vous créer un profil et commencer à discuter avec %1$s ?</string>
|
||||
<!-- Question shown when group's/channel's QR code is scanned from onboarding screen -->
|
||||
<string name="instant_onboarding_confirm_group">Voulez-vous créer un profil et rejoindre le groupe de discussion \"%1$s\" ?</string>
|
||||
<string name="instant_onboarding_confirm_group">Voulez-vous créer un profil et rejoindre « %1$s » ?</string>
|
||||
|
||||
<string name="welcome_chat_over_email">Chat décentralisé et sûr</string>
|
||||
<string name="welcome_chat_over_email">Messagerie décentralisée sécurisée</string>
|
||||
<string name="scan_invitation_code">Scanner le code d\'invitation</string>
|
||||
<string name="login_title">Connexion</string>
|
||||
<string name="login_advanced_hint">Ce type de connexion est pour les utilisateurs avancés:\n\n• N\'utilisez pas le compte pour la connexion à une autre appli.\n\n• Les serveurs de mail classique permettent les conversations non chiffrés de bout-en-bout, celles-ci indiquées par une icône mail.</string>
|
||||
<string name="login_advanced_hint">Ce type de connexion est réservé aux utilisateurs avancés.\n\n• N\'utilisez pas une adresse déjà employée dans une autre appli.\n\n• Les serveurs de courriel classiques permettent les discussions non chiffrées de bout en bout, lesquelles sont représentées par une icône enveloppe.</string>
|
||||
<string name="login_inbox">Boîte de réception</string>
|
||||
<string name="login_imap_login">Utilisateur IMAP</string>
|
||||
<string name="login_imap_server">Serveur IMAP</string>
|
||||
@@ -658,55 +670,55 @@
|
||||
<string name="login_smtp_security">Sécurité SMTP</string>
|
||||
<!-- the word "Proxy" might be left untranslated unless the destination language has a well-known term for a "Proxy Server", acting intermediary between the app and the server -->
|
||||
<string name="proxy_settings">Proxy</string>
|
||||
<string name="proxy_use_proxy">Utiliser le proxy</string>
|
||||
<string name="proxy_use_proxy">Utiliser un proxy</string>
|
||||
<string name="proxy_add">Ajouter un proxy</string>
|
||||
<string name="proxy_add_explain">Types de proxy supportés: HTTP(S), SOCKS5 et Shadowsocks.</string>
|
||||
<string name="proxy_add_url_hint">Entrer le lien du proxy ici</string>
|
||||
<string name="proxy_invalid">Proxy invalide ou non supporté</string>
|
||||
<string name="proxy_list_header">Sauver les proxy</string>
|
||||
<string name="proxy_add_explain">Types de proxy pris en charge : HTTP(S), SOCKS5 et Shadowsocks.</string>
|
||||
<string name="proxy_add_url_hint">Insérer le lien du proxy ici</string>
|
||||
<string name="proxy_invalid">Proxy invalide ou non pris en charge</string>
|
||||
<string name="proxy_list_header">Proxies enregistrés</string>
|
||||
<string name="proxy_delete">Supprimer le proxy</string>
|
||||
<string name="proxy_delete_explain">Voulez-vous vraiment supprimer « %1$s » ?</string>
|
||||
<string name="proxy_use_proxy_confirm">Voulez-vous utilser le proxy \"%1$s\" ?</string>
|
||||
<string name="proxy_use_proxy_confirm">Voulez-vous utiliser le proxy « %1$s » ?</string>
|
||||
<string name="proxy_share_explain">Vos amis peuvent ajouter ce proxy en scannant le code QR.</string>
|
||||
<string name="proxy_share_link">Partager le lien</string>
|
||||
<string name="proxy_enabled">Proxy activé</string>
|
||||
<string name="proxy_enabled_hint">Vous êtes en train d\'utiliser un proxy. Si vous avez des difficultés à vous connecter, essayez un autre proxy.</string>
|
||||
<string name="proxy_enabled_hint">Vous utilisez un proxy. Si vous rencontrez des difficultés pour vous connecter, essayez un autre proxy.</string>
|
||||
<!-- "Relay" refers to the relay servers used; please chose a common term in your language, no need to be literal. If in doubt, stay with "Relay" -->
|
||||
<string name="transports">Serveur de relais</string>
|
||||
<string name="transports">Relais</string>
|
||||
<string name="add_transport">Ajouter un relais</string>
|
||||
<string name="remove_transport">Enlever un relais</string>
|
||||
<string name="remove_transport">Supprimer un relais</string>
|
||||
<string name="edit_transport">Modifier le relais</string>
|
||||
<!-- shown if a QR code was scanned that can be used as a relay -->
|
||||
<string name="confirm_add_transport">Ajouter le relais ?</string>
|
||||
<string name="invalid_transport_qr">Le QR code scanné ne renvoie pas vers un relai valide.</string>
|
||||
<string name="confirm_add_transport">Ajouter le relais ?</string>
|
||||
<string name="invalid_transport_qr">Le code QR scanné ne renvoie pas vers un relais valide.</string>
|
||||
<!-- placeholder will be replaced by a relay server name -->
|
||||
<string name="confirm_remove_transport">Supprimer le relai \"%1$s\"\n\nVos contacts ne peuvent vous contacter que si vous les avez déjà contactés depuis un autre relai.\n\nDans le doute, supprimez le relai plus tard.</string>
|
||||
<string name="confirm_remove_transport">Supprimer le relais « %1$s » ?\n\nVos contacts ne pourront vous contacter que si vous les avez déjà contactés via un autre relais.\n\nEn cas de doute, supprimez le relais plus tard.</string>
|
||||
|
||||
<string name="login_certificate_checks">Vérification du certificat</string>
|
||||
<string name="login_error_mail">Entrez une adresse email valide</string>
|
||||
<string name="login_error_mail">Entrez une adresse courriel valide</string>
|
||||
<string name="login_error_server">Entre un serveur / adresse IP valide</string>
|
||||
<string name="login_error_port">Entrez un port valide (1-65535)</string>
|
||||
<string name="login_error_required_fields">Entrez une adresse email et un mot de passe valides</string>
|
||||
<string name="login_error_required_fields">Entrez une adresse courriel et un mot de passe valides</string>
|
||||
<string name="import_backup_title">Rétablir une sauvegarde</string>
|
||||
<string name="import_backup_ask">Sauvegarde trouvée sur \"%1$s\".\n\nVoulez-vous importer et en utiliser toutes les données et paramètres ?</string>
|
||||
<string name="import_backup_no_backup_found">Aucune sauvegarde trouvée.\n\nCopiez le fichier de sauvegarde vers \"%1$s\" et essayez à nouveau.</string>
|
||||
<string name="import_backup_ask">Sauvegarde trouvée dans « %1$s ».\n\nVoulez-vous l\'importer et en utiliser toutes les données et paramètres ?</string>
|
||||
<string name="import_backup_no_backup_found">Aucune sauvegarde trouvée.\n\nCopiez le fichier de sauvegarde vers « %1$s » et essayez à nouveau.</string>
|
||||
<!-- %1$s will be replaced by the failing address -->
|
||||
<string name="login_error_cannot_login">Connexion en tant que \"%1$s\" échouée. Vérifiez que votre adresse courriel et votre mot de passe sont corrects.</string>
|
||||
<string name="login_error_cannot_login">Connexion en tant que « %1$s » impossible. Vérifiez que votre adresse courriel et votre mot de passe sont corrects.</string>
|
||||
<!-- TLS certificate checks -->
|
||||
<string name="accept_invalid_certificates">Accepter les certificats non valides</string>
|
||||
<string name="switch_account">Changer de compte</string>
|
||||
<string name="add_account">Ajouter un compte</string>
|
||||
<string name="switch_account">Changer de profil</string>
|
||||
<string name="add_account">Ajouter un profil</string>
|
||||
<!-- for translations, you can also think of "Profile Tag" or "Profile Description" as the source string -->
|
||||
<string name="profile_tag">Description du profil</string>
|
||||
<string name="profile_tag_hint">Travail ou famille par exemple</string>
|
||||
<string name="profile_tag_explain">Définir une description visible seulement par vous; vous aidant à faire la différence entre vos profils.</string>
|
||||
<string name="profile_tag">Étiquette du profil</string>
|
||||
<string name="profile_tag_hint">Travail ou Famille, par exemple</string>
|
||||
<string name="profile_tag_explain">Saisissez une étiquette, visible seulement par vous, pour vous aider à faire la différence entre vos profils.</string>
|
||||
<!-- Menu entry to sort an item to the beginning of a list. Only "To Top" may do as well in some translations, if that helps to stay shorter. -->
|
||||
<string name="move_to_top">Remonter l\'élément</string>
|
||||
<string name="delete_account">Supprimer le compte</string>
|
||||
<string name="delete_account_ask">Voulez-vous vraiment supprimer les données de votre compte ?</string>
|
||||
<string name="delete_account_explain_with_name">Toutes les données de compte de « %s » sur cet appareil seront effacées, y compris votre configuration de chiffrement de bout en bout, vos contacts, discussions, messages et médias. Cette action est irrévocable.</string>
|
||||
<string name="unconfigured_account">Compte non configuré</string>
|
||||
<string name="unconfigured_account_hint">Ouvrir le compte pour le configurer</string>
|
||||
<string name="move_to_top">Placer en premier</string>
|
||||
<string name="delete_account">Supprimer le profil</string>
|
||||
<string name="delete_account_ask">Voulez-vous vraiment supprimer les données de votre profil ?</string>
|
||||
<string name="delete_account_explain_with_name">Toutes les données du profil « %s » sur cet appareil seront effacées, y compris la configuration du chiffrement de bout en bout, vos contacts, discussions, messages et fichiers multimédias. Cette action est irrévocable.</string>
|
||||
<string name="unconfigured_account">Profil non configuré</string>
|
||||
<string name="unconfigured_account_hint">Ouvrir le profil pour le configurer</string>
|
||||
<string name="try_connect_now">Essayer de se connecter maintenant</string>
|
||||
<string name="sync_all">Tout synchroniser</string>
|
||||
<!-- Translations: %1$s will be replaced by a more detailed error message -->
|
||||
@@ -718,7 +730,7 @@
|
||||
<!-- first placeholder is replaced by the number of files (always 2 or more); second placeholder is replaced by a chat name -->
|
||||
<string name="ask_send_files_to_chat">Envoyer %1$d fichiers à « %2$s » ?</string>
|
||||
<string name="ask_send_files_to_selected_chats">Envoyer %1$d fichier(s) à %2$d discussions ?</string>
|
||||
<string name="videos_sent_without_recoding">(Les vidéos sont envoyés au format original, en conséquence volumineux. Pour envoyer des fichiers de plus petite taille, joignez-les séparément.)</string>
|
||||
<string name="videos_sent_without_recoding">(Les vidéos sont envoyées en tant que fichiers originaux, donc volumineux. Il faut les envoyer une par une pour qu\'elles soient réencodées automatiquement en fichiers plus légers.)</string>
|
||||
<string name="share_text_multiple_chats">Envoyer ce texte à %1$d discussions ?\n\n« %2$s »</string>
|
||||
<string name="share_abort">Partage annulé en raison de permissions manquantes.</string>
|
||||
|
||||
@@ -726,7 +738,7 @@
|
||||
<!-- preferences -->
|
||||
<string name="pref_using_custom">Usage de la personnalisation : %s</string>
|
||||
<string name="pref_using_default">Utilisation par défaut : %s</string>
|
||||
<string name="pref_profile_info_headline">Informations de votre profil</string>
|
||||
<string name="pref_profile_info_headline">Votre profil</string>
|
||||
<string name="pref_profile_photo">Photo de profil</string>
|
||||
<string name="pref_blocked_contacts">Contacts bloqués</string>
|
||||
<string name="blocked_empty_hint">Si vous bloquez des contacts, ils seront affichés ici.</string>
|
||||
@@ -734,11 +746,12 @@
|
||||
<string name="pref_your_name">Votre nom</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Signature</string>
|
||||
<string name="pref_enter_sends">Entrer les envois de clés</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Touche Entrée pour envoyer</string>
|
||||
<string name="pref_enter_sends_explain">Appuyez sur la touche Entrée pour envoyer des messages texte</string>
|
||||
<string name="pref_outgoing_media_quality">Qualité du média en sortie</string>
|
||||
<string name="pref_outgoing_balanced">Équilibré</string>
|
||||
<string name="pref_outgoing_worse">Pire qualité, taille réduite</string>
|
||||
<string name="pref_outgoing_worse">Qualité la plus basse, taille réduite</string>
|
||||
<string name="pref_vibrate">Vibrer</string>
|
||||
<string name="pref_screen_security">Écran de sécurité</string>
|
||||
<!-- Translators: Must indicate that there is no guarantee as the system may not honor our request. -->
|
||||
@@ -746,7 +759,7 @@
|
||||
<string name="pref_screen_security_please_restart_hint">Pour appliquer les paramètres de sécurité de l\'écran, veuillez redémarrer l\'application.</string>
|
||||
<string name="pref_notifications">Notifications</string>
|
||||
<string name="pref_mention_notifications">Mentions</string>
|
||||
<string name="pref_mention_notifications_explain">Dans les groupes passés en muet, des notifications vous sont envoyées, comme des réponses ou des réactions</string>
|
||||
<string name="pref_mention_notifications_explain">Dans les groupes mis en sourdine, notifier les messages qui vous sont adressés, tels que les réponses ou les réactions</string>
|
||||
<string name="pref_notifications_show">Afficher</string>
|
||||
<string name="pref_notifications_priority">Priorité</string>
|
||||
<string name="pref_notifications_explain">Activer les notifications système pour les nouveaux messages</string>
|
||||
@@ -757,7 +770,7 @@
|
||||
<string name="pref_silent">Silencieux</string>
|
||||
<string name="pref_privacy">Vie privée</string>
|
||||
<!-- deprecated, use pref_chats -->
|
||||
<string name="pref_chats_and_media">Discussions et fichiers multimédia</string>
|
||||
<string name="pref_chats_and_media">Discussions et fichiers multimédias</string>
|
||||
<string name="pref_system_default">Valeur par défaut du système</string>
|
||||
<!-- Translators: as in "opposite of dark" -->
|
||||
<string name="pref_light_theme">Clair</string>
|
||||
@@ -777,8 +790,8 @@
|
||||
<string name="pref_chats">Discussions</string>
|
||||
<string name="pref_in_chat_sounds">Sons de messages entrants</string>
|
||||
<string name="pref_view_log">Voir le journal</string>
|
||||
<string name="pref_saved_log">Journal enregistré dans le dossier \"Téléchargements\"</string>
|
||||
<string name="pref_save_log_failed">Enregistrement du journal échoué</string>
|
||||
<string name="pref_saved_log">Journal enregistré dans le dossier « Téléchargements »</string>
|
||||
<string name="pref_save_log_failed">Échec de l\'enregistrement du journal</string>
|
||||
<string name="pref_log_header">Journal</string>
|
||||
<string name="pref_other">Autre</string>
|
||||
<string name="pref_backup">Sauvegarde</string>
|
||||
@@ -786,7 +799,7 @@
|
||||
<string name="pref_backup_export_explain">Une sauvegarde vous aide à configurer une nouvelle installation sur cet appareil ou sur un autre.\n\nLa sauvegarde contiendra tous vos messages, tous vos contacts et toutes vos discussions, ainsi que vos paramètres de chiffrement de bout en bout Autocrypt. Conservez le fichier de sauvegarde dans un endroit sûr, ou supprimez-le aussitôt utilisé.</string>
|
||||
<string name="pref_backup_export_this">Exporter ce profil</string>
|
||||
<!-- the placeholder will be replaced by the number of profiles to export; the number is always larger than 1 -->
|
||||
<string name="pref_backup_export_all">Exporter les %1$d comptes</string>
|
||||
<string name="pref_backup_export_all">Exporter les %1$d profils</string>
|
||||
<string name="pref_backup_export_start_button">Démarrer la sauvegarde</string>
|
||||
<string name="pref_backup_written_to_x">Sauvegarde effectuée avec succès sur %1$s</string>
|
||||
<!-- No need to translate "Wallpaper" literally. Chose what is common in your language for a "Wallpaper" or a "Background". Avoid adding the term "image" here, as the "Wallpaper" may also be just a single color. -->
|
||||
@@ -795,9 +808,9 @@
|
||||
<string name="pref_background_btn_gallery">Sélectionner depuis la galerie</string>
|
||||
<string name="pref_imap_folder_warn_disable_defaults">Si vous désactivez cette option, assurez-vous que votre serveur et vos autres clients sont configurés en conséquence.\n\nSinon des choses pourraient ne pas fonctionner du tout.</string>
|
||||
<!-- No need to be literal here, you can also use "Use Multiple Devices", "Support Multiple Devices" or other fitting terms. However, it should fit to the wording or your language at https://delta.chat/help -->
|
||||
<string name="pref_multidevice">Mode multi-appareils</string>
|
||||
<string name="pref_multidevice_explain">Synchronise vos messages avec vos autres appareils. Activé automatiquement lors de l\'ajout d\'un second appareil</string>
|
||||
<string name="pref_multidevice_change_warn">Le mode multi-appareils doit être activé quand vous utilisez le mêmeprofil/compte sur plusieurs appareils. Désactivez cette option seulement si vousavez supprimé le profil de vos autres appareils.\n\nDésactiver le mode alors que vous utilisez le compte sur de multiples appareils causera le manquement de messages et autres problèmes.</string>
|
||||
<string name="pref_multidevice">Mode appareils multiples</string>
|
||||
<string name="pref_multidevice_explain">Synchronise vos messages avec vos autres appareils. Activé automatiquement lorsque vous ajoutez un deuxième appareil</string>
|
||||
<string name="pref_multidevice_change_warn">Le mode appareils multiples doit être activé quand vous utilisez le même profil sur plusieurs appareils. Désactivez cette option seulement si vous avez supprimé ce profil de vos autres appareils.\n\nDésactiver le mode alors que vous utilisez un profil sur plusieurs appareils causera un certain nombre de problèmes, dont des messages perdus.</string>
|
||||
<string name="pref_auto_folder_moves">Déplacer automatiquement vers le dossier DeltaChat</string>
|
||||
<string name="pref_only_fetch_mvbox_title">Ne consulter que le dossier DeltaChat</string>
|
||||
<string name="pref_show_emails">Voir les courriels classiques</string>
|
||||
@@ -805,7 +818,7 @@
|
||||
<string name="pref_show_emails_accepted_contacts">Pour les contacts acceptés</string>
|
||||
<string name="pref_show_emails_all">Tout</string>
|
||||
<string name="pref_experimental_features">Fonctionnalités expérimentales</string>
|
||||
<string name="pref_experimental_features_explain">Ces fonctionnalités peuvent être instable et être changées ou supprimées dans le futur</string>
|
||||
<string name="pref_experimental_features_explain">Ces fonctionnalités peuvent présenter des instabilités, être modifiées ou supprimées</string>
|
||||
<string name="pref_on_demand_location_streaming">Envoi de la géolocalisation à la demande</string>
|
||||
<string name="pref_background_default">Image par défaut</string>
|
||||
<string name="pref_background_default_color">Couleur par défaut</string>
|
||||
@@ -815,29 +828,30 @@
|
||||
<string name="auto_download_messages">Télécharger les messages automatiquement</string>
|
||||
<!-- %1$s will be replaced by a human-readable number of bytes, eg. 32 KiB, 1 MiB -->
|
||||
<string name="up_to_x">Jusqu\'à %1$s</string>
|
||||
<string name="up_to_x_most_worse_quality_images">Jusqu\'à %1$s, plus mauvaise qualité d\'image</string>
|
||||
<string name="up_to_x_most_balanced_quality_images">Jusqu\'à %1$s, qualité d\'image raisonnable </string>
|
||||
<string name="up_to_x_most_worse_quality_images">Jusqu\'à %1$s, plus basse qualité d\'image</string>
|
||||
<string name="up_to_x_most_balanced_quality_images">Jusqu\'à %1$s, qualité d\'image la plus équilibrée </string>
|
||||
<string name="download_failed">Échec du téléchargement</string>
|
||||
<!-- %1$s will be replaced by a human-readable number of bytes, eg. 32 KiB, 1 MiB. Resulting string eg. "1 MiB message" -->
|
||||
<string name="n_bytes_message">%1$s message</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Télécharger le plus possible jusqu\'à %1$s</string>
|
||||
<string name="select_profile">Séléctionner le profil</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Sélectionner un profil</string>
|
||||
<string name="profile_image_select">Sélectionnez l\'image de profil</string>
|
||||
<string name="select_your_new_profile_image">Sélectionnez votre nouvelle image de profil</string>
|
||||
<string name="profile_image_delete">Supprimer l\'image de profil</string>
|
||||
<string name="pref_show_tray_icon">Afficher l\'icône dans la zone de notifications</string>
|
||||
<string name="pref_edit_profile">Édition du profil</string>
|
||||
<string name="pref_edit_profile">Modifier le profil</string>
|
||||
<string name="disable_imap_idle">Désactiver IMAP IDLE</string>
|
||||
<string name="disable_imap_idle_explain">N\'utilisez pas d\'extension IMAP IDLE, même si elle est prise en charge par votre serveur, car elle provoque des retards dans la récupération des messages. Activez cette option uniquement pour effectuer des tests.</string>
|
||||
<string name="send_stats_to_devs">Envoyer les statistiques aux développeurs Delta Chat</string>
|
||||
<string name="stats_device_message">Voulez-vous aider à améliorer Delta Chat et soutenir notre recherche en envoyant des statistiques d\'utilisation hebdomadaires ?\n\n👉 Touchez ici... 👈</string>
|
||||
<string name="stats_confirmation_dialog">Voulez-vous aider à améliorer Delta Chat et soutenir notre recherche en envoyant des statistiques d\'utilisation hebdomadaires ?</string>
|
||||
<string name="stats_thanks">Merci ! Vous pouvez toujours désactiver l\'envoi dans \"Paramètres -> Avancé\".\n\nAvez-vous en plus 5 minutes pour participer à une étude scientifique sur la sécurité de Delta Chat ?</string>
|
||||
<string name="send_stats_to_devs">Envoyer les statistiques aux développeurs de Delta Chat</string>
|
||||
<string name="stats_device_message">Voulez-vous participer à l\'amélioration de Delta Chat et soutenir nos recherches en envoyant des statistiques d\'utilisation hebdomadaires de manière anonyme ?\n\n👉 Appuyez ici… 👈</string>
|
||||
<string name="stats_confirmation_dialog">Voulez-vous participer à l\'amélioration de Delta Chat et soutenir nos recherches en envoyant des statistiques d\'utilisation hebdomadaires de manière anonyme ?</string>
|
||||
<string name="stats_thanks">Merci ! Vous pouvez toujours désactiver l\'envoi dans \"Paramètres -> Avancé\".\n\nAuriez-vous 5 minutes de plus pour participer à une étude scientifique sur la sécurité de Delta Chat ?</string>
|
||||
<string name="stats_disable_dialog">L\'envoi de statistiques est déjà activé.\n\nSouhaitez-vous le désactiver ?</string>
|
||||
<string name="disable">Désactiver</string>
|
||||
<string name="stats_keep_sending">Continuer l\'envoi</string>
|
||||
<string name="stats_msg_body">La pièce jointe contient des statistiques d\'usage anonymisés, qui nous aide à améliorer Delta Chat. Merci !</string>
|
||||
<string name="stats_keep_sending">Maintenir l\'envoi de statistiques</string>
|
||||
<string name="stats_msg_body">La pièce jointe contient des statistiques d\'utilisation anonymisées qui nous aide à améliorer Delta Chat. Vous pouvez consulter la page https://delta.chat/fr/help#statssending pour en savoir plus. Merci !</string>
|
||||
|
||||
<!-- Emoji picker and categories -->
|
||||
<string name="emoji_search_results">Résultats de la recherche</string>
|
||||
@@ -857,9 +871,9 @@
|
||||
<!-- Verb, the action of adding a "Reaction" to a message. Used eg. in context menus, similar to "Reply" or "Forward" -->
|
||||
<string name="react">Réagir</string>
|
||||
<!-- %1$s will be replaced by an emoji. %2$s will be replaced by message summary (the summary is often long and whole string gets truncated; words after %2$s will often not being visible). Eg. 'You reacted 👍 to "Found my suitcase"'. Use less than 20 characters, otherwise the string will be truncated too soon and too few information are shown. Do not try to translate "reacted to" too strict. Depending on the language, "added 👍 to" or "gave 👍 to" or just "👍 to" may be shorter and/or clearer and work as well. -->
|
||||
<string name="reaction_by_you">Vous avez réagi %1$spour \"%2$s\"</string>
|
||||
<string name="reaction_by_you">Vous avez réagi avec %1$s à « %2$s »</string>
|
||||
<!-- %1$s will be replaced a name. %2$s will be replaced by an emoji. %3$s will be replaced by message summary (the summary is often long and whole string gets truncated; words after %3$s will often not being visible). Eg. 'Alice reacted 👍 to "Nice photos"'. Use less than 20 characters, otherwise the string will be truncated too soon and too few information are shown. Do not try to translate "reacted to" too strict. Depending on the language, "added 👍 to" or "gave 👍 to" or just "👍 to" may be shorter and/or clearer work as well. -->
|
||||
<string name="reaction_by_other">%1$s a réagi %2$s à « %3$s »</string>
|
||||
<string name="reaction_by_other">%1$s a réagi avec %2$s à « %3$s »</string>
|
||||
|
||||
<!-- automatically delete message -->
|
||||
<string name="delete_old_messages">Supprimer les anciens messages</string>
|
||||
@@ -868,20 +882,20 @@
|
||||
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
|
||||
<string name="autodel_device_ask">Voulez-vous supprimer %1$d messages maintenant ainsi que tous les nouveaux futurs messages reçus « %2$s » ?\n\n• Cela inclut tous les fichiers multimédia\n\n• Les messages seront effacés qu\'ils aient été vus ou non\n\n• Les « Messages sauvegardés » seront préservés de la suppression locale</string>
|
||||
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
|
||||
<string name="autodel_server_ask">Voulez-vous supprimer %1$d messages maintenant ainsi que tous les futurs nouveaux messages reçus « %2$s » ?\n\n⚠️ Cela inclut les courriels, les fichiers multimédia et les « Messages sauvegardés » dans tous les répertoires du serveur\n\n⚠️ N\'utilisez pas cette fonction si vous utilisez d\'autres clients de messagerie électronique en plus de Delta Chat</string>
|
||||
<string name="autodel_server_ask">Voulez-vous supprimer %1$d messages maintenant ainsi que tous les futurs messages reçus « %2$s » ?\n\n⚠️ Cela inclut les courriels, les fichier multimédias et les « Messages enregistrés » dans tous les répertoires du serveur\n\n⚠️ N\'utilisez pas cette fonctionnalité si vous voulez conserver vos données sur le serveur ou si vous utilisez des clients de courriel classiques en plus de Delta Chat</string>
|
||||
<!-- shown below enabled autodel_server-option, should be a summary of autodel_server_ask and remind about the impact -->
|
||||
<string name="autodel_server_enabled_hint">Cela inclus les courriels, médias et les « Messages sauvegardés » dans tous les répertoires du serveur. N\'utilisez pas cette fonction si vous voulez garder les données sur le serveur ou si vous utilisez d\'autres clients de messagerie électronique en plus de Delta Chat.</string>
|
||||
<string name="autodel_server_enabled_hint">Cela inclut les courriels, les fichiers multimédias et les « Messages enregistrés » dans tous les répertoires du serveur. N\'utilisez pas cette fonctionnalité si vous voulez conserver vos données sur le serveur ou si vous utilisez des clients de courriel classiques en plus de Delta Chat</string>
|
||||
<string name="autodel_server_warn_multi_device_title">Activer la suppression immédiate</string>
|
||||
<string name="autodel_server_warn_multi_device">Si vous activez la suppression immédiate, vous ne pourrez pas utiliser plusieurs appareils sur ce profil.</string>
|
||||
<string name="autodel_confirm">J\'ai compris, supprimer tous ces messages</string>
|
||||
<!-- "At once" in the meaning of "Immediately", without any intervening time. -->
|
||||
<string name="autodel_at_once">Immédiatement</string>
|
||||
<string name="autodel_at_once">Tout de suite après le téléchargement</string>
|
||||
<string name="after_5_minutes">Après 5 minutes</string>
|
||||
<string name="autodel_after_1_hour">Après 1 heure</string>
|
||||
<string name="autodel_after_1_day">Après 1 jour</string>
|
||||
<string name="autodel_after_1_week">Après 1 semaine</string>
|
||||
<string name="after_5_weeks">Après 5 semaines</string>
|
||||
<string name="autodel_after_1_year">Après 1 année</string>
|
||||
<string name="autodel_after_1_year">Après 1 an</string>
|
||||
|
||||
<!-- system messages -->
|
||||
<string name="systemmsg_subject_for_new_contact">Message de %1$s</string>
|
||||
@@ -918,55 +932,55 @@
|
||||
<string name="location_enabled_by_you">Vous avez activé l\'envoi de votre position.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="location_enabled_by_other">%1$s a activé l\'envoi de sa position.</string>
|
||||
<string name="ephemeral_timer_disabled_by_you">Vous avez désactivé la minuterie des messages éphémères.</string>
|
||||
<string name="ephemeral_timer_disabled_by_you">Vous avez désactivé le délai avant disparition des messages éphémères.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_disabled_by_other">Minuterie des messages éphémères désactivée par %1$s.</string>
|
||||
<string name="ephemeral_timer_disabled_by_other">Délai avant disparition des messages éphémères désactivé par %1$s.</string>
|
||||
<!-- %1$s will be replaced by the number of seconds (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_seconds_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à %1$s seconde(s).</string>
|
||||
<string name="ephemeral_timer_seconds_by_you">Vous avez défini le délai avant disparition des messages éphémères à %1$s secondes.</string>
|
||||
<!-- %1$s will be replaced by the number of seconds (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_seconds_by_other">Minuterie des messages éphémères réglée à %1$s secondes par %2$s.</string>
|
||||
<string name="ephemeral_timer_seconds_by_other">Délai avant disparition des messages éphémères défini à %1$s secondes par %2$s.</string>
|
||||
<!-- deprecated, usage needs to be removed in core -->
|
||||
<string name="ephemeral_timer_1_minute_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à 1 minute.</string>
|
||||
<string name="ephemeral_timer_1_minute_by_you">Vous avez défini le délai avant disparition des messages éphémères à 1 minute.</string>
|
||||
<!-- deprecated, usage needs to be removed in core -->
|
||||
<string name="ephemeral_timer_1_minute_by_other">Minuterie des messages éphémères réglée à 1 minute par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_hour_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à 1 heure.</string>
|
||||
<string name="ephemeral_timer_1_minute_by_other">Délai avant disparition des messages éphémères défini à 1 minute par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_hour_by_you">Vous avez défini le délai avant disparition des messages éphémères à 1 heure.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_hour_by_other">Minuterie des messages éphémères réglée à 1 heure par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_day_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à 1 jour.</string>
|
||||
<string name="ephemeral_timer_1_hour_by_other">Délai avant disparition des messages éphémères défini à 1 heure par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_day_by_you">Vous avez défini le délai avant disparition des messages éphémères à 1 jour.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_day_by_other">Minuterie des messages éphémères réglée à 1 jour par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_week_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à 1 semaine.</string>
|
||||
<string name="ephemeral_timer_1_day_by_other">Délai avant disparition des messages éphémères défini à 1 jour par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_week_by_you">Vous avez défini le délai avant disparition des messages éphémères à 1 semaine.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_week_by_other">Minuterie des messages éphémères réglée à 1 semaine par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_year_by_you">Vous avez défini le compte à rebours de disparition des messages à 1 an.</string>
|
||||
<string name="ephemeral_timer_1_week_by_other">Délai avant disparition des messages éphémères défini à 1 semaine par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_year_by_you">Vous avez défini le délai avant disparition des messages éphémères à 1 an.</string>
|
||||
<!-- %1$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_1_year_by_other">Compte à rebours de disparition des messages définit à 1 an par %1$s.</string>
|
||||
<string name="ephemeral_timer_1_year_by_other">Délai avant disparition des messages éphémères défini à 1 an par %1$s.</string>
|
||||
<!-- %1$s will be replaced by the number of minutes (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_minutes_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à %1$s minutes.</string>
|
||||
<string name="ephemeral_timer_minutes_by_you">Vous avez défini le délai avant disparition des messages éphémères à %1$s minutes.</string>
|
||||
<!-- %1$s will be replaced by the number of minutes (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_minutes_by_other">Minuterie des messages éphémères réglée à %1$s minutes par %2$s.</string>
|
||||
<string name="ephemeral_timer_minutes_by_other">Délai avant disparition des messages éphémères défini à %1$s minutes par %2$s.</string>
|
||||
<!-- %1$s will be replaced by the number of hours (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_hours_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à %1$s heures.</string>
|
||||
<string name="ephemeral_timer_hours_by_you">Vous avez défini le délai avant disparition des messages éphémères à %1$s heures.</string>
|
||||
<!-- %1$s will be replaced by the number of hours (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_hours_by_other">Minuterie des messages éphémères réglée à %1$s heures par %2$s.</string>
|
||||
<string name="ephemeral_timer_hours_by_other">Délai avant disparition des messages éphémères défini à %1$s heures par %2$s.</string>
|
||||
<!-- %1$s will be replaced by the number of days (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_days_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à %1$s jours.</string>
|
||||
<string name="ephemeral_timer_days_by_you">Vous avez défini le délai avant disparition des messages éphémères à %1$s jours.</string>
|
||||
<!-- %1$s will be replaced by the number of days (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_days_by_other">Minuterie des messages éphémères réglée à %1$s jours par %2$s.</string>
|
||||
<string name="ephemeral_timer_days_by_other">Délai avant disparition des messages éphémères défini à %1$s jours par %2$s.</string>
|
||||
<!-- %1$s will be replaced by the number of weeks (always >1) the timer is set to -->
|
||||
<string name="ephemeral_timer_weeks_by_you">Vous avez réglé le temps d\'affichage des messages éphémères à %1$s semaines.</string>
|
||||
<string name="ephemeral_timer_weeks_by_you">Vous avez défini le délai avant disparition des messages éphémères à %1$s semaines.</string>
|
||||
<!-- %1$s will be replaced by the number of weeks (always >1) the timer is set to, %2$s will be replaced by name of the contact -->
|
||||
<string name="ephemeral_timer_weeks_by_other">Minuterie des messages éphémères réglée à %1$s semaines par %2$s.</string>
|
||||
<string name="chat_unencrypted_explanation">Les messages de cette conversation utilisent le mail classique et ne sont pas chiffrés de bout-en-bout.</string>
|
||||
<string name="chat_protection_enabled_tap_to_learn_more">Les messages sont désormais garantis chiffrés de bout en bout. Appuyer pour en savoir plus.</string>
|
||||
<string name="chat_protection_enabled_explanation">Il n\'est pas garanti que tous les messages de cette discussion sont chiffrés de bout en bout.\n\nLe chiffrement de bout en bout assure la confidentialité des messages échangés par les membres d\'une discussion. Même votre fournisseur de courriel ne peut pas les lire. </string>
|
||||
<string name="ephemeral_timer_weeks_by_other">Délai avant disparition des messages éphémères défini à %1$s semaines par %2$s.</string>
|
||||
<string name="chat_unencrypted_explanation">Les messages de cette discussion utilisent le courriel classique et ne sont pas chiffrés de bout en bout.</string>
|
||||
<string name="chat_protection_enabled_tap_to_learn_more">Les messages sont chiffrés de bout en bout. Toucher pour en savoir plus.</string>
|
||||
<string name="chat_protection_enabled_explanation">Tous les messages de cette discussion sont chiffrés de bout-en-bout.\n\nLe chiffrement de bout-en-bout garantit la confidentialité des messages échangés par les membres d\'une discussion. Même les serveurs, les fournisseurs de courriel et les relais ne peuvent pas les lire. </string>
|
||||
<string name="invalid_unencrypted_tap_to_learn_more">⚠️ %1$s nécessite un chiffrement de bout en bout qui n\'est pas encore configuré sur cette discussion. Appuyez pour en savoir plus.</string>
|
||||
<string name="invalid_unencrypted_explanation">Pour établir un chiffrement de bout en bout vous pouvez rencontrer vos contacts en personne et scanner leur code QR.</string>
|
||||
<string name="invalid_unencrypted_explanation">Pour mettre en place le chiffrement de bout-en-bout, vous pouvez rencontrer vos contacts en personne et les ajouter en scannant leur code QR.</string>
|
||||
<string name="learn_more">En savoir plus</string>
|
||||
|
||||
<string name="devicemsg_self_deleted">Vous avez supprimé la discussion \"Messages sauvegardés\".\n\nℹ️ Pour utiliser la fonctionnalité \"Message enregistrés\" à nouveau, commencez une nouvelle discussion avec vous-même.</string>
|
||||
<string name="devicemsg_self_deleted">Vous avez supprimé la discussion « Messages enregistrés ».\n\nℹ️ Pour utiliser la fonctionnalité « Messages enregistrés » à nouveau, commencez une nouvelle discussion avec vous-même.</string>
|
||||
<!-- %1$s will be replaced by the amount of storage already used, sth. as '500 MB'. If you want to use a percentage sign, type in two of them, eg. %1$s %% -->
|
||||
<string name="devicemsg_storage_exceeding">⚠️ Bientôt plus d\'espace de stockage chez votre fournisseur, %1$s%% utilisés.\n\nVous ne serez peut-être plus en mesure de recevoir des messages quand votre espace de stockage sera plein.\n\n👉 Veuillez vérifier si vous avez d\'anciens éléments à supprimer directement sur l\'interface web de votre fournisseur et envisagez d\'activer \"Paramètres / Supprimer les anciens messages\". Vous pouvez vérifier à tout moment le volume d\'espace de stockage en cours d\'utilisation depuis \"Paramètres / Connectivité\".</string>
|
||||
<string name="devicemsg_storage_exceeding">⚠️ Bientôt plus d\'espace de stockage chez votre fournisseur : %1$s%% utilisés.\n\nQuand il sera plein, vous ne pourrez probablement plus recevoir de messages.\n\n👉 Vérifiez si vous pouvez supprimer des éléments anciens directement via l\'interface web de votre fournisseur, et envisagez d\'activer l\'option « Paramètres/ Discussions/ Supprimer les anciens messages ». Vous pouvez vérifier à tout moment le volume utilisé dans votre espace de stockage depuis « Paramètres/ Connectivité ».</string>
|
||||
<!-- %1%s will be replaced by date and time in some human-readable format -->
|
||||
<string name="devicemsg_bad_time">⚠️ L\'heure ou la date de votre appareil semble erronée (%1$s).\n\nRéglez votre horloge ⏰🔧 pour que vos messages soient bien reçus.</string>
|
||||
<string name="devicemsg_update_reminder">⚠️ Votre version de Delta Chat semble obsolète.\n\nCela risque de créer des dysfonctionnements parce que vos contacts utilisent des versions plus récentes - en plus, vous ratez les nouvelles fonctionnalités 😳\n Rendez-vous sur https://get.delta.chat ou sur votre magasin d\'applications pour effectuer la mise à jour !</string>
|
||||
@@ -978,25 +992,25 @@
|
||||
<string name="qr_code">Code QR</string>
|
||||
<string name="load_qr_code_as_image">Charger le code QR comme une image</string>
|
||||
<string name="qrscan_title">Scanner le code QR</string>
|
||||
<string name="qrscan_hint">Placez votre caméra au dessus du QR code</string>
|
||||
<string name="qrscan_hint">Placez votre caméra au-dessus du code QR</string>
|
||||
<string name="qrscan_hint_desktop">Placez le code QR devant la caméra</string>
|
||||
<string name="qrscan_failed">Le code QR n\'a pas pu être décodé</string>
|
||||
<string name="qrscan_ask_join_group">Voulez-vous rejoindre le groupe \"%1$s\" ?</string>
|
||||
<string name="qrscan_ask_join_channel">Voulez-vous rejoindre le canal \"%1$s\" ?</string>
|
||||
<string name="qrscan_fingerprint_mismatch">L\'empreinte digitale numérisée ne correspond pas à la dernière empreinte digitale vue depuis %1$s</string>
|
||||
<string name="qrscan_no_addr_found">Ce QR code contient une empreinte digitale mais pas d\'adresse de courriel.\n\nPour une vérification externe, veuillez d\'abord établir une connexion cryptée avec le destinataire.</string>
|
||||
<string name="qrscan_no_addr_found">Ce code QR contient une empreinte numérique mais pas d\'adresse de courriel.\n\nPour une vérification externe, veuillez d\'abord établir une connexion chiffrée avec le destinataire.</string>
|
||||
<string name="qrscan_contains_text">Texte du QR code numérisé:\n\n%1$s</string>
|
||||
<string name="qrscan_contains_url">Url du QR code numérisé :\n\n%1$s</string>
|
||||
<string name="qrscan_fingerprint_label">Empreinte digitale</string>
|
||||
<string name="withdraw_verifycontact_explain">Ce code QR pourrait être scanné par d\'autre personnes pour vous contacter.\n\nVous pouvez désactiver le QR code ici et le réactiver en le scannant ici de nouveau.</string>
|
||||
<string name="withdraw_verifygroup_explain">Le code QR peut être scanné par d\'autres personnes pour rejoindre le groupe \"%1$s\".\n\nVous pouvez désactiver le QR code ici et le réactiver en le scannant ici de nouveau.</string>
|
||||
<string name="withdraw_joinbroadcast_explain">Ce code QR peut être scanné pour rejoindre le canal \"%1$s\".\n\nVous pouvez le réinitialiser, afin que ce code QR ou lien d\'invitation soit désactivé.</string>
|
||||
<string name="withdraw_verifycontact_explain">Ce code QR peut être scanné par d\'autres personnes pour vous contacter.\n\nVous pouvez le réinitialiser pour désactiver le code QR ou le lien d\'invitation existants.</string>
|
||||
<string name="withdraw_verifygroup_explain">Le code QR peut être scanné par d\'autres personnes pour rejoindre le groupe « %1$s ».\n\nVous pouvez le réinitialiser pour désactiver le code QR ou le lien d\'invitation existants.</string>
|
||||
<string name="withdraw_joinbroadcast_explain">Ce code QR peut être scanné par d\'autres personnes pour rejoindre le canal « %1$s ».\n\nVous pouvez le réinitialiser pour désactiver le code QR ou le lien d\'invitation existants.</string>
|
||||
<string name="withdraw_qr_code">Réinitialiser le code QR</string>
|
||||
<string name="revive_verifycontact_explain">Ce code QR pourrait être scanné par d\'autre personnes pour vous contacter.\n\nCe code QR n\'est pas actif sur cet appareil.</string>
|
||||
<string name="revive_verifycontact_explain">Ce code QR a été réinitialisé et n\'est plus valide.</string>
|
||||
<string name="revive_qr_code">Activer le QR Code</string>
|
||||
<string name="qrshow_title">QR Code d\'Invitation</string>
|
||||
<string name="qrshow_x_joining">%1$s rejoints.</string>
|
||||
<string name="qrshow_x_verified">%1$s connus.</string>
|
||||
<string name="qrshow_x_verified">%1$s ajouté.</string>
|
||||
<string name="qrshow_x_has_joined_group">%1$s a rejoint le groupe.</string>
|
||||
<string name="qrshow_join_group_title">QR code d\'invitation</string>
|
||||
<!-- This text is shown inside the "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the group name, eg. "Scan to join group \"Testing group\"" -->
|
||||
@@ -1006,28 +1020,28 @@
|
||||
<!-- This text is shown inside the "QR code card" with very limited space; please formulate the text as short as possible therefore. The placeholder will be replaced by the profile name eg. "Scan to chat with Alice" -->
|
||||
<string name="qrshow_join_contact_hint">Scanner pour discuter avec %1$s</string>
|
||||
<string name="qrshow_join_contact_no_connection_toast">Pas de connexion Internet, ne peut pas effectuer la configuration du QR code.</string>
|
||||
<string name="qraccount_ask_create_and_login">Créer une nouvelle adresse de courriel sur « %1$s » et se connecter ici ?</string>
|
||||
<string name="qraccount_ask_create_and_login">Créer un nouveau profil sur « %1$s » et s\'y connecter ?</string>
|
||||
<string name="set_name_and_avatar_explain">Choisissez un nom que vos contacts reconnaîtront. Vous pouvez également définir une image pour votre profil.</string>
|
||||
<string name="please_enter_name">Veuillez saisir un nom.</string>
|
||||
<string name="qraccount_qr_code_cannot_be_used">Le code QR scanné ne peut pas être utilisé pour ouvrir un nouveau compte.</string>
|
||||
<string name="qraccount_qr_code_cannot_be_used">Le code QR scanné ne peut pas être utilisé pour configurer un nouveau profil.</string>
|
||||
<!-- the placeholder will be replaced by the address of the profile -->
|
||||
<string name="qrlogin_ask_login">Se connecter au compte « %1$s » ?</string>
|
||||
<string name="qrlogin_ask_login">Se connecter à « %1$s » ?</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_started">%1$s vous a invité à rejoindre ce groupe.\n\nEn attente de la réponse de l’appareil de %2$s…</string>
|
||||
<!-- first placeholder will be replaced by name of the inviter, second placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_channel_started">%1$svous a invité à rejoindre ce canal.\n\nEn attente de la réponse de l\'appareil de %2$s...</string>
|
||||
<string name="secure_join_channel_started">%1$svous a envoyé une invitation à rejoindre ce canal.\n\nEn attente de réponse de l\'appareil de %2$s...</string>
|
||||
<!-- placeholder will be replaced by the name of the inviter. -->
|
||||
<string name="secure_join_replies">%1$s a répondu, en attente d’être ajouté au groupe…</string>
|
||||
<string name="secure_join_wait">Chiffrement de bout en bout en cours d\'établissement, merci de patienter...</string>
|
||||
<string name="contact_verified">%1$s connu.</string>
|
||||
<string name="secure_join_replies">%1$s a répondu. En attente de l\'ajout au groupe…</string>
|
||||
<string name="secure_join_wait">Connexion en cours, merci de patienter...</string>
|
||||
<string name="contact_verified">%1$s ajouté.</string>
|
||||
<string name="contact_blocked">Vous avez bloqué le contact</string>
|
||||
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
|
||||
<string name="verified_by">Connu par %1$s</string>
|
||||
<string name="verified_by_you">Connu par vous</string>
|
||||
<string name="verified_by_unknown">a introduit</string>
|
||||
<string name="verified_by">Ajouté par %1$s</string>
|
||||
<string name="verified_by_you">Ajouté par vous</string>
|
||||
<string name="verified_by_unknown">Ajouté</string>
|
||||
<!-- deprecated -->
|
||||
<string name="verified_contact_required_explain">Pour garantir le chiffrement de bout en bout, vous pouvez ajouter à ce groupe uniquement les contacts avec un badge vert.\n\nVous pouvez rencontrer ces contacts en personne pour scanner leur code QR et les ajouter à votre liste de contacts connus.</string>
|
||||
<string name="mailto_dialog_header_select_chat">Sélectionnez une discussion à qui envoyer le message</string>
|
||||
<string name="mailto_dialog_header_select_chat">Sélectionnez une discussion où envoyer le message</string>
|
||||
<!-- first placeholder is the name of the chat -->
|
||||
<string name="confirm_replace_draft">%1$sa déjà un message en brouillon, voulez-vous le remplacer?</string>
|
||||
<string name="mailto_link_could_not_be_decoded">Le lien mailto n\'a pas pu être décodé: %1$s</string>
|
||||
@@ -1042,7 +1056,7 @@
|
||||
<string name="notify_name_only">Nom seulement</string>
|
||||
<string name="notify_no_name_or_message">Pas de nom ou de message</string>
|
||||
<string name="notifications_disabled">Notifications désactivées</string>
|
||||
<string name="unreliable_bg_notifications">Activer \"Forcer la connexion en arrière-plan\" pour des notifications fiables</string>
|
||||
<string name="unreliable_bg_notifications">Activer « Forcer la connexion en arrière-plan » pour des notifications fiables</string>
|
||||
<string name="new_messages">Nouveaux messages</string>
|
||||
<!-- Body text for a generic "New messages" notification. Shown if we do not have more information about a new messages. Note, that the string is also referenced at https://github.com/deltachat/notifiers -->
|
||||
<string name="new_messages_body">Vous avez de nouveaux messages</string>
|
||||
@@ -1054,7 +1068,7 @@
|
||||
<string name="perm_continue">Continuez</string>
|
||||
<string name="perm_explain_access_to_camera_denied">Pour prendre des photos ou filmer des vidéos, aller au menu Paramètres de l\'application, sélectionnez \"Autorisations\" et autorisez \"Appareil photo\".</string>
|
||||
<!-- give the user an idea where to find the "Microphone" option. the hint is only shown if access was initially denied by the user. pick up wordings really used on the systems, but do not be overly precise: things shift around often and there are too many system we support to track every detail and click path -->
|
||||
<string name="perm_explain_access_to_mic_denied">Pour envoyer des messages audio, aller dans les paramètres de l\'application, sélectionner \"Autorisations\" et autoriser \"Microphone\".</string>
|
||||
<string name="perm_explain_access_to_mic_denied">Pour envoyer des messages audio, rendez-vous dans les paramètres de l\'application ou du système, sélectionnez « Autorisations » ou « Sécurité et confidentialité », et activez « Microphone ».</string>
|
||||
<string name="perm_explain_access_to_storage_denied">Pour recevoir ou envoyer des fichiers, aller dans les Paramètres de l\'application, sélectionner \"Autorisations\" et autoriser \"Stockage\".</string>
|
||||
<string name="perm_explain_access_to_location_denied">Pour joindre une position, aller au menu paramètres de l\'application, sélectionnez \"Autorisations\" et activez \"Position\".</string>
|
||||
<string name="perm_explain_access_to_notifications_denied">Pour recevoir les notifications, accédez à \"Paramètres système / Applications / Delta Chat\" et activez les \"Notifications\".</string>
|
||||
@@ -1076,13 +1090,13 @@
|
||||
<string name="global_menu_preferences_language_desktop">Choisissez la langue...</string>
|
||||
<string name="global_menu_file_desktop">Fichier</string>
|
||||
<string name="global_menu_file_quit_desktop">Quitter</string>
|
||||
<string name="global_menu_edit_desktop">Modifier</string>
|
||||
<string name="global_menu_edit_desktop">Édition</string>
|
||||
<string name="global_menu_edit_undo_desktop">Annuler</string>
|
||||
<string name="global_menu_edit_redo_desktop">Refaire</string>
|
||||
<string name="global_menu_edit_cut_desktop">Couper</string>
|
||||
<string name="global_menu_edit_copy_desktop">Copier</string>
|
||||
<string name="global_menu_edit_paste_desktop">Coller</string>
|
||||
<string name="global_menu_view_desktop">Voir</string>
|
||||
<string name="global_menu_view_desktop">Affichage</string>
|
||||
<string name="global_menu_view_floatontop_desktop">Flotter au dessus</string>
|
||||
<string name="global_menu_view_developer_desktop">Développeur</string>
|
||||
<string name="global_menu_view_developer_tools_desktop">Outils de développement</string>
|
||||
@@ -1100,14 +1114,14 @@
|
||||
<string name="more_info_desktop">En savoir plus</string>
|
||||
<string name="timestamp_format_m_desktop">MMM D</string>
|
||||
<string name="remove_desktop">Retirer</string>
|
||||
<string name="save_desktop">Sauvegardez</string>
|
||||
<string name="save_desktop">Enregistrer</string>
|
||||
<!-- Opposite of "Save". Undo a "Save" action. Similar to "Unmute", "Unpin". Could also be worded as "Save no longer" or so. -->
|
||||
<string name="unsave">Annuler la sauvegarde</string>
|
||||
<string name="unsave">Ne plus enregistrer</string>
|
||||
<string name="name_desktop">Nom</string>
|
||||
<string name="select_group_image_desktop">Choisir l\'image de groupe</string>
|
||||
<string name="export_backup_desktop">Exporter la sauvegarde</string>
|
||||
<string name="message_detail_sent_desktop">envoyé</string>
|
||||
<string name="message_detail_received_desktop">reçu</string>
|
||||
<string name="export_backup_desktop">Exporter une sauvegarde</string>
|
||||
<string name="message_detail_sent_desktop">Envoyé</string>
|
||||
<string name="message_detail_received_desktop">Reçu</string>
|
||||
<string name="menu.view.developer.open.log.folder">Ouvrir le dossier Journal</string>
|
||||
<string name="menu.view.developer.open.current.log.file">Ouvrir le fichier Journal courant</string>
|
||||
<string name="explain_desktop_minimized_disabled_tray_pref" tools:ignore="TypographyDashes">L\'icône système ne peut pas être enlevé car Delta Chat a été démarré avec l\'option --minimized.</string>
|
||||
@@ -1141,7 +1155,7 @@
|
||||
<string name="a11y_voice_message_hint_ios">Après l\'enregistrement, poussez deux fois pour envoyer. Pour le supprimer, balayez l\'écran avec deux doigts.</string>
|
||||
<string name="a11y_connectivity_hint">Double-cliquez pour afficher les détails de la connectivité.</string>
|
||||
<string name="login_error_no_internet_connection">Pas de connexion Internet, connexion échouée.</string>
|
||||
<string name="share_account_not_configured">Le compte n\'est pas configuré.</string>
|
||||
<string name="share_account_not_configured">Le profil n\'est pas configuré.</string>
|
||||
<string name="cannot_play_audio_file">Le fichier audio ne peut pas être joué.</string>
|
||||
<!-- iOS camera permission alert -->
|
||||
<string name="perm_ios_explain_access_to_camera_denied">Pour prendre des photos, des vidéos ou utiliser le scanneur de QR-Code, ouvrez les paramètres du système et activez \"Appareil photo\".</string>
|
||||
@@ -1156,14 +1170,14 @@
|
||||
<string name="notifications_avg_minutes">Toutes les %1$d minutes en moyenne</string>
|
||||
<string name="notifications_avg_hours">Toutes les %1$d heures en moyenne</string>
|
||||
<string name="last_check_at">Dernièrement vu à %1$s</string>
|
||||
<string name="system_settings">Paramètres du système</string>
|
||||
<string name="system_settings">Paramètres système</string>
|
||||
<!-- shown below the button "System Settings" on the notification screen. this is a hint about what can be edited on System Settings' Notification page - eg. the notification type (banner, lock screen, notification centre), sound, badges and so on. no need to be exhaustive here, it is only to give the user an idea. -->
|
||||
<string name="system_settings_notify_explain_ios">Éditer le type, les badges, les prévisualisation et plus encore.</string>
|
||||
<string name="system_settings_notify_explain_ios">Modifier le type de notification, les badges, les prévisualisations, etc.</string>
|
||||
<!-- iOS shortcut widget -->
|
||||
<!-- use the same translation for "Shortcuts" as the system is using, often the term "Shortcut" stays untranslated; check eg. how the "Shortcuts" system app is called in your locale -->
|
||||
<string name="shortcuts_widget_title">Raccourcis</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
<string name="shortcuts_widget_description">Utiliser la fonction \"Ajouter au Widget\" de Delta Chat pour ajouter un élément.</string>
|
||||
<string name="shortcuts_widget_description">Utiliser la fonction « Ajouter au Widget » de Delta Chat pour ajouter des éléments</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
<string name="remove_from_widget">Retirer du Widget</string>
|
||||
<!-- use the same translation for "Widget" as the system is using; often the term "Widget" stays untranslated -->
|
||||
@@ -1175,20 +1189,20 @@
|
||||
<string name="InfoPlist_NSMicrophoneUsageDescription">Delta Chat utilise votre micro pour enregistrer et envoyer des messages vocaux et des vidéos avec bande son.</string>
|
||||
<string name="InfoPlist_NSPhotoLibraryUsageDescription">Delta Chat vous laisse choisir quelles photos envoyer de votre photothèque. </string>
|
||||
<string name="InfoPlist_NSPhotoLibraryAddUsageDescription">Delta Chat veut enregistrer les images dans votre bibliothèque photo.</string>
|
||||
<string name="InfoPlist_NSFaceIDUsageDescription">Delta Chat peut utiliser le Face ID pour protéger votre profil en local et la création des sauvegardes, et pour la configuration d\'un second appareil.</string>
|
||||
<string name="InfoPlist_NSFaceIDUsageDescription">Delta Chat peut utiliser Face ID pour protéger votre profil local, la création de sauvegardes et la configuration d\'un deuxième appareil.</string>
|
||||
|
||||
<!-- android specific strings, developers: please take care to remove strings that are no longer used! -->
|
||||
<string name="pref_instant_delivery">Envoi Immédiat</string>
|
||||
<string name="pref_background_notifications">Utiliser une connexion en arrière plan</string>
|
||||
<string name="pref_background_notifications_explain">Requiert la désactivation des optimisations de battterie, utilisez cette option si les notifications sont en retard.</string>
|
||||
<string name="pref_reliable_service">Forcer une connexion en arrière plan</string>
|
||||
<string name="pref_instant_delivery"> Distribution immédiate</string>
|
||||
<string name="pref_background_notifications">Utiliser la connexion en arrière-plan</string>
|
||||
<string name="pref_background_notifications_explain">Nécessite que les optimisations de batterie soient désactivées. Utilisez cette option si vous recevez les notifications avec du retard.</string>
|
||||
<string name="pref_reliable_service">Forcer la connexion en arrière-plan</string>
|
||||
<string name="pref_reliable_service_explain">Entraîne une notification permanente.</string>
|
||||
|
||||
<string name="pref_background_notifications_rationale">Pour maintenir une connexion à votre serveur de courriel et recevoir les messages en arrière-plan, ignorez l\'optimisation de la batterie à l\'étape suivante.\n\nDelta Chat utilise peu de ressources et prend garde à ne pas vider votre batterie.</string>
|
||||
<string name="pref_background_notifications_rationale">Pour maintenir une connexion ininterrompue et recevoir les messages en arrière-plan, ignorez les optimisations de batterie à l\'étape suivante.\n\nDelta Chat utilise peu de ressources et fait attention à ne pas vider votre batterie.</string>
|
||||
<!-- disabling "Reliable service" will hide a the maybe annoying permanent-notification with the drawback that new-message-notifications get potentially unreliable -->
|
||||
<string name="perm_enable_bg_reminder_title">Touchez ici pour recevoir des messages pendant que DeltaChat est en arrière-plan.</string>
|
||||
<string name="perm_enable_bg_reminder_title">Touchez ici pour recevoir des messages pendant que Delta Chat est en arrière-plan.</string>
|
||||
<string name="perm_enable_bg_already_done">Vous avez déjà autorisé Delta Chat à recevoir des messages en arrière plan.\n\nSi vous ne les recevez toujours pas en arrière plan, vérifiez les paramètres de votre système.</string>
|
||||
|
||||
<!-- device messages for updates -->
|
||||
<string name="update_2_0">Quoi de neuf?\n\n💯 Le chiffrement de bout-en-bout est maintenant fiable et pérenne. 🔒Fini les cadenas !\n\n✉️ Les mails sans chiffrement de bout-en-bout sont maintenant marqués par une icône de mail \n\n😻 Nouvelle fenêtre de profil améliorée pour tous les contacts \n\n🔲 Nouveau bouton pour l\'accès rapide aux applis utilisées dans une discussion\n\n❤️ Merci d\'envisager de faire une donation afin que nous restions indépendants et continuions à améliorer Delta Chat: %1$s</string>
|
||||
<string name="update_2_0">Quoi de neuf ?\n\n💯 Le chiffrement de bout en bout est maintenant fiable et pérenne. 🔒Fini les cadenas !\n\n✉️ Les courriels sans chiffrement de bout en bout sont maintenant marqués par une icône enveloppe \n\n😻 Nouvelle fenêtre de profil améliorée pour tous les contacts \n\n🔲 Nouveau bouton pour l\'accès rapide aux applis utilisées dans une discussion\n\n❤️ Merci d\'envisager de faire un don afin que nous restions indépendants et continuions à améliorer Delta Chat : %1$s</string>
|
||||
</resources>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Arquivar</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Desarquivar</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Acalar</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Acalada</string>
|
||||
<string name="ephemeral_messages">Desaparición de Mensaxes</string>
|
||||
<string name="ephemeral_messages_hint">Estos axustes aplícanse a todas as participantes que usan Delta Chat. Porén, elas poderían copiar, gardar e reenviar mensaxes ou usar outros clientes de email.</string>
|
||||
@@ -168,6 +170,7 @@
|
||||
<string name="add_stickers_instructions">Para engadir adhesivos toca en \"Abrir cartafol de adhesivos\", crea un subcartafol para o paquete de adhesivos e arrastra alí ficheiros de imaxe e adhesivos</string>
|
||||
<string name="open_sticker_folder">Abrir cartafol de adhesivos</string>
|
||||
<string name="images">Imaxes</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Mensaxe de voz</string>
|
||||
<string name="forwarded">Reenviada</string>
|
||||
@@ -199,6 +202,7 @@
|
||||
<string name="games">Xogos</string>
|
||||
<string name="tools">Ferramentas</string>
|
||||
<string name="app_size">Tamaño</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Publicada</string>
|
||||
<string name="add_to_chat">Engadir á Conversa</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -660,6 +664,7 @@
|
||||
<string name="pref_your_name">O teu nome</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Texto de firma</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">A tecla Enter envía</string>
|
||||
<string name="pref_enter_sends_explain">Ao premer Enter enviarás a mensaxe</string>
|
||||
<string name="pref_outgoing_media_quality">Calidade de Multimedia Enviados</string>
|
||||
@@ -741,6 +746,7 @@
|
||||
<string name="n_bytes_message">%1$s mensaxe</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Descarga o máximo dispoñible ata %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Seleccionar Perfil</string>
|
||||
<string name="profile_image_select">Elixe imaxe de perfil</string>
|
||||
<string name="select_your_new_profile_image">Elixe a túa nova imaxe de perfil</string>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<string name="archive">Arhiviraj</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Dearhiviraj</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Prigušiti</string>
|
||||
<string name="ephemeral_messages">Nestajuće poruke</string>
|
||||
<string name="save">Spremi</string>
|
||||
@@ -175,6 +176,7 @@
|
||||
<string name="pref_profile_photo">Profilna slika</string>
|
||||
<string name="pref_blocked_contacts">Blokirani kontakti</string>
|
||||
<string name="pref_your_name">Vaše ime</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Enter šalje poruku</string>
|
||||
<string name="pref_enter_sends_explain">Pritisak na Enter će poslati tekst poruku</string>
|
||||
<string name="pref_vibrate">Vibracija</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Archiválás</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Archiválás visszavonása</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Némítás</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Némított</string>
|
||||
<string name="ephemeral_messages">Eltűnő üzenetek</string>
|
||||
<string name="ephemeral_messages_hint">A csevegés összes tagjára vonatkozik; az üzeneteket továbbra is másolhatják, menthetik és továbbíthatják.</string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">A matricák hozzáadásához koppintson a „Matricamappa megnyitása” lehetőségre, hozzon létre egy almappát a matricacsomagnak, és húzza oda a kép- és matricafájlokat.</string>
|
||||
<string name="open_sticker_folder">Matricamappa megnyitása</string>
|
||||
<string name="images">Képek</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Hang</string>
|
||||
<string name="voice_message">Hangüzenet</string>
|
||||
<string name="forwarded">Továbbított</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">Játékok</string>
|
||||
<string name="tools">Eszközök</string>
|
||||
<string name="app_size">Méret</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Közzétéve</string>
|
||||
<string name="add_to_chat">Hozzáadás csevegéshez</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -384,7 +388,9 @@
|
||||
<string name="answer_call">Fogadás</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Elutasítás</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Kimenő hívás</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Bejövő hívás</string>
|
||||
<string name="declined_call">Elutasított hívás</string>
|
||||
<string name="canceled_call">Visszavont hívás</string>
|
||||
@@ -704,6 +710,7 @@
|
||||
<string name="pref_your_name">Név</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Névjegy</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Küldés „Enterrel”</string>
|
||||
<string name="pref_enter_sends_explain">Az „Enter” billentyű megnyomásával szöveges üzeneteket küldhet</string>
|
||||
<string name="pref_outgoing_media_quality">Kimenő média minősége</string>
|
||||
@@ -787,6 +794,7 @@
|
||||
<string name="n_bytes_message">%1$s üzenet</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Letöltés maximum ennyi ideig visszamenőleg: %1$s </string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Profil kiválasztása</string>
|
||||
<string name="profile_image_select">Profilkép kiválasztása</string>
|
||||
<string name="select_your_new_profile_image">Válassza ki az új profilképet</string>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<string name="archive">Arsip</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Tidak diarsip</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Diam</string>
|
||||
<string name="ephemeral_messages">Pesan yang berhilangan</string>
|
||||
<string name="ephemeral_messages_hint">Pengaturan ini berlaku untuk semua peserta yang menggunakan Delta Chat. Namun, mereka dapat menyalin, menyimpan, dan meneruskan pesan atau menggunakan klien email lainnya.</string>
|
||||
@@ -130,6 +131,7 @@
|
||||
<!-- "Stickers" as known from other messengers; in some languages, the English "Sticker" is fine. -->
|
||||
<string name="sticker">Stiker</string>
|
||||
<string name="images">Gambar</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Pesan suara</string>
|
||||
<string name="forwarded">Diteruskan</string>
|
||||
@@ -402,6 +404,7 @@
|
||||
<string name="pref_your_name">Nama Anda</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Signature text</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Tombol Enter mengirim</string>
|
||||
<string name="pref_enter_sends_explain">Menekan tombol Enter akan mengirimkan teks pesan</string>
|
||||
<string name="pref_outgoing_media_quality">Kualitas media yang dikirim</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Archivia</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Ripristina</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Silenzia</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Silenziato</string>
|
||||
<string name="ephemeral_messages">Messaggi a Scomparsa</string>
|
||||
<string name="ephemeral_messages_hint">Si applica a tutti i membri di questa chat; possono comunque copiare, salvare e inoltrare i messaggi.</string>
|
||||
@@ -190,6 +192,7 @@
|
||||
<string name="add_stickers_instructions">Per aggiungere adesivi, tocca \"Apri Cartella Adesivi\", crea una sottocartella per il tuo pacchetto di adesivi e trascina lì i file di immagini e adesivi</string>
|
||||
<string name="open_sticker_folder">Apri Cartella Adesivi</string>
|
||||
<string name="images">Immagini</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Audio</string>
|
||||
<string name="voice_message">Messaggio Vocale</string>
|
||||
<string name="forwarded">Inoltrato</string>
|
||||
@@ -226,6 +229,7 @@
|
||||
<string name="games">Giochi</string>
|
||||
<string name="tools">Strumenti</string>
|
||||
<string name="app_size">Dimensione</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Pubblicato</string>
|
||||
<string name="add_to_chat">Aggiungi alla Chat</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -393,12 +397,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Chiama</string>
|
||||
<string name="start_audio_call">Chiamata Audio</string>
|
||||
<string name="start_video_call">Chiamata Video</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Rispondi</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Rifiuta</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Chiamata in uscita</string>
|
||||
<string name="outgoing_audio_call">Chiamata in uscita</string>
|
||||
<string name="outgoing_video_call">Videochiamata in uscita</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Chiamata in arrivo</string>
|
||||
<string name="incoming_audio_call">Chiamata in arrivo</string>
|
||||
<string name="incoming_video_call">Videochiamata in arrivo</string>
|
||||
<string name="declined_call">Chiamata rifiutata</string>
|
||||
<string name="canceled_call">Chiamata annullata</string>
|
||||
<string name="missed_call">Chiamata persa</string>
|
||||
@@ -734,6 +746,7 @@
|
||||
<string name="pref_your_name">Il tuo Nome</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Biografia</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Spedisci con Invio</string>
|
||||
<string name="pref_enter_sends_explain">Premendo il tasto Invio invierà i messaggi</string>
|
||||
<string name="pref_outgoing_media_quality">Qualità Media in Uscita</string>
|
||||
@@ -822,6 +835,7 @@
|
||||
<string name="n_bytes_message">%1$s messaggio</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Scaricamento disponibile massimo fino a %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Seleziona il Profilo</string>
|
||||
<string name="profile_image_select">Seleziona Immagine Profilo</string>
|
||||
<string name="select_your_new_profile_image">Seleziona la tua nuova immagine profilo</string>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<string name="archive">アーカイブ</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">元に戻す</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">ミュート</string>
|
||||
<string name="ephemeral_messages">消えるメッセージ</string>
|
||||
<string name="ephemeral_messages_hint">この設定は、Delta Chatの利用する参加者に適用されます。ただし、参加者はメッセージをコピーしたり、保存したり、転送したり、他のアプリを利用したりすることができます。</string>
|
||||
@@ -109,6 +110,7 @@
|
||||
<string name="reply_noun">返信</string>
|
||||
<string name="gif">Gif</string>
|
||||
<string name="images">画像</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">音楽</string>
|
||||
<string name="voice_message">音声メッセージ</string>
|
||||
<string name="forwarded">転送された</string>
|
||||
@@ -383,6 +385,7 @@
|
||||
<string name="pref_your_name">あなたの名前</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">署名</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">エンターキーで送信</string>
|
||||
<string name="pref_enter_sends_explain">エンターキーを押すとテキストメッセージが送信されます</string>
|
||||
<string name="pref_outgoing_media_quality">送信する画像や映像の画質</string>
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
<string name="archive">Aɣbaṛ </string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">Kkes aɣbaṛ</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">Sgugem</string>
|
||||
<!-- Adjective "smth is muted". used to describe a muted or silenced chat, that e.g. does not make noise or cause notifications -->
|
||||
<string name="muted">Yettwasgugmen </string>
|
||||
<string name="ephemeral_messages">Iznan ur nettdum ara</string>
|
||||
<string name="ephemeral_messages_hint">Ad isnes akk imttekkiyen n udiwenni-a; mazal zemren ad nɣelen, ad ḥerzen, neɣ ad sniflen awelleh n yiznan.</string>
|
||||
@@ -179,6 +181,7 @@
|
||||
<string name="add_stickers_instructions">Akken ad ternuḍ tamenṭaḍt, sit ɣef \" ldi akaram n tmenṭaḍt \", snulfu-d akaram anaddaw i ukemmus-ik·im n tmenṭaḍt, zuɣer tugna akked ifuyla n tmenṭaḍt din</string>
|
||||
<string name="open_sticker_folder">Ldi akaran n tmenṭaḍt</string>
|
||||
<string name="images">Tugniwin</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">Ameslaw</string>
|
||||
<string name="voice_message">Izen n taɣect</string>
|
||||
<string name="forwarded">Yettuwelleh</string>
|
||||
@@ -215,6 +218,7 @@
|
||||
<string name="games">Uraren</string>
|
||||
<string name="tools">Ifecka</string>
|
||||
<string name="app_size">Tiddi</string>
|
||||
<!-- Used as a headline for a date. E.g. in the details of a mini app in the app picker -->
|
||||
<string name="app_date_published">Yeffeɣ-d</string>
|
||||
<string name="add_to_chat">Rnu ɣer udiwenni usrid</string>
|
||||
<!-- short for "Browse through the App Picker/Store/Catalogue"; could also be translated as "Discover" or "Search" -->
|
||||
@@ -379,12 +383,20 @@
|
||||
|
||||
<!-- the action "to call someone", used as a tooltip for the "phone" icon. not: "the call" -->
|
||||
<string name="start_call">Siwel</string>
|
||||
<string name="start_audio_call">Asiwel n umeslaw</string>
|
||||
<string name="start_video_call">Asiwel n tvidyut</string>
|
||||
<!-- the action "to answer" or to "accept" or to "pick up" a call. not: "the answer" -->
|
||||
<string name="answer_call">Err</string>
|
||||
<!-- the action "to decline" a call, not: "the decline" -->
|
||||
<string name="end_call">Agi</string>
|
||||
<!-- deprecated, use outgoing_audio_call or outgoing_video_call instead -->
|
||||
<string name="outgoing_call">Tiɣri tuffiɣt</string>
|
||||
<string name="outgoing_audio_call">Asiwel n umeslaw uffiɣ</string>
|
||||
<string name="outgoing_video_call">Asiwel n uvidyu uffiɣ</string>
|
||||
<!-- deprecated, use incoming_audio_call or incoming_video_call instead -->
|
||||
<string name="incoming_call">Tiɣri i d-ikecmen</string>
|
||||
<string name="incoming_audio_call">Asiwel n umeslaw ukcim</string>
|
||||
<string name="incoming_video_call">Asiwel n uvidyu ukcim</string>
|
||||
<string name="declined_call">Tiɣri tettwagi</string>
|
||||
<string name="canceled_call">Tiɣri tettwasefsex</string>
|
||||
<string name="missed_call">Tiɣri ittwazeglen</string>
|
||||
@@ -715,6 +727,7 @@
|
||||
<string name="pref_your_name">Isem-ik·im</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">Tameddurt</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">Kcem tisura i umazan</string>
|
||||
<string name="pref_enter_sends_explain">Asiti ɣef tanast Kcem ad yazen aḍris n yiznan</string>
|
||||
<string name="pref_outgoing_media_quality">Taɣara n umidya</string>
|
||||
@@ -803,6 +816,7 @@
|
||||
<string name="n_bytes_message">Izen %1$s</string>
|
||||
<!-- %1$s will be replaced by human-readable date and time -->
|
||||
<string name="download_max_available_until">Sader-d afellay i yellan alamma d %1$s</string>
|
||||
<!-- deprecated -->
|
||||
<string name="select_profile">Fren amaɣnu</string>
|
||||
<string name="profile_image_select">Fren tugna n umaɣnu</string>
|
||||
<string name="select_your_new_profile_image">Fren tugna-ik·im tamaynut n umaɣnu</string>
|
||||
@@ -1001,6 +1015,7 @@
|
||||
<string name="secure_join_replies">%1$s yerra-d, rǧu i tmerna-as ɣer ugraw...</string>
|
||||
<string name="secure_join_wait">Asbeddi n tuqqna, ttxil-k·m rǧu...</string>
|
||||
<string name="contact_verified">%1$s ittwasenked.</string>
|
||||
<string name="contact_blocked">Tesweḥleḍ anermis</string>
|
||||
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
|
||||
<string name="verified_by">Yettwasenked sɣur %1$s</string>
|
||||
<string name="verified_by_you">Yettwasenked sɣur nekk</string>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<string name="archive">아카이브</string>
|
||||
<!-- Verb "to unarchive", as in "remove a chat from the archive", opposite of the previous string -->
|
||||
<string name="unarchive">보관 취소</string>
|
||||
<!-- Verb "to mute". used to mute a chat, so that it is silenced e.g. does not make noise or cause notifications -->
|
||||
<string name="mute">음소거</string>
|
||||
<string name="ephemeral_messages">사라지는 메시지</string>
|
||||
<string name="ephemeral_messages_hint">Delta Chat을 사용하는 경우 이 대화의 모든 구성원에게 적용되며, 메시지를 복사, 저장 및 회송하거나 다른 전자우편 클라이언트를 사용할 수 있습니다.</string>
|
||||
@@ -124,6 +125,7 @@
|
||||
<!-- "Stickers" as known from other messengers; in some languages, the English "Sticker" is fine. -->
|
||||
<string name="sticker">스티커</string>
|
||||
<string name="images">이미지</string>
|
||||
<!-- a noun, used for "Music" and other "Audio" files -->
|
||||
<string name="audio">오디오</string>
|
||||
<string name="voice_message">음성 메시지</string>
|
||||
<string name="forwarded">전달됨</string>
|
||||
@@ -456,6 +458,7 @@
|
||||
<string name="pref_your_name">내 이름</string>
|
||||
<!-- Label of the Bio/Signature/Status/Motto field -->
|
||||
<string name="pref_default_status_label">서명 텍스트</string>
|
||||
<!-- Option name for changing behaviour of the "Enter key" to sending out a message directly (instead of adding new line). If in doubt, please refer to a similar option in other messengers. -->
|
||||
<string name="pref_enter_sends">엔터키로 메시지 전송</string>
|
||||
<string name="pref_enter_sends_explain">Enter 키를 누르면 문자 메시지가 전송됩니다.</string>
|
||||
<string name="pref_outgoing_media_quality">발신 미디어 품질</string>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user