mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-04 00:47:00 +01:00
Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a888e0bb28 | ||
|
|
c7fc85e943 | ||
|
|
5bfae0fee1 | ||
|
|
edd62c5f7a | ||
|
|
5c1530b4b9 | ||
|
|
ce324510de | ||
|
|
274bfd0ca2 | ||
|
|
b8cfd30ff3 | ||
|
|
9fa88ff397 | ||
|
|
f105159186 | ||
|
|
a14a63c94c |
No files matched your search
@@ -0,0 +1,121 @@
|
||||
name: Test build
|
||||
|
||||
# On-demand Fedora RPM of any branch, for someone to try a fix before it ships.
|
||||
# Run it from the Actions tab ("Run workflow", pick the branch). Built inside a
|
||||
# Fedora container so the binaries link against Fedora's own GTK, libadwaita and
|
||||
# WebKitGTK, not the Ubuntu ones the release RPM is built against.
|
||||
#
|
||||
# The RPM is unsigned and versioned `<Cargo version>-1.test.<sha>`, so it sorts
|
||||
# below the release it precedes and `dnf` replaces it when that ships.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
fedora:
|
||||
description: 'Fedora release to build on'
|
||||
required: false
|
||||
default: '44'
|
||||
type: string
|
||||
prerelease:
|
||||
description: 'Also publish a pre-release anyone can download without a GitHub login'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: test-build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
rpm:
|
||||
name: Fedora ${{ inputs.fedora }} RPM
|
||||
runs-on: ubuntu-24.04
|
||||
container: fedora:${{ inputs.fedora }}
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
dnf install -y --setopt=install_weak_deps=False \
|
||||
git rpm-build gcc gcc-c++ make gettext curl \
|
||||
pkgconf-pkg-config fuse3-devel gtk4-devel libadwaita-devel \
|
||||
libsecret-devel dbus-devel glib2-devel webkitgtk6.0-devel
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
# Fedora's packaged Rust can trail the workspace's minimum (1.96).
|
||||
- name: Set up Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: '1.96'
|
||||
cache: false
|
||||
|
||||
- name: Cache Cargo target
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
shared-key: fedora-test-build
|
||||
save-if: false
|
||||
|
||||
- name: Build release binaries
|
||||
run: cargo build --release --locked
|
||||
|
||||
- name: Package RPM
|
||||
run: |
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
VERSION=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
|
||||
SHORT=${GITHUB_SHA::7}
|
||||
mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS,BUILDROOT,db}
|
||||
rpmbuild -bb \
|
||||
--nodeps \
|
||||
--define "_topdir $PWD/rpmbuild" \
|
||||
--define "_sourcedir $PWD" \
|
||||
--define "git_dir $PWD" \
|
||||
--define "prebuilt 1" \
|
||||
--define "version ${VERSION}" \
|
||||
--define "dist .test.${SHORT}" \
|
||||
--define "_dbpath $PWD/rpmbuild/db" \
|
||||
packaging/proton-drive-linux.spec
|
||||
mkdir -p out
|
||||
cp rpmbuild/RPMS/x86_64/*.rpm out/
|
||||
# The bare binaries, for trying one without installing anything.
|
||||
tar -czf "out/proton-drive-linux-${VERSION}-${SHORT}-fedora${{ inputs.fedora }}-x86_64.tar.gz" \
|
||||
-C target/release pdfs pdfs-tray pdfs-app pdfs-prompt
|
||||
ls -l out
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: proton-drive-linux-fedora${{ inputs.fedora }}-${{ github.sha }}
|
||||
path: out/*
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
|
||||
prerelease:
|
||||
name: Publish pre-release
|
||||
needs: rpm
|
||||
if: inputs.prerelease
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Download build
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: out
|
||||
merge-multiple: true
|
||||
|
||||
# One rolling pre-release per branch: a new run replaces the last one, so
|
||||
# the link a tester was given keeps pointing at the newest build.
|
||||
- name: Publish
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
run: |
|
||||
TAG="test-$(echo "${GITHUB_REF_NAME}" | tr -c 'A-Za-z0-9._\n' '-')"
|
||||
gh release delete "$TAG" --cleanup-tag --yes 2>/dev/null || true
|
||||
gh release create "$TAG" out/* \
|
||||
--target "$GITHUB_SHA" \
|
||||
--prerelease \
|
||||
--title "Test build of ${GITHUB_REF_NAME} (${GITHUB_SHA::7})" \
|
||||
--notes "Unsigned test build of branch \`${GITHUB_REF_NAME}\` at ${GITHUB_SHA}. Not a release; replaced by the next test build of this branch."
|
||||
Generated
+14
-10
@@ -3474,7 +3474,7 @@ checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4"
|
||||
|
||||
[[package]]
|
||||
name = "pdfs-cli"
|
||||
version = "3.0.0"
|
||||
version = "3.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -3485,13 +3485,15 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pdfs-core"
|
||||
version = "3.0.0"
|
||||
version = "3.1.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.23.1",
|
||||
"dbus-secret-service-keyring-store",
|
||||
"directories",
|
||||
"ignore",
|
||||
@@ -3508,12 +3510,13 @@ dependencies = [
|
||||
"thiserror 2.0.20",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"zeroize",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pdfs-fuse"
|
||||
version = "3.0.0"
|
||||
version = "3.1.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.23.1",
|
||||
@@ -3535,7 +3538,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pdfs-gui"
|
||||
version = "3.0.0"
|
||||
version = "3.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel",
|
||||
@@ -3572,9 +3575,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pgp"
|
||||
version = "0.20.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cfa4743b28656065ff4c0ba09e46b357a65e8c00fc2341e89084b82f87cbdf1"
|
||||
checksum = "ae70f4d9325a391db30d115d6191a7bb67cec856aa0bba131290f0c4e09a532a"
|
||||
dependencies = [
|
||||
"aead 0.5.2",
|
||||
"aes 0.8.4",
|
||||
@@ -3775,9 +3778,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proton-drive-rs"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6ce113d234474821d34787436ee80e1458e3d8a8f97212219615ed315eb70be"
|
||||
checksum = "5bde475139afb5fc2649621e1d283e243f9df2bb412f08802cdf3f4ffaf97c44"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.23.1",
|
||||
@@ -3802,9 +3805,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proton-sdk"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a33c67df9694f90ce60e5b34984275956244138511b4640ca0d100e1dac8b3d"
|
||||
checksum = "faf32d0a03f7d13bd9bdcc8c9503e35e9df9318ca9f2a100dcf06cf50cb7ac8c"
|
||||
dependencies = [
|
||||
"aes-gcm 0.11.1",
|
||||
"async-trait",
|
||||
@@ -3831,6 +3834,7 @@ dependencies = [
|
||||
"thiserror 2.0.20",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+4
-3
@@ -3,7 +3,7 @@ resolver = "2"
|
||||
members = ["crates/pdfs-core", "crates/pdfs-fuse", "crates/pdfs-cli", "crates/pdfs-gui"]
|
||||
|
||||
[workspace.package]
|
||||
version = "3.0.0"
|
||||
version = "3.1.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
authors = ["Nils Pukropp <contact@narl.io>"]
|
||||
@@ -15,8 +15,8 @@ keywords = ["proton", "drive", "fuse", "sync", "linux"]
|
||||
categories = ["filesystem", "command-line-utilities"]
|
||||
|
||||
[workspace.dependencies]
|
||||
proton-sdk = { version = "0.7.2" }
|
||||
proton-drive-rs = { version = "0.7.2" }
|
||||
proton-sdk = { version = "0.8.0" }
|
||||
proton-drive-rs = { version = "0.8.0" }
|
||||
|
||||
# Internal crates.
|
||||
pdfs-core = { path = "crates/pdfs-core" }
|
||||
@@ -26,6 +26,7 @@ tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "fs",
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
base64 = "0.23"
|
||||
zeroize = "1"
|
||||
thiserror = "2"
|
||||
anyhow = "1"
|
||||
# Non-poisoning mutexes. A handler that panics while holding a lock must not
|
||||
|
||||
@@ -23,3 +23,4 @@ tracing-subscriber.workspace = true
|
||||
clap.workspace = true
|
||||
rpassword.workspace = true
|
||||
serde_json.workspace = true
|
||||
zeroize.workspace = true
|
||||
+156
-7
@@ -135,6 +135,24 @@ enum Command {
|
||||
/// Account email; prompted if omitted.
|
||||
#[arg(short, long)]
|
||||
username: Option<String>,
|
||||
/// For a two-password account, keep the mailbox password's unlock in the
|
||||
/// system keyring so the daemon starts without asking after every login.
|
||||
/// Without it the unlock lives in kernel memory for this session only.
|
||||
#[arg(long)]
|
||||
remember: bool,
|
||||
},
|
||||
/// Enter the mailbox password of a two-password account so the daemon can
|
||||
/// unlock your files. Needed once per login session.
|
||||
Unlock {
|
||||
/// Keep the unlock in the system keyring instead of kernel memory only.
|
||||
#[arg(long)]
|
||||
remember: bool,
|
||||
},
|
||||
/// Forget the unlock held in kernel memory; the account is locked again.
|
||||
Lock {
|
||||
/// Also remove an unlock kept in the keyring with `--remember`.
|
||||
#[arg(long)]
|
||||
forget: bool,
|
||||
},
|
||||
/// Forget the stored session.
|
||||
Logout,
|
||||
@@ -803,7 +821,9 @@ fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
JSON_OUTPUT.store(cli.json, std::sync::atomic::Ordering::Relaxed);
|
||||
match cli.command {
|
||||
Command::Login { username } => cmd_login(username),
|
||||
Command::Login { username, remember } => cmd_login(username, remember),
|
||||
Command::Unlock { remember } => cmd_unlock(remember),
|
||||
Command::Lock { forget } => cmd_lock(forget),
|
||||
Command::Logout => cmd_logout(),
|
||||
Command::Status => cmd_status(),
|
||||
Command::Locations => cmd_locations(),
|
||||
@@ -1781,7 +1801,7 @@ fn prompt_line(label: &str) -> Result<String> {
|
||||
Ok(line.trim().to_owned())
|
||||
}
|
||||
|
||||
fn cmd_login(username: Option<String>) -> Result<()> {
|
||||
fn cmd_login(username: Option<String>, remember: bool) -> Result<()> {
|
||||
let username = match username {
|
||||
Some(u) => u,
|
||||
None => prompt_line("Proton email")?,
|
||||
@@ -1793,11 +1813,14 @@ fn cmd_login(username: Option<String>) -> Result<()> {
|
||||
prompt_line("2FA code").map_err(|e| pdfs_core::Error::Other(format!("read 2FA code: {e}")))
|
||||
};
|
||||
|
||||
// Only a two-password account is ever asked for this.
|
||||
let get_mailbox = |attempt: u32| prompt_mailbox(attempt, remember);
|
||||
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
// Solving a CAPTCHA needs a browser engine, which the CLI has no business
|
||||
// carrying. Point at the app that does rather than failing with the raw API
|
||||
// message, which reads as "your login is broken".
|
||||
rt.block_on(auth::login(&username, &password, get_totp))
|
||||
rt.block_on(auth::login(&username, &password, get_totp, get_mailbox))
|
||||
.map_err(|e| match e {
|
||||
pdfs_core::Error::HumanVerificationRequired(_) => anyhow::anyhow!(
|
||||
"Proton is asking for a CAPTCHA before it will accept this sign-in.\n\
|
||||
@@ -1818,9 +1841,88 @@ fn cmd_login(username: Option<String>) -> Result<()> {
|
||||
}
|
||||
|
||||
println!("Logged in as {username}. Session stored in the system keyring.");
|
||||
report_key_state();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ask for the mailbox password of a two-password account, without echo.
|
||||
fn prompt_mailbox(attempt: u32, remember: bool) -> pdfs_core::Result<auth::Mailbox> {
|
||||
if attempt == 0 {
|
||||
eprintln!("This account has a separate mailbox password.");
|
||||
} else {
|
||||
eprintln!("That mailbox password did not unlock the account. Try again.");
|
||||
}
|
||||
let password = rpassword::prompt_password("Mailbox password: ")
|
||||
.map_err(|e| pdfs_core::Error::Other(format!("read mailbox password: {e}")))?;
|
||||
Ok(auth::Mailbox {
|
||||
password: zeroize::Zeroizing::new(password),
|
||||
remember,
|
||||
})
|
||||
}
|
||||
|
||||
/// Say where the account's keys are held, and what that means for the next login.
|
||||
fn report_key_state() {
|
||||
match auth::key_state() {
|
||||
Ok(auth::KeyState::Session) => println!(
|
||||
"Unlocked for this login session only. After you log out or reboot, run `pdfs unlock`."
|
||||
),
|
||||
Ok(auth::KeyState::Locked) => println!("The account is locked. Run `pdfs unlock`."),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_unlock(remember: bool) -> Result<()> {
|
||||
auth::load().context("not logged in (run `pdfs login` first)")?;
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
// Bounded like the login prompt: three wrong answers end the command.
|
||||
let mut attempt = 0;
|
||||
loop {
|
||||
let mailbox = prompt_mailbox(attempt, remember)?;
|
||||
match rt.block_on(auth::unlock(&mailbox.password, remember)) {
|
||||
Ok(()) => break,
|
||||
Err(pdfs_core::Error::WrongMailboxPassword) if attempt < 2 => attempt += 1,
|
||||
Err(e) => return Err(anyhow::Error::new(e).context("unlock failed")),
|
||||
}
|
||||
}
|
||||
// A daemon parked on the locked account would otherwise notice on its next
|
||||
// poll; restarting it makes the mount appear now, as after `pdfs login`.
|
||||
if service::is_active() {
|
||||
service::restart();
|
||||
}
|
||||
println!("Unlocked.");
|
||||
report_key_state();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_lock(forget: bool) -> Result<()> {
|
||||
auth::lock(forget)?;
|
||||
println!(
|
||||
"Locked. {}",
|
||||
if forget {
|
||||
"Unlock removed from memory and keyring."
|
||||
} else {
|
||||
"Run `pdfs unlock` to unlock again."
|
||||
}
|
||||
);
|
||||
// The running daemon keeps its keys until it restarts; say so, since
|
||||
// "locked" would otherwise suggest the mount stopped.
|
||||
if service::is_active() {
|
||||
println!(
|
||||
"The running daemon keeps its keys until it restarts: `systemctl --user restart proton-drive`."
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `stored`, `session` or `locked`: where the account's keys are held.
|
||||
fn key_state_name() -> &'static str {
|
||||
match auth::key_state() {
|
||||
Ok(auth::KeyState::Stored) => "stored",
|
||||
Ok(auth::KeyState::Session) => "session",
|
||||
_ => "locked",
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd_logout() -> Result<()> {
|
||||
auth::logout()?;
|
||||
println!("Stored session cleared.");
|
||||
@@ -1848,6 +1950,7 @@ fn cmd_status() -> Result<()> {
|
||||
"username": session.as_ref().map(|s| s.username.clone()),
|
||||
"user_id": session.as_ref().map(|s| s.user_id.clone()),
|
||||
"scopes": session.as_ref().map(|s| s.scopes.clone()),
|
||||
"keys": session.as_ref().map(|_| key_state_name()),
|
||||
"mount": mount,
|
||||
});
|
||||
println!("{}", serde_json::to_string_pretty(&out)?);
|
||||
@@ -1858,6 +1961,11 @@ fn cmd_status() -> Result<()> {
|
||||
Ok(s) => {
|
||||
println!("Logged in as {} (user {})", s.username, s.user_id);
|
||||
println!("Scopes: {}", s.scopes.join(", "));
|
||||
match key_state_name() {
|
||||
"locked" => println!("Keys: locked — run `pdfs unlock`"),
|
||||
"session" => println!("Keys: unlocked for this login session"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Err(pdfs_core::Error::NotLoggedIn) => {
|
||||
println!("Not logged in. Run `pdfs login`.");
|
||||
@@ -1989,7 +2097,7 @@ fn login_poll_delay(attempts: u32) -> std::time::Duration {
|
||||
std::time::Duration::from_secs(BASE_SECS.saturating_mul(factor).min(MAX_SECS))
|
||||
}
|
||||
|
||||
/// Block until a session is stored, backing off between checks.
|
||||
/// Block until a session is stored and unlocked, backing off between checks.
|
||||
///
|
||||
/// `load` and `sleep` are parameters rather than direct calls so the backoff
|
||||
/// schedule can be tested without a keyring and without real time passing.
|
||||
@@ -2014,6 +2122,16 @@ where
|
||||
sleep(delay);
|
||||
attempts = attempts.saturating_add(1);
|
||||
}
|
||||
Err(pdfs_core::Error::Locked) => {
|
||||
let delay = login_poll_delay(attempts);
|
||||
if attempts == 0 {
|
||||
tracing::info!("account is locked; waiting for `pdfs unlock`…");
|
||||
} else {
|
||||
tracing::debug!(delay_secs = delay.as_secs(), "account still locked");
|
||||
}
|
||||
sleep(delay);
|
||||
attempts = attempts.saturating_add(1);
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
}
|
||||
@@ -2024,10 +2142,13 @@ where
|
||||
/// an external unmount triggers a remount; errors back off and retry. This is
|
||||
/// the entry point for the systemd user service.
|
||||
fn cmd_daemon(mountpoint: Option<PathBuf>) -> Result<()> {
|
||||
// The daemon holds the account's key passphrases in memory; keep them out
|
||||
// of core dumps and away from same-user ptrace.
|
||||
pdfs_core::kernelkey::forbid_dumps();
|
||||
loop {
|
||||
// Wait until a session is stored. The GUI enables this service on login,
|
||||
// but the service may also start at boot before the user has logged in.
|
||||
wait_for_session(|| auth::load().map(|_| ()), std::thread::sleep)?;
|
||||
wait_for_session(auth::ready, pdfs_fuse::idle_sleep)?;
|
||||
|
||||
match mount_once(mountpoint.clone()) {
|
||||
Ok(pdfs_fuse::MountOutcome::Shutdown) => {
|
||||
@@ -2036,13 +2157,13 @@ fn cmd_daemon(mountpoint: Option<PathBuf>) -> Result<()> {
|
||||
}
|
||||
Ok(pdfs_fuse::MountOutcome::Unmounted) => {
|
||||
tracing::warn!("mount ended externally; remounting in 2s");
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
pdfs_fuse::idle_sleep(std::time::Duration::from_secs(2));
|
||||
}
|
||||
Err(e) => {
|
||||
// `{:#}` so the whole anyhow chain lands in the log — the top
|
||||
// context alone ("mount failed") never says *why*.
|
||||
tracing::error!(error = format!("{e:#}"), "mount failed; retrying in 5s");
|
||||
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||
pdfs_fuse::idle_sleep(std::time::Duration::from_secs(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3224,6 +3345,19 @@ fn cmd_diagnose() -> Result<()> {
|
||||
match pdfs_core::auth::load() {
|
||||
Ok(session) => {
|
||||
report.finding(DiagnoseLevel::Ok, " keyring session", session.username);
|
||||
match key_state_name() {
|
||||
"locked" => report.finding(
|
||||
DiagnoseLevel::Fail,
|
||||
" account keys",
|
||||
"locked — run `pdfs unlock` (the daemon waits for it)",
|
||||
),
|
||||
"session" => report.finding(
|
||||
DiagnoseLevel::Ok,
|
||||
" account keys",
|
||||
"unlocked for this login session",
|
||||
),
|
||||
_ => report.finding(DiagnoseLevel::Ok, " account keys", "stored in the keyring"),
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// A locked keyring and an absent login look the same from here, so
|
||||
@@ -3522,6 +3656,21 @@ mod login_wait_tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_locked_account_is_waited_on_until_it_is_unlocked() {
|
||||
let mut checks = vec![
|
||||
Ok(()),
|
||||
Err(pdfs_core::Error::Locked),
|
||||
Err(pdfs_core::Error::NotLoggedIn),
|
||||
Err(pdfs_core::Error::Locked),
|
||||
];
|
||||
let mut slept = 0;
|
||||
|
||||
wait_for_session(|| checks.pop().unwrap(), |_| slept += 1).unwrap();
|
||||
|
||||
assert_eq!(slept, 3, "locked and signed-out are both waited out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_stored_session_is_not_waited_for_at_all() {
|
||||
let mut slept = 0;
|
||||
|
||||
@@ -28,3 +28,5 @@ dbus-secret-service-keyring-store.workspace = true
|
||||
parking_lot.workspace = true
|
||||
async-trait.workspace = true
|
||||
libc.workspace = true
|
||||
zeroize.workspace = true
|
||||
base64.workspace = true
|
||||
+471
-119
@@ -1,22 +1,50 @@
|
||||
//! Login, session persistence, and Drive-client construction.
|
||||
//!
|
||||
//! A successful login is persisted to the OS keyring as a single JSON blob
|
||||
//! holding the resumable session tokens plus the mailbox password (needed to
|
||||
//! rebuild the key chain on resume). The daemon resumes from this blob with no
|
||||
//! interactive step; the refresh token auto-renews via the HTTP client's 401
|
||||
//! path, so no fresh 2FA is required until the refresh token itself expires.
|
||||
//! holding the resumable session tokens, the account's key salts and — unless
|
||||
//! the user chose otherwise — the per-key *passphrases* derived from the
|
||||
//! mailbox password. The password itself is never stored: the passphrases are
|
||||
//! what it exists to produce, and they are enough to rebuild the key chain on
|
||||
//! resume. The daemon resumes from this blob with no interactive step; the
|
||||
//! refresh token auto-renews via the HTTP client's 401 path, so no fresh 2FA is
|
||||
//! required until the refresh token itself expires.
|
||||
//!
|
||||
//! # Two-password accounts
|
||||
//!
|
||||
//! An account with a separate mailbox password exists precisely so that no one
|
||||
//! login holds the means to read the data. Storing that password in the keyring
|
||||
//! would defeat it, so such an account is **locked by default**: its
|
||||
//! passphrases are kept only in the kernel keyring ([`crate::kernelkey`]), for
|
||||
//! the length of the user's session, and `pdfs unlock` (or the app) supplies
|
||||
//! them again after each login. Storing them in the Secret Service as well is
|
||||
//! an explicit opt-in ([`Mailbox::remember`]). Single-password accounts have no
|
||||
//! such separation to protect and are stored, as they always were.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use base64::Engine as _;
|
||||
use base64::engine::general_purpose::STANDARD as BASE64;
|
||||
use keyring_core::Entry;
|
||||
use proton_drive_rs::{KeySalt, ProtonDriveClient};
|
||||
use proton_sdk::account::KeyPassphrases;
|
||||
use proton_sdk::api::{HumanVerification, HumanVerificationCredential};
|
||||
use proton_sdk::cache::EncryptedCacheRepository;
|
||||
use proton_sdk::config::ProtonClientConfiguration;
|
||||
use proton_sdk::error::ProtonError;
|
||||
use proton_sdk::session::{PasswordMode, ProtonApiSession, ResumeParameters};
|
||||
use proton_sdk::telemetry::TracingTelemetry;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
use crate::config::{APP_VERSION, AppDirs, KEYRING_SERVICE, USER_AGENT};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::kernelkey;
|
||||
|
||||
/// How often a wrong mailbox password is asked for again before the login gives up.
|
||||
const MAILBOX_ATTEMPTS: u32 = 3;
|
||||
|
||||
/// Domain-separation label for the key that encrypts the persistent entity cache.
|
||||
const ENTITY_CACHE_PURPOSE: &[u8] = b"pdfs entity cache v1";
|
||||
|
||||
/// Fixed keyring account name for the single stored session blob.
|
||||
const KEYRING_USER: &str = "session";
|
||||
@@ -32,8 +60,11 @@ pub struct StoredSession {
|
||||
pub scopes: Vec<String>,
|
||||
/// `1` = single password, `2` = dual (Proton wire value).
|
||||
pub password_mode: u8,
|
||||
/// Mailbox (data) password — required by `ProtonDriveClient::new` to derive
|
||||
/// the key chain. Lives only in the OS keyring, never on disk in cleartext.
|
||||
/// The mailbox password of a blob written by 3.0.x and earlier.
|
||||
///
|
||||
/// Read only, to migrate: [`resume_client`] derives the passphrases from it
|
||||
/// once and writes the blob back without it. Never serialized again.
|
||||
#[serde(default, skip_serializing)]
|
||||
pub mailbox_password: String,
|
||||
/// The account's key salts, captured at login.
|
||||
///
|
||||
@@ -49,6 +80,11 @@ pub struct StoredSession {
|
||||
/// backfilling) them.
|
||||
#[serde(default)]
|
||||
pub key_salts: Vec<KeySalt>,
|
||||
/// Per-key passphrases (key id → base64), when the user keeps them in the
|
||||
/// keyring: always for a single-password account, by opt-in for a
|
||||
/// two-password one. `None` means they are not stored here.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub key_passphrases: Option<BTreeMap<String, String>>,
|
||||
}
|
||||
|
||||
impl StoredSession {
|
||||
@@ -73,7 +109,10 @@ fn client_config() -> ProtonClientConfiguration {
|
||||
let (app_version, user_agent) = match AppDirs::new() {
|
||||
Ok(dirs) => {
|
||||
let config = dirs.load_config();
|
||||
(config.app_version, config.user_agent)
|
||||
(
|
||||
config.resolved_app_version().to_string(),
|
||||
config.resolved_user_agent().to_string(),
|
||||
)
|
||||
}
|
||||
Err(_) => (APP_VERSION.to_string(), USER_AGENT.to_string()),
|
||||
};
|
||||
@@ -89,6 +128,26 @@ fn keyring_entry() -> Result<Entry> {
|
||||
Ok(Entry::new(KEYRING_SERVICE, KEYRING_USER)?)
|
||||
}
|
||||
|
||||
/// What the user answered when asked for the mailbox password.
|
||||
pub struct Mailbox {
|
||||
pub password: Zeroizing<String>,
|
||||
/// Keep the derived passphrases in the keyring, so the daemon unlocks by
|
||||
/// itself after every login. Off by default: it trades the protection a
|
||||
/// separate mailbox password gives for convenience.
|
||||
pub remember: bool,
|
||||
}
|
||||
|
||||
/// Where the passphrases that unlock this account's keys currently live.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum KeyState {
|
||||
/// In the keyring, available after every login.
|
||||
Stored,
|
||||
/// In kernel memory for this login session only.
|
||||
Session,
|
||||
/// Nowhere: the mailbox password has to be entered (`pdfs unlock`).
|
||||
Locked,
|
||||
}
|
||||
|
||||
/// Run an interactive SRP + (optional) 2FA login and persist the session.
|
||||
///
|
||||
/// `get_totp` is only invoked when the account requires a second factor, so
|
||||
@@ -96,14 +155,19 @@ fn keyring_entry() -> Result<Entry> {
|
||||
/// more than once — [`login_interactive`] re-runs the whole login after human
|
||||
/// verification, and a 2FA account needs a fresh code on that second attempt.
|
||||
///
|
||||
/// `get_mailbox` is only invoked for a two-password account. It receives the
|
||||
/// number of earlier wrong answers (so a prompt can say "try again") and is
|
||||
/// asked at most [`MAILBOX_ATTEMPTS`] times; an `Err` from it aborts the login.
|
||||
///
|
||||
/// A gated login fails with [`Error::HumanVerificationRequired`]; a front-end
|
||||
/// that can present the challenge should use [`login_interactive`] instead.
|
||||
pub async fn login(
|
||||
username: &str,
|
||||
password: &str,
|
||||
get_totp: impl Fn() -> Result<String>,
|
||||
get_mailbox: impl Fn(u32) -> Result<Mailbox>,
|
||||
) -> Result<()> {
|
||||
login_verified(username, password, None, get_totp).await
|
||||
login_verified(username, password, None, get_totp, get_mailbox).await
|
||||
}
|
||||
|
||||
/// [`login`], able to answer a human-verification gate rather than fail on it.
|
||||
@@ -123,12 +187,20 @@ pub async fn login_interactive(
|
||||
username: &str,
|
||||
password: &str,
|
||||
get_totp: impl Fn() -> Result<String>,
|
||||
get_mailbox: impl Fn(u32) -> Result<Mailbox>,
|
||||
get_hv: impl FnOnce(HumanVerification) -> Result<HumanVerificationCredential>,
|
||||
) -> Result<()> {
|
||||
match login_verified(username, password, None, &get_totp).await {
|
||||
match login_verified(username, password, None, &get_totp, &get_mailbox).await {
|
||||
Err(Error::HumanVerificationRequired(hv)) => {
|
||||
let credential = get_hv(*hv)?;
|
||||
login_verified(username, password, Some(&credential), &get_totp).await
|
||||
login_verified(
|
||||
username,
|
||||
password,
|
||||
Some(&credential),
|
||||
&get_totp,
|
||||
&get_mailbox,
|
||||
)
|
||||
.await
|
||||
}
|
||||
other => other,
|
||||
}
|
||||
@@ -145,15 +217,18 @@ pub async fn login_verified(
|
||||
password: &str,
|
||||
verification: Option<&HumanVerificationCredential>,
|
||||
get_totp: impl Fn() -> Result<String>,
|
||||
get_mailbox: impl Fn(u32) -> Result<Mailbox>,
|
||||
) -> Result<()> {
|
||||
let mut session = ProtonApiSession::begin_verified(
|
||||
let password = Zeroizing::new(password.to_owned());
|
||||
let session = ProtonApiSession::begin_verified(
|
||||
client_config(),
|
||||
username,
|
||||
password.as_bytes(),
|
||||
verification,
|
||||
)
|
||||
.await
|
||||
.map_err(classify_verification_gate)?;
|
||||
.map_err(classify_verification_gate);
|
||||
let mut session = session?;
|
||||
|
||||
if session.is_waiting_for_second_factor() {
|
||||
let code = get_totp()?;
|
||||
@@ -163,38 +238,38 @@ pub async fn login_verified(
|
||||
// Grab the key salts while this access token still has the `locked` scope:
|
||||
// after its first refresh it never will again, and without them no later
|
||||
// resume can unlock the key chain. See `StoredSession::key_salts`.
|
||||
let client = ProtonDriveClient::new(&session, password.as_bytes().to_vec());
|
||||
let key_salts = client.account().key_salts().await?;
|
||||
let key_salts = ProtonDriveClient::new(&session, Vec::new())
|
||||
.account()
|
||||
.key_salts()
|
||||
.await?;
|
||||
|
||||
register_refresh_handler(&session, password.to_owned(), key_salts.clone());
|
||||
|
||||
save(&session, password, key_salts).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lift a human-verification gate out of the generic API error into the typed
|
||||
/// variant a front-end can act on.
|
||||
///
|
||||
/// Only a gate that names a solvable method is converted. A `9001` with no
|
||||
/// `Details`, or one offering only `email`/`sms`, stays a plain API error:
|
||||
/// promoting it would send the UI to open a verification page it cannot
|
||||
/// complete, which reads to the user as a hang rather than a refusal.
|
||||
fn classify_verification_gate(e: proton_sdk::error::ProtonError) -> Error {
|
||||
let proton_sdk::error::ProtonError::Api(api) = &e else {
|
||||
return e.into();
|
||||
// A single-password account's mailbox password is the login password. A
|
||||
// two-password one has a second secret the user must type, and it is checked
|
||||
// against the account now — a typo found at login is a retry, found later it
|
||||
// is a daemon that never mounts.
|
||||
let (passphrases, remember) = match session.password_mode() {
|
||||
PasswordMode::Single => (
|
||||
derive_verified(&session, password.as_bytes(), key_salts.clone()).await?,
|
||||
true,
|
||||
),
|
||||
PasswordMode::Dual => {
|
||||
let mut attempt = 0;
|
||||
loop {
|
||||
let mailbox = get_mailbox(attempt)?;
|
||||
match derive_verified(&session, mailbox.password.as_bytes(), key_salts.clone())
|
||||
.await
|
||||
{
|
||||
Ok(passphrases) => break (passphrases, mailbox.remember),
|
||||
Err(Error::WrongMailboxPassword) if attempt + 1 < MAILBOX_ATTEMPTS => {
|
||||
attempt += 1;
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
match api.human_verification() {
|
||||
Some(hv) if hv.supports_captcha() => Error::HumanVerificationRequired(Box::new(hv)),
|
||||
_ => e.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Persist the session's current tokens, mailbox password and key salts.
|
||||
pub async fn save(
|
||||
session: &ProtonApiSession,
|
||||
mailbox_password: &str,
|
||||
key_salts: Vec<KeySalt>,
|
||||
) -> Result<()> {
|
||||
register_refresh_handler(&session);
|
||||
let tokens = session.current_tokens().await;
|
||||
let stored = StoredSession {
|
||||
session_id: session.session_id().as_str().to_owned(),
|
||||
@@ -207,10 +282,103 @@ pub async fn save(
|
||||
PasswordMode::Single => 1,
|
||||
PasswordMode::Dual => 2,
|
||||
},
|
||||
mailbox_password: mailbox_password.to_owned(),
|
||||
mailbox_password: String::new(),
|
||||
key_salts,
|
||||
key_passphrases: None,
|
||||
};
|
||||
let json = serde_json::to_string(&stored)?;
|
||||
keep_passphrases(stored, &passphrases, remember)
|
||||
}
|
||||
|
||||
/// Derive the key passphrases from `mailbox` and prove they unlock the account.
|
||||
///
|
||||
/// [`Error::WrongMailboxPassword`] means the account answered and the password
|
||||
/// is wrong; any other error says nothing about the password (no network, an
|
||||
/// API fault) and must not be reported as a typo.
|
||||
async fn derive_verified(
|
||||
session: &ProtonApiSession,
|
||||
mailbox: &[u8],
|
||||
key_salts: Vec<KeySalt>,
|
||||
) -> Result<KeyPassphrases> {
|
||||
let client = ProtonDriveClient::with_key_salts(session, mailbox.to_vec(), key_salts);
|
||||
client.account().unlock().await.map_err(|e| match e {
|
||||
ProtonError::KeysLocked => Error::WrongMailboxPassword,
|
||||
other => other.into(),
|
||||
})?;
|
||||
Ok(client.account().key_passphrases().await?)
|
||||
}
|
||||
|
||||
/// Write `stored` with the passphrases in the place the user chose: the
|
||||
/// keyring (`remember`) or kernel memory only. Whichever is not chosen is
|
||||
/// cleared, so a revoked choice never leaves a copy behind.
|
||||
///
|
||||
/// The kernel entry is written first. If it cannot be (no keyring support), the
|
||||
/// secret is *not* quietly stored somewhere weaker: the blob is written locked
|
||||
/// and the error says so.
|
||||
fn keep_passphrases(
|
||||
mut stored: StoredSession,
|
||||
passphrases: &KeyPassphrases,
|
||||
remember: bool,
|
||||
) -> Result<()> {
|
||||
let outcome = if remember {
|
||||
stored.key_passphrases = Some(encode(passphrases));
|
||||
// Best-effort: a system without a kernel keyring has nothing to clear.
|
||||
let _ = kernelkey::clear();
|
||||
Ok(())
|
||||
} else {
|
||||
stored.key_passphrases = None;
|
||||
kernelkey::store(&encode_secret(passphrases)).map_err(|e| {
|
||||
Error::Other(format!(
|
||||
"the kernel keyring is unavailable, so the unlock cannot be kept for this session: {e}"
|
||||
))
|
||||
})
|
||||
};
|
||||
write_stored(&stored)?;
|
||||
outcome
|
||||
}
|
||||
|
||||
fn encode(passphrases: &KeyPassphrases) -> BTreeMap<String, String> {
|
||||
passphrases
|
||||
.iter()
|
||||
.map(|(id, secret)| (id.to_owned(), BASE64.encode(secret)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn decode(encoded: &BTreeMap<String, String>) -> Option<KeyPassphrases> {
|
||||
let mut passphrases = KeyPassphrases::new();
|
||||
for (id, secret) in encoded {
|
||||
passphrases.insert(id.clone(), BASE64.decode(secret).ok()?);
|
||||
}
|
||||
(!passphrases.is_empty()).then_some(passphrases)
|
||||
}
|
||||
|
||||
/// The kernel-keyring payload: the same map as the blob's, as JSON.
|
||||
fn encode_secret(passphrases: &KeyPassphrases) -> Zeroizing<Vec<u8>> {
|
||||
Zeroizing::new(serde_json::to_vec(&encode(passphrases)).unwrap_or_default())
|
||||
}
|
||||
|
||||
fn decode_secret(secret: &[u8]) -> Option<KeyPassphrases> {
|
||||
decode(&serde_json::from_slice(secret).ok()?)
|
||||
}
|
||||
|
||||
/// Lift a human-verification gate out of the generic API error into the typed
|
||||
/// variant a front-end can act on.
|
||||
///
|
||||
/// Only a gate that names a solvable method is converted. A `9001` with no
|
||||
/// `Details`, or one offering only `email`/`sms`, stays a plain API error:
|
||||
/// promoting it would send the UI to open a verification page it cannot
|
||||
/// complete, which reads to the user as a hang rather than a refusal.
|
||||
fn classify_verification_gate(e: ProtonError) -> Error {
|
||||
let ProtonError::Api(api) = &e else {
|
||||
return e.into();
|
||||
};
|
||||
match api.human_verification() {
|
||||
Some(hv) if hv.supports_captcha() => Error::HumanVerificationRequired(Box::new(hv)),
|
||||
_ => e.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_stored(stored: &StoredSession) -> Result<()> {
|
||||
let json = Zeroizing::new(serde_json::to_string(stored)?);
|
||||
keyring_entry()?.set_password(&json)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -225,12 +393,93 @@ pub fn load() -> Result<StoredSession> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Where the passphrases for the stored session live right now.
|
||||
///
|
||||
/// Reads the kernel keyring and the stored blob only; never the network.
|
||||
pub fn key_state() -> Result<KeyState> {
|
||||
Ok(key_state_of(&load()?))
|
||||
}
|
||||
|
||||
fn key_state_of(stored: &StoredSession) -> KeyState {
|
||||
match find_passphrases(stored) {
|
||||
Ok(Some((_, origin))) => origin,
|
||||
// A 3.0.x blob still holds its password; `resume_client` migrates it.
|
||||
_ if !stored.mailbox_password.is_empty() => KeyState::Stored,
|
||||
_ => KeyState::Locked,
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the stored session can be resumed without asking the user:
|
||||
/// `Ok` when it can, [`Error::NotLoggedIn`] or [`Error::Locked`] when not.
|
||||
/// What the daemon waits on before it mounts.
|
||||
pub fn ready() -> Result<()> {
|
||||
match key_state_of(&load()?) {
|
||||
KeyState::Locked => Err(Error::Locked),
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// The passphrases the stored session can use without being asked, and which
|
||||
/// of the two places they came from. Prefers the keyring blob: it is what the
|
||||
/// user opted into. A corrupt entry is treated as absent, so it reads as
|
||||
/// locked instead of wedging the daemon.
|
||||
fn find_passphrases(stored: &StoredSession) -> Result<Option<(KeyPassphrases, KeyState)>> {
|
||||
if let Some(found) = stored.key_passphrases.as_ref().and_then(decode) {
|
||||
return Ok(Some((found, KeyState::Stored)));
|
||||
}
|
||||
match kernelkey::load() {
|
||||
Ok(Some(secret)) => Ok(decode_secret(&secret).map(|p| (p, KeyState::Session))),
|
||||
Ok(None) => Ok(None),
|
||||
// No keyring on this system: nothing was ever kept there.
|
||||
Err(e) => {
|
||||
tracing::debug!(error = %e, "kernel keyring not readable; treating the account as locked");
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Supply the mailbox password of a locked account.
|
||||
///
|
||||
/// Verifies it against the account, then keeps the derived passphrases in
|
||||
/// kernel memory for this login session — or, with `remember`, in the keyring.
|
||||
/// A daemon waiting on [`Error::Locked`] picks them up on its next attempt.
|
||||
///
|
||||
/// Fails with [`Error::WrongMailboxPassword`] for a wrong password, which
|
||||
/// changes nothing, and [`Error::ReloginRequired`] for a session that predates
|
||||
/// stored key salts.
|
||||
pub async fn unlock(mailbox: &str, remember: bool) -> Result<()> {
|
||||
let stored = load()?;
|
||||
if stored.key_salts.is_empty() {
|
||||
return Err(Error::ReloginRequired);
|
||||
}
|
||||
let mailbox = Zeroizing::new(mailbox.to_owned());
|
||||
let session = ProtonApiSession::resume(client_config(), stored.to_params())?;
|
||||
register_refresh_handler(&session);
|
||||
let passphrases =
|
||||
derive_verified(&session, mailbox.as_bytes(), stored.key_salts.clone()).await?;
|
||||
keep_passphrases(stored, &passphrases, remember)
|
||||
}
|
||||
|
||||
/// Drop the passphrases held in kernel memory, so the account is locked again
|
||||
/// until [`unlock`]. With `forget`, also those in the keyring blob.
|
||||
pub fn lock(forget: bool) -> Result<()> {
|
||||
kernelkey::clear()?;
|
||||
if forget {
|
||||
let mut stored = load()?;
|
||||
if stored.key_passphrases.take().is_some() {
|
||||
write_stored(&stored)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Forget the persisted session (best-effort; absent entry is not an error).
|
||||
pub fn logout() -> Result<()> {
|
||||
// The persisted entity cache describes the account being logged out of. It
|
||||
// is encrypted under that account's mailbox password, but leaving it behind
|
||||
// would also mean the next account inherits a store it can only ever read as
|
||||
// misses. Best-effort: failing to remove a cache must not block the logout.
|
||||
// is encrypted under a key derived from that account's passphrases, but
|
||||
// leaving it behind would also mean the next account inherits a store it can
|
||||
// only ever read as misses. Best-effort: failing to remove a cache must not
|
||||
// block the logout.
|
||||
if let Ok(dirs) = AppDirs::new() {
|
||||
let path = dirs.state_dir().join("sdk_cache.db");
|
||||
if let Some(cache) = crate::sdkcache::SdkCache::opened()
|
||||
@@ -242,6 +491,9 @@ pub fn logout() -> Result<()> {
|
||||
let _ = std::fs::remove_file(format!("{}{suffix}", path.display()));
|
||||
}
|
||||
}
|
||||
if let Err(e) = kernelkey::clear() {
|
||||
tracing::warn!(error = %e, "clearing the kernel-keyring unlock on logout failed");
|
||||
}
|
||||
match keyring_entry()?.delete_credential() {
|
||||
Ok(()) | Err(keyring_core::Error::NoEntry) => Ok(()),
|
||||
Err(e) => Err(e.into()),
|
||||
@@ -250,44 +502,87 @@ pub fn logout() -> Result<()> {
|
||||
|
||||
/// Resume a persisted session and build an authenticated Drive client.
|
||||
///
|
||||
/// Returns `Error::NotLoggedIn` when no session has been saved. The caller is
|
||||
/// responsible for persisting rotated tokens over the session's lifetime via
|
||||
/// [`persist`] — Proton refresh tokens are single-use, so a refresh that is not
|
||||
/// written back leaves the keyring holding a stale (now-invalid) refresh token,
|
||||
/// and the next resume fails with `InvalidRefreshToken`.
|
||||
/// Returns `Error::NotLoggedIn` when no session has been saved and
|
||||
/// [`Error::Locked`] when the account is waiting for its mailbox password. Tokens
|
||||
/// the session rotates are written back to the keyring as they happen (see
|
||||
/// [`register_refresh_handler`]); Proton refresh tokens are single-use, so a
|
||||
/// refresh that is not written back would leave the keyring holding a stale
|
||||
/// refresh token, and the next resume would fail with `InvalidRefreshToken`.
|
||||
///
|
||||
/// Makes no network call for an account whose passphrases are already known, so
|
||||
/// a daemon starting offline can still mount from its cache.
|
||||
pub async fn resume_client() -> Result<(ProtonDriveClient, ProtonApiSession)> {
|
||||
let stored = load()?;
|
||||
let session = ProtonApiSession::resume(client_config(), stored.to_params())?;
|
||||
let password = stored.mailbox_password.clone();
|
||||
register_refresh_handler(&session);
|
||||
|
||||
// Blobs written before key salts were persisted have none: fetch them once
|
||||
// more and write them back, which only works while the stored access token
|
||||
// still carries the `locked` scope. If it doesn't, the account must be
|
||||
// logged into again — no refresh can restore that scope.
|
||||
let key_salts = if stored.key_salts.is_empty() {
|
||||
register_refresh_handler(&session, password.clone(), Vec::new());
|
||||
let probe = ProtonDriveClient::new(&session, password.clone().into_bytes());
|
||||
let salts = probe.account().key_salts().await.map_err(|e| match &e {
|
||||
proton_sdk::error::ProtonError::Api(api) if api.is_insufficient_scope() => {
|
||||
Error::ReloginRequired
|
||||
}
|
||||
_ => e.into(),
|
||||
})?;
|
||||
save(&session, &password, salts.clone()).await?;
|
||||
salts
|
||||
} else {
|
||||
stored.key_salts
|
||||
let passphrases = match find_passphrases(&stored)? {
|
||||
Some((passphrases, _)) => passphrases,
|
||||
None if !stored.mailbox_password.is_empty() => migrate_legacy(&session, &stored).await?,
|
||||
None => return Err(Error::Locked),
|
||||
};
|
||||
|
||||
register_refresh_handler(&session, password.clone(), key_salts.clone());
|
||||
|
||||
let client = tune(
|
||||
ProtonDriveClient::with_key_salts(&session, password.clone().into_bytes(), key_salts),
|
||||
password.as_bytes(),
|
||||
ProtonDriveClient::with_key_passphrases(&session, passphrases.clone()),
|
||||
&passphrases,
|
||||
);
|
||||
Ok((client, session))
|
||||
}
|
||||
|
||||
/// Turn a blob written by 3.0.x — which holds the mailbox password — into one
|
||||
/// that holds passphrases, so the password stops being stored.
|
||||
///
|
||||
/// The old login saved whatever was typed as the mailbox password, which for a
|
||||
/// two-password account is the *login* password and unlocks nothing. That is
|
||||
/// checked here: a password the account rejects leaves the account locked (and
|
||||
/// the stored copy gone) rather than failing every start forever.
|
||||
async fn migrate_legacy(
|
||||
session: &ProtonApiSession,
|
||||
stored: &StoredSession,
|
||||
) -> Result<KeyPassphrases> {
|
||||
let legacy = Zeroizing::new(stored.mailbox_password.clone());
|
||||
|
||||
// Blobs from before key salts were persisted have none: fetch them once
|
||||
// more, which only works while the stored access token still carries the
|
||||
// `locked` scope. If it doesn't, the account must be logged into again — no
|
||||
// refresh can restore that scope.
|
||||
let key_salts = if stored.key_salts.is_empty() {
|
||||
ProtonDriveClient::new(session, Vec::new())
|
||||
.account()
|
||||
.key_salts()
|
||||
.await
|
||||
.map_err(|e| match &e {
|
||||
ProtonError::Api(api) if api.is_insufficient_scope() => Error::ReloginRequired,
|
||||
_ => e.into(),
|
||||
})?
|
||||
} else {
|
||||
stored.key_salts.clone()
|
||||
};
|
||||
|
||||
let mut migrated = stored.clone();
|
||||
migrated.mailbox_password = String::new();
|
||||
migrated.key_salts = key_salts.clone();
|
||||
|
||||
match derive_verified(session, legacy.as_bytes(), key_salts).await {
|
||||
Ok(passphrases) => {
|
||||
migrated.key_passphrases = Some(encode(&passphrases));
|
||||
write_stored(&migrated)?;
|
||||
tracing::info!(
|
||||
"migrated the stored session from a mailbox password to key passphrases"
|
||||
);
|
||||
Ok(passphrases)
|
||||
}
|
||||
Err(Error::WrongMailboxPassword) => {
|
||||
write_stored(&migrated)?;
|
||||
tracing::warn!(
|
||||
"the stored password does not unlock the account's keys; unlock required"
|
||||
);
|
||||
Err(Error::Locked)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// The client settings every front-end wants, applied wherever a
|
||||
/// [`ProtonDriveClient`] is built for real work.
|
||||
///
|
||||
@@ -301,23 +596,24 @@ pub async fn resume_client() -> Result<(ProtonDriveClient, ProtonApiSession)> {
|
||||
/// failure point per write instead of three.
|
||||
/// - **A persistent entity cache** ([`crate::sdkcache`]), so a restart does not
|
||||
/// re-fetch and re-decrypt the tree the previous run already walked. It is
|
||||
/// wrapped in the SDK's [`EncryptedCacheRepository`] keyed by the mailbox
|
||||
/// password, so the decrypted node names it holds are not readable from the
|
||||
/// file alone — and a password change simply reads as a cold cache, since the
|
||||
/// SDK treats an undecryptable entry as a miss and clears the store.
|
||||
/// wrapped in the SDK's [`EncryptedCacheRepository`] keyed by a secret derived
|
||||
/// from the key passphrases, so the decrypted node names it holds are not
|
||||
/// readable from the file alone — and a password change simply reads as a cold
|
||||
/// cache, since the SDK treats an undecryptable entry as a miss and clears the
|
||||
/// store.
|
||||
///
|
||||
/// Opening it is best-effort: a store this process cannot open costs cache
|
||||
/// hits, not the session, so the client falls back to the SDK's in-memory
|
||||
/// default.
|
||||
fn tune(client: ProtonDriveClient, mailbox_password: &[u8]) -> ProtonDriveClient {
|
||||
fn tune(client: ProtonDriveClient, passphrases: &KeyPassphrases) -> ProtonDriveClient {
|
||||
let client = client
|
||||
.with_telemetry(TracingTelemetry::shared())
|
||||
.with_small_file_upload(true);
|
||||
match AppDirs::new().and_then(|dirs| crate::sdkcache::SdkCache::shared(&dirs)) {
|
||||
Ok(cache) => client.with_entity_repository(EncryptedCacheRepository::shared(
|
||||
cache,
|
||||
mailbox_password.to_vec(),
|
||||
)),
|
||||
Ok(cache) => {
|
||||
let key = passphrases.derive_secret(ENTITY_CACHE_PURPOSE);
|
||||
client.with_entity_repository(EncryptedCacheRepository::shared(cache, key.to_vec()))
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %e, "persistent SDK entity cache unavailable; using memory");
|
||||
client
|
||||
@@ -327,49 +623,105 @@ fn tune(client: ProtonDriveClient, mailbox_password: &[u8]) -> ProtonDriveClient
|
||||
|
||||
/// Write the session's current tokens back to the keyring.
|
||||
///
|
||||
/// The session does not carry the mailbox password (it is only needed to rebuild
|
||||
/// the key chain on resume), so it is re-read from the existing stored blob and
|
||||
/// preserved. Call whenever the session may have rotated its tokens through the
|
||||
/// 401-refresh path so a later [`resume_client`] presents a live refresh token.
|
||||
/// Everything else in the stored blob — salts, passphrases — is preserved, so
|
||||
/// this never undoes an [`unlock`] or [`lock`] made since the session started.
|
||||
/// Call whenever the session may have rotated its tokens so a later
|
||||
/// [`resume_client`] presents a live refresh token.
|
||||
pub async fn persist(session: &ProtonApiSession) -> Result<()> {
|
||||
let stored = load()?;
|
||||
save(session, &stored.mailbox_password, stored.key_salts).await
|
||||
let tokens = session.current_tokens().await;
|
||||
store_tokens(tokens.access_token, tokens.refresh_token)
|
||||
}
|
||||
|
||||
fn register_refresh_handler(
|
||||
session: &ProtonApiSession,
|
||||
mailbox_password: String,
|
||||
key_salts: Vec<KeySalt>,
|
||||
) {
|
||||
let session_id = session.session_id().as_str().to_owned();
|
||||
let username = session.username().to_owned();
|
||||
let user_id = session.user_id().as_str().to_owned();
|
||||
let scopes = session.scopes().to_vec();
|
||||
let password_mode = match session.password_mode() {
|
||||
PasswordMode::Single => 1,
|
||||
PasswordMode::Dual => 2,
|
||||
};
|
||||
fn store_tokens(access_token: String, refresh_token: String) -> Result<()> {
|
||||
let mut stored = load()?;
|
||||
stored.access_token = access_token;
|
||||
stored.refresh_token = refresh_token;
|
||||
write_stored(&stored)
|
||||
}
|
||||
|
||||
/// Persist rotated tokens the moment the session obtains them.
|
||||
///
|
||||
/// The handler re-reads the stored blob instead of capturing one, so it cannot
|
||||
/// write back a stale copy over a later unlock or lock — and cannot resurrect a
|
||||
/// session that was logged out while the daemon still ran.
|
||||
fn register_refresh_handler(session: &ProtonApiSession) {
|
||||
session.http().set_on_tokens_refreshed(move |tokens| {
|
||||
let stored = StoredSession {
|
||||
session_id: session_id.clone(),
|
||||
username: username.clone(),
|
||||
user_id: user_id.clone(),
|
||||
access_token: tokens.access_token,
|
||||
refresh_token: tokens.refresh_token,
|
||||
scopes: scopes.clone(),
|
||||
password_mode,
|
||||
mailbox_password: mailbox_password.clone(),
|
||||
key_salts: key_salts.clone(),
|
||||
};
|
||||
if let Ok(json) = serde_json::to_string(&stored)
|
||||
&& let Ok(entry) = keyring_entry()
|
||||
{
|
||||
if let Err(e) = entry.set_password(&json) {
|
||||
tracing::warn!(error = %e, "failed to auto-persist refreshed tokens in keyring");
|
||||
} else {
|
||||
tracing::info!("successfully auto-persisted refreshed tokens in keyring");
|
||||
match store_tokens(tokens.access_token, tokens.refresh_token) {
|
||||
Ok(()) => tracing::info!("successfully auto-persisted refreshed tokens in keyring"),
|
||||
Err(Error::NotLoggedIn) => {}
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %e, "failed to auto-persist refreshed tokens in keyring")
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn passphrases() -> KeyPassphrases {
|
||||
let mut p = KeyPassphrases::new();
|
||||
p.insert("key-a", b"alpha".to_vec());
|
||||
p.insert("key-b", vec![0, 255, 7]);
|
||||
p
|
||||
}
|
||||
|
||||
fn blob(extra: &str) -> String {
|
||||
format!(
|
||||
r#"{{"session_id":"s","username":"u","user_id":"i","access_token":"a",
|
||||
"refresh_token":"r","scopes":[],"password_mode":2{extra}}}"#
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn passphrases_survive_the_blob_encoding() {
|
||||
let decoded = decode(&encode(&passphrases())).expect("decodes");
|
||||
assert_eq!(decoded, passphrases());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn passphrases_survive_the_kernel_payload_encoding() {
|
||||
let decoded = decode_secret(&encode_secret(&passphrases())).expect("decodes");
|
||||
assert_eq!(decoded, passphrases());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn corrupt_or_empty_secrets_read_as_absent() {
|
||||
assert!(decode_secret(b"not json").is_none());
|
||||
assert!(decode(&BTreeMap::new()).is_none());
|
||||
assert!(decode(&BTreeMap::from([("k".into(), "!!!".into())])).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn legacy_blob_is_read_but_its_password_is_never_written_back() {
|
||||
let stored: StoredSession =
|
||||
serde_json::from_str(&blob(r#","mailbox_password":"hunter2""#)).unwrap();
|
||||
assert_eq!(stored.mailbox_password, "hunter2");
|
||||
assert!(stored.key_passphrases.is_none());
|
||||
|
||||
let written = serde_json::to_string(&stored).unwrap();
|
||||
assert!(!written.contains("hunter2"));
|
||||
assert!(!written.contains("mailbox_password"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn locked_blob_has_no_passphrases_field() {
|
||||
let stored: StoredSession = serde_json::from_str(&blob("")).unwrap();
|
||||
assert!(
|
||||
serde_json::to_string(&stored)
|
||||
.unwrap()
|
||||
.find("key_passphrases")
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stored_passphrases_win_over_the_kernel_keyring() {
|
||||
let mut stored: StoredSession = serde_json::from_str(&blob("")).unwrap();
|
||||
stored.key_passphrases = Some(encode(&passphrases()));
|
||||
let (found, origin) = find_passphrases(&stored).unwrap().unwrap();
|
||||
assert_eq!(origin, KeyState::Stored);
|
||||
assert_eq!(found, passphrases());
|
||||
}
|
||||
}
|
||||
+106
-34
@@ -3,7 +3,7 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use directories::ProjectDirs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::menu::PromptConfig;
|
||||
@@ -12,8 +12,19 @@ use crate::syncignore::DEFAULT_IGNORE_PATTERNS;
|
||||
|
||||
/// Proton requires `external-drive-{name}@{semver}-{channel}` (channel ∈
|
||||
/// stable/beta/alpha); a malformed value trips the 422 anti-abuse path.
|
||||
pub const APP_VERSION: &str = "external-drive-linux@0.1.0-alpha";
|
||||
pub const USER_AGENT: &str = "proton-drive-linux/0.1.0";
|
||||
/// Follows the release so Proton can tell releases apart and retire old ones
|
||||
/// without retiring every one.
|
||||
pub const APP_VERSION: &str = concat!(
|
||||
"external-drive-linux@",
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
"-stable"
|
||||
);
|
||||
pub const USER_AGENT: &str = concat!("proton-drive-linux/", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
/// The fixed identity every release up to 3.1.0 wrote into `config.json`. Read
|
||||
/// back as "unset" so those configs follow the release instead of pinning it.
|
||||
const LEGACY_APP_VERSION: &str = "external-drive-linux@0.1.0-alpha";
|
||||
const LEGACY_USER_AGENT: &str = "proton-drive-linux/0.1.0";
|
||||
|
||||
/// Keyring service name; one entry per credential kind keyed by username.
|
||||
pub const KEYRING_SERVICE: &str = "proton-drive-linux";
|
||||
@@ -76,10 +87,24 @@ fn resolve_sweep_mode(env: Option<&str>, stored: Option<SweepMode>) -> SweepMode
|
||||
}
|
||||
|
||||
/// Configuration structure allowing the user to customize client identification headers.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct AppConfig {
|
||||
pub app_version: String,
|
||||
pub user_agent: String,
|
||||
/// Override for [`APP_VERSION`]. `None` means "use the release's own";
|
||||
/// the old fixed default reads as `None`, so it leaves the file on the
|
||||
/// next save.
|
||||
#[serde(
|
||||
default,
|
||||
deserialize_with = "identity_override",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub app_version: Option<String>,
|
||||
/// Override for [`USER_AGENT`], handled like `app_version`.
|
||||
#[serde(
|
||||
default,
|
||||
deserialize_with = "identity_override",
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub user_agent: Option<String>,
|
||||
/// Soft cap on the on-disk content cache, in bytes (`0` = unlimited).
|
||||
/// `None` means "use [`DEFAULT_CACHE_BUDGET_BYTES`]"; the Settings page
|
||||
/// writes an explicit value here. Defaulted for configs predating the field.
|
||||
@@ -216,31 +241,28 @@ impl FileSort {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
app_version: APP_VERSION.to_string(),
|
||||
user_agent: USER_AGENT.to_string(),
|
||||
cache_budget: None,
|
||||
upload_limit: None,
|
||||
download_limit: None,
|
||||
mountpoint: None,
|
||||
ignore_patterns: None,
|
||||
device_uid: None,
|
||||
conflict_sweep: None,
|
||||
open_with: None,
|
||||
prompt: None,
|
||||
proton_theme: None,
|
||||
files_view: FilesView::default(),
|
||||
tray_hidden: false,
|
||||
language: None,
|
||||
online_map: false,
|
||||
local_first: None,
|
||||
}
|
||||
}
|
||||
/// Reads an `app_version` or `user_agent` override, dropping the fixed
|
||||
/// identity older releases stored as the default.
|
||||
fn identity_override<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> std::result::Result<Option<String>, D::Error> {
|
||||
let value = Option::<String>::deserialize(deserializer)?;
|
||||
Ok(value.filter(|v| v != LEGACY_APP_VERSION && v != LEGACY_USER_AGENT))
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
/// The `x-pm-appversion` sent to Proton: the user's override, or
|
||||
/// [`APP_VERSION`].
|
||||
pub fn resolved_app_version(&self) -> &str {
|
||||
self.app_version.as_deref().unwrap_or(APP_VERSION)
|
||||
}
|
||||
|
||||
/// The `User-Agent` sent to Proton: the user's override, or
|
||||
/// [`USER_AGENT`].
|
||||
pub fn resolved_user_agent(&self) -> &str {
|
||||
self.user_agent.as_deref().unwrap_or(USER_AGENT)
|
||||
}
|
||||
|
||||
/// The effective cache budget in bytes: the user's explicit choice, or
|
||||
/// [`DEFAULT_CACHE_BUDGET_BYTES`] when unset.
|
||||
pub fn resolved_cache_budget(&self) -> u64 {
|
||||
@@ -571,8 +593,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_app_config_serialization() {
|
||||
let config = AppConfig {
|
||||
app_version: "external-drive-test-client@1.0.0".to_string(),
|
||||
user_agent: "test-agent/1.0".to_string(),
|
||||
app_version: Some("external-drive-test-client@1.0.0".to_string()),
|
||||
user_agent: Some("test-agent/1.0".to_string()),
|
||||
cache_budget: Some(1234),
|
||||
upload_limit: Some(500_000),
|
||||
download_limit: None,
|
||||
@@ -596,8 +618,11 @@ mod tests {
|
||||
};
|
||||
let json = serde_json::to_string(&config).unwrap();
|
||||
let decoded: AppConfig = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(decoded.app_version, "external-drive-test-client@1.0.0");
|
||||
assert_eq!(decoded.user_agent, "test-agent/1.0");
|
||||
assert_eq!(
|
||||
decoded.resolved_app_version(),
|
||||
"external-drive-test-client@1.0.0"
|
||||
);
|
||||
assert_eq!(decoded.resolved_user_agent(), "test-agent/1.0");
|
||||
assert_eq!(decoded.proton_theme, Some(true));
|
||||
assert!(decoded.tray_hidden);
|
||||
assert!(decoded.online_map);
|
||||
@@ -628,8 +653,55 @@ mod tests {
|
||||
#[test]
|
||||
fn test_default_app_config() {
|
||||
let default_config = AppConfig::default();
|
||||
assert_eq!(default_config.app_version, APP_VERSION);
|
||||
assert_eq!(default_config.user_agent, USER_AGENT);
|
||||
assert_eq!(default_config.resolved_app_version(), APP_VERSION);
|
||||
assert_eq!(default_config.resolved_user_agent(), USER_AGENT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_client_identity_follows_the_release() {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
assert_eq!(
|
||||
APP_VERSION,
|
||||
format!("external-drive-linux@{version}-stable")
|
||||
);
|
||||
assert_eq!(USER_AGENT, format!("proton-drive-linux/{version}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_old_config_with_the_fixed_identity_follows_the_release() {
|
||||
// Every config written up to 3.1.0 holds these two values, so they must
|
||||
// not pin the identity once Proton retires 0.1.0.
|
||||
let json = format!(
|
||||
r#"{{"app_version":"{LEGACY_APP_VERSION}","user_agent":"{LEGACY_USER_AGENT}","tray_hidden":true}}"#
|
||||
);
|
||||
let decoded: AppConfig = serde_json::from_str(&json).unwrap();
|
||||
assert_eq!(decoded.resolved_app_version(), APP_VERSION);
|
||||
assert_eq!(decoded.resolved_user_agent(), USER_AGENT);
|
||||
assert!(decoded.tray_hidden, "the rest of the config survives");
|
||||
|
||||
let saved = serde_json::to_string(&decoded).unwrap();
|
||||
assert!(!saved.contains("app_version"), "{saved}");
|
||||
assert!(!saved.contains("user_agent"), "{saved}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_hand_set_client_identity_is_kept() {
|
||||
let json = r#"{"app_version":"external-drive-linux@9.9.9-beta","user_agent":"custom/1"}"#;
|
||||
let decoded: AppConfig = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(
|
||||
decoded.resolved_app_version(),
|
||||
"external-drive-linux@9.9.9-beta"
|
||||
);
|
||||
assert_eq!(decoded.resolved_user_agent(), "custom/1");
|
||||
let saved = serde_json::to_string(&decoded).unwrap();
|
||||
assert!(saved.contains("external-drive-linux@9.9.9-beta"), "{saved}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_config_without_a_client_identity_loads() {
|
||||
let decoded: AppConfig = serde_json::from_str("{}").unwrap();
|
||||
assert_eq!(decoded.resolved_app_version(), APP_VERSION);
|
||||
assert_eq!(decoded.resolved_user_agent(), USER_AGENT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -32,6 +32,16 @@ pub enum Error {
|
||||
#[error("saved session can no longer unlock your keys — run `pdfs login` again")]
|
||||
ReloginRequired,
|
||||
|
||||
/// The account has a separate mailbox password that has not been entered
|
||||
/// since login, so its keys cannot be unlocked. The fix is
|
||||
/// [`auth::unlock`](crate::auth::unlock), not a new login.
|
||||
#[error("account is locked — enter the mailbox password with `pdfs unlock`")]
|
||||
Locked,
|
||||
|
||||
/// The mailbox password was checked against the account and is wrong.
|
||||
#[error("that mailbox password does not unlock your account")]
|
||||
WrongMailboxPassword,
|
||||
|
||||
/// The login was gated behind human verification. Not a failure the user can
|
||||
/// fix by retrying: the challenge has to be solved and the login restarted
|
||||
/// with the resulting token (see [`auth::login_verified`](crate::auth::login_verified)).
|
||||
@@ -199,9 +209,11 @@ impl From<serde_json::Error> for CoreError {
|
||||
impl From<Error> for CoreError {
|
||||
fn from(e: Error) -> Self {
|
||||
let kind = match &e {
|
||||
Error::NotLoggedIn | Error::ReloginRequired | Error::HumanVerificationRequired(_) => {
|
||||
ErrorKind::Denied
|
||||
}
|
||||
Error::NotLoggedIn
|
||||
| Error::ReloginRequired
|
||||
| Error::Locked
|
||||
| Error::WrongMailboxPassword
|
||||
| Error::HumanVerificationRequired(_) => ErrorKind::Denied,
|
||||
Error::Proton(proton_sdk::ProtonError::Api(api)) => api_kind(api.code),
|
||||
// A `ProtonError` that never reached the API is a transport failure.
|
||||
Error::Proton(_) => ErrorKind::Offline,
|
||||
|
||||
@@ -0,0 +1,204 @@
|
||||
//! A secret held in the Linux kernel keyring, for as long as the user is logged in.
|
||||
//!
|
||||
//! This is where the key passphrases of a two-password account live by default:
|
||||
//! the mailbox password is never stored, and the secrets derived from it are
|
||||
//! kept in kernel memory — not on disk, not in the Secret Service — and vanish
|
||||
//! when the user's last session ends or the machine reboots. Both the daemon and
|
||||
//! `pdfs unlock` reach the same entry because it hangs off the *user* keyring.
|
||||
//!
|
||||
//! Kernel keys are not paged to swap, are invisible to other users, and are
|
||||
//! wiped by [`clear`] (`KEYCTL_REVOKE`), which makes them a better home than a
|
||||
//! process's heap. Processes of the same user can still read them, exactly as
|
||||
//! they could ptrace the daemon: this protects against disk, backup and other
|
||||
//! users, not against code already running as you.
|
||||
//!
|
||||
//! The keyring may be unavailable (a container, a kernel built without
|
||||
//! `CONFIG_KEYS`); every operation then reports it as an error and the caller
|
||||
//! falls back to asking again, never to storing the secret somewhere weaker.
|
||||
|
||||
use std::io;
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
/// Key description. Namespaced so it cannot collide with another program's key.
|
||||
#[cfg(not(test))]
|
||||
const DESCRIPTION: &[u8] = b"pdfs:key-passphrases\0";
|
||||
/// Tests must never touch a real unlock.
|
||||
#[cfg(test)]
|
||||
const DESCRIPTION: &[u8] = b"pdfs:key-passphrases:test\0";
|
||||
const KEY_TYPE: &[u8] = b"user\0";
|
||||
|
||||
const KEY_SPEC_USER_KEYRING: i32 = -4;
|
||||
const KEYCTL_REVOKE: libc::c_long = 3;
|
||||
const KEYCTL_SETPERM: libc::c_long = 5;
|
||||
const KEYCTL_SEARCH: libc::c_long = 10;
|
||||
const KEYCTL_READ: libc::c_long = 11;
|
||||
|
||||
/// Possessor and owner may view, read, write, search, link and set attributes;
|
||||
/// group and others get nothing.
|
||||
///
|
||||
/// A new key's default grants the owner only *view*, and read access to the
|
||||
/// possessor. A process possesses the user keyring only when its session
|
||||
/// keyring links to it, which a systemd user service or a container does not
|
||||
/// guarantee — so with the default, the daemon could store a key it then
|
||||
/// cannot read back. The owner is the same user that could ptrace the daemon
|
||||
/// anyway, so granting it read access gives up nothing.
|
||||
const PERM_OWNER_AND_POSSESSOR: u32 = 0x3f3f_0000;
|
||||
|
||||
fn last_error<T>() -> io::Result<T> {
|
||||
Err(io::Error::last_os_error())
|
||||
}
|
||||
|
||||
fn find() -> io::Result<Option<libc::c_long>> {
|
||||
// SAFETY: both strings are NUL-terminated and outlive the call.
|
||||
let id = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_keyctl,
|
||||
KEYCTL_SEARCH,
|
||||
KEY_SPEC_USER_KEYRING,
|
||||
KEY_TYPE.as_ptr(),
|
||||
DESCRIPTION.as_ptr(),
|
||||
0,
|
||||
)
|
||||
};
|
||||
if id >= 0 {
|
||||
return Ok(Some(id));
|
||||
}
|
||||
let err = io::Error::last_os_error();
|
||||
match err.raw_os_error() {
|
||||
// ENOKEY: not stored. EKEYREVOKED/EKEYEXPIRED: stored once, now gone.
|
||||
Some(libc::ENOKEY | libc::EKEYREVOKED | libc::EKEYEXPIRED) => Ok(None),
|
||||
_ => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop this process from being core-dumped or ptraced by an unprivileged
|
||||
/// process of the same user, so the secrets in its memory stay out of crash
|
||||
/// reports. Call once at start of a long-lived process that holds them.
|
||||
pub fn forbid_dumps() {
|
||||
// SAFETY: `PR_SET_DUMPABLE` takes plain integers and only affects this process.
|
||||
let rc = unsafe { libc::prctl(libc::PR_SET_DUMPABLE, 0, 0, 0, 0) };
|
||||
if rc != 0 {
|
||||
tracing::warn!(error = %io::Error::last_os_error(), "could not mark the process non-dumpable");
|
||||
}
|
||||
}
|
||||
|
||||
/// Store `secret`, replacing any earlier one.
|
||||
pub fn store(secret: &[u8]) -> io::Result<()> {
|
||||
// SAFETY: strings are NUL-terminated; the payload pointer/length pair
|
||||
// describes `secret`, which outlives the call.
|
||||
let id = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_add_key,
|
||||
KEY_TYPE.as_ptr(),
|
||||
DESCRIPTION.as_ptr(),
|
||||
secret.as_ptr(),
|
||||
secret.len(),
|
||||
KEY_SPEC_USER_KEYRING,
|
||||
)
|
||||
};
|
||||
if id < 0 {
|
||||
return last_error();
|
||||
}
|
||||
// SAFETY: plain integer arguments.
|
||||
let rc = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_keyctl,
|
||||
KEYCTL_SETPERM,
|
||||
id,
|
||||
PERM_OWNER_AND_POSSESSOR,
|
||||
)
|
||||
};
|
||||
if rc < 0 {
|
||||
// A key whose permissions are unknown is not one to leave behind.
|
||||
let err = io::Error::last_os_error();
|
||||
let _ = clear();
|
||||
return Err(err);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read the stored secret, or `None` when there is none.
|
||||
pub fn load() -> io::Result<Option<Zeroizing<Vec<u8>>>> {
|
||||
let Some(id) = find()? else {
|
||||
return Ok(None);
|
||||
};
|
||||
// Size first, then read; retry if the key was replaced in between.
|
||||
for _ in 0..3 {
|
||||
// SAFETY: a null buffer asks the kernel only for the payload length.
|
||||
let len = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_keyctl,
|
||||
KEYCTL_READ,
|
||||
id,
|
||||
std::ptr::null_mut::<u8>(),
|
||||
0usize,
|
||||
)
|
||||
};
|
||||
if len < 0 {
|
||||
return match io::Error::last_os_error().raw_os_error() {
|
||||
Some(libc::ENOKEY | libc::EKEYREVOKED | libc::EKEYEXPIRED) => Ok(None),
|
||||
_ => last_error(),
|
||||
};
|
||||
}
|
||||
let mut buf = Zeroizing::new(vec![0u8; len as usize]);
|
||||
// SAFETY: `buf` is `len` writable bytes.
|
||||
let read = unsafe {
|
||||
libc::syscall(
|
||||
libc::SYS_keyctl,
|
||||
KEYCTL_READ,
|
||||
id,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len(),
|
||||
)
|
||||
};
|
||||
if read < 0 {
|
||||
return last_error();
|
||||
}
|
||||
if read as usize <= buf.len() {
|
||||
buf.truncate(read as usize);
|
||||
return Ok(Some(buf));
|
||||
}
|
||||
}
|
||||
Err(io::Error::other("the key changed while it was being read"))
|
||||
}
|
||||
|
||||
/// Remove the stored secret. Succeeds when there is none.
|
||||
pub fn clear() -> io::Result<()> {
|
||||
let Some(id) = find()? else {
|
||||
return Ok(());
|
||||
};
|
||||
// SAFETY: plain integer arguments.
|
||||
let rc = unsafe { libc::syscall(libc::SYS_keyctl, KEYCTL_REVOKE, id) };
|
||||
if rc < 0 {
|
||||
return match io::Error::last_os_error().raw_os_error() {
|
||||
Some(libc::ENOKEY | libc::EKEYREVOKED) => Ok(()),
|
||||
_ => last_error(),
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// The kernel keyring is process-wide state and a sandbox may not offer it,
|
||||
// so one test covers the whole round trip and skips when it is unavailable.
|
||||
#[test]
|
||||
fn stored_secret_round_trips_and_clears() {
|
||||
if store(b"probe").is_err() {
|
||||
eprintln!("kernel keyring unavailable; skipping");
|
||||
return;
|
||||
}
|
||||
let saved = load().unwrap().expect("stored secret is readable");
|
||||
assert_eq!(saved.as_slice(), b"probe");
|
||||
|
||||
store(b"replaced").unwrap();
|
||||
assert_eq!(load().unwrap().unwrap().as_slice(), b"replaced");
|
||||
|
||||
clear().unwrap();
|
||||
assert!(load().unwrap().is_none());
|
||||
clear().unwrap();
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ pub mod config;
|
||||
pub mod control;
|
||||
pub mod db;
|
||||
pub mod error;
|
||||
pub mod kernelkey;
|
||||
pub mod localindex;
|
||||
pub mod menu;
|
||||
pub mod mounts;
|
||||
|
||||
@@ -123,6 +123,7 @@ use mount::{
|
||||
};
|
||||
use reads::{BlockFlight, BlockRing, PREFETCH_BUDGET, Prefetch, ReaderSlot, STREAM_BYPASS_MIN};
|
||||
use state::{Entry, Intervals, PendingRevision, State, StateGuard, WriteHandle};
|
||||
pub use systemd::idle_sleep;
|
||||
use tracing::{debug, error, info, warn};
|
||||
use transfers::{CountingWriter, JobGuard, OwnedCountingReader, TransferRegistry};
|
||||
use r#virtual::{
|
||||
|
||||
@@ -74,6 +74,26 @@ pub(crate) fn watchdog_ping() {
|
||||
let _ = notify("WATCHDOG=1\n");
|
||||
}
|
||||
|
||||
/// Sleep for `duration`, pinging the watchdog on the way.
|
||||
///
|
||||
/// For the stretches where the daemon is alive but has no mount, and so no
|
||||
/// supervisor: waiting for a login, or backing off after a failed mount. The
|
||||
/// manager arms the watchdog when the process starts, so without these pings a
|
||||
/// daemon that is merely retrying is aborted after `WatchdogSec` and leaves a
|
||||
/// coredump instead of the error it was logging. Never use this while mounted:
|
||||
/// there the ping must prove the control socket answers.
|
||||
pub fn idle_sleep(duration: Duration) {
|
||||
const CHUNK: Duration = Duration::from_secs(10);
|
||||
let mut left = duration;
|
||||
watchdog_ping();
|
||||
while !left.is_zero() {
|
||||
let step = left.min(CHUNK);
|
||||
std::thread::sleep(step);
|
||||
left -= step;
|
||||
watchdog_ping();
|
||||
}
|
||||
}
|
||||
|
||||
/// Tell the manager the daemon is stopping, so a slow teardown is not mistaken
|
||||
/// for a hang by the watchdog it is racing.
|
||||
pub(crate) fn stopping() {
|
||||
|
||||
@@ -119,6 +119,9 @@ struct Ui {
|
||||
/// keyring (a DBus round-trip). Populated at startup and updated only on
|
||||
/// login / logout. `None` = signed out.
|
||||
session: RefCell<Option<auth::StoredSession>>,
|
||||
/// Whether this run already asked for the mailbox password of a locked
|
||||
/// account, so a refresh never re-opens a dialog the user cancelled.
|
||||
unlock_offered: Cell<bool>,
|
||||
/// Whether the last refresh saw a live mount daemon. Gates the unpin buttons
|
||||
/// (which need the daemon to evict + re-hydrate) and every mutating action.
|
||||
mounted: RefCell<bool>,
|
||||
@@ -199,12 +202,20 @@ impl Ui {
|
||||
}
|
||||
|
||||
fn main() -> glib::ExitCode {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()),
|
||||
)
|
||||
.init();
|
||||
let verify = std::env::args().nth(1).as_deref() == Some(VERIFY_ARG);
|
||||
let logs = tracing_subscriber::fmt().with_env_filter(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()),
|
||||
);
|
||||
// The verification window's stdout carries its token back to the app.
|
||||
if verify {
|
||||
logs.with_writer(std::io::stderr).init();
|
||||
} else {
|
||||
logs.init();
|
||||
}
|
||||
i18n::init();
|
||||
if verify {
|
||||
return run_verification_window();
|
||||
}
|
||||
|
||||
// The tray launches the app with arguments ("--page locations",
|
||||
// "--confirm-stop"), which a running instance must receive too.
|
||||
@@ -300,6 +311,11 @@ fn build_window(app: &adw::Application) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
// On a fresh install the daemon has not run yet to make these, and the
|
||||
// Takeout page keeps its staged archives in the state dir (B194).
|
||||
if let Err(e) = dirs.ensure() {
|
||||
tracing::warn!("cannot create the app's directories: {e}");
|
||||
}
|
||||
|
||||
let stack = adw::ViewStack::new();
|
||||
let (login_page, login_widgets) = build_login_page();
|
||||
@@ -362,6 +378,7 @@ fn build_window(app: &adw::Application) {
|
||||
busy: Cell::new(0),
|
||||
opening: RefCell::new(HashSet::new()),
|
||||
session: RefCell::new(auth::load().ok()),
|
||||
unlock_offered: Cell::new(false),
|
||||
mounted: RefCell::new(false),
|
||||
sidebar: sidebar_list.clone(),
|
||||
nav: split.clone(),
|
||||
@@ -1206,7 +1223,7 @@ fn install_window_actions(ui: &Rc<Ui>, window: &adw::ApplicationWindow) {
|
||||
let dialog = adw::AboutDialog::builder()
|
||||
.application_name(gettext("Proton Drive for Linux"))
|
||||
.application_icon("io.narl.proton-drive-linux")
|
||||
.version(pdfs_core::config::APP_VERSION)
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.developer_name("Nils Pukropp")
|
||||
.website("https://proton-drive.narl.io")
|
||||
.issue_url("https://github.com/narrrl/proton-drive-linux/issues")
|
||||
@@ -1346,8 +1363,8 @@ fn debug_info(ui: &Rc<Ui>) -> String {
|
||||
format!(
|
||||
"App version: {}\nUser agent: {}\nlibadwaita: {}.{}.{}\nGTK: {}.{}.{}\n\
|
||||
Mountpoint: {}\nControl socket: {}\nMount service running: {}\n",
|
||||
pdfs_core::config::APP_VERSION,
|
||||
pdfs_core::config::USER_AGENT,
|
||||
config.resolved_app_version(),
|
||||
config.resolved_user_agent(),
|
||||
adw::major_version(),
|
||||
adw::minor_version(),
|
||||
adw::micro_version(),
|
||||
|
||||
@@ -128,7 +128,12 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
|
||||
set_signing_in(&ui, true);
|
||||
ui.login.login_status.set_text(&gettext("Signing in…"));
|
||||
let (rx, totp_req_rx, hv_req_rx) = spawn_login(username, password);
|
||||
let LoginChannels {
|
||||
result: rx,
|
||||
totp: totp_req_rx,
|
||||
hv: hv_req_rx,
|
||||
mailbox: mailbox_req_rx,
|
||||
} = spawn_login(username, password);
|
||||
|
||||
// Surface the 2FA dialog only if the SDK actually asks for a code (i.e.
|
||||
// the account has 2FA enabled). The worker blocks until the dialog feeds
|
||||
@@ -145,15 +150,42 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
});
|
||||
|
||||
// Same shape for human verification: only fires when the API gates the
|
||||
// sign-in, and the worker is blocked on the token until it does.
|
||||
// sign-in, and the worker is blocked on the token until it does. A
|
||||
// window that never came up is told apart from one the user closed, so
|
||||
// the result below can say why the sign-in stopped.
|
||||
let ui_hv = ui.clone();
|
||||
let verification_failed = Rc::new(Cell::new(false));
|
||||
let hv_failed = verification_failed.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
if let Ok((url, token_tx)) = hv_req_rx.recv().await {
|
||||
ui_hv
|
||||
.login
|
||||
.login_status
|
||||
.set_text(&gettext("Complete the verification to continue…"));
|
||||
prompt_human_verification(&ui_hv, &url, token_tx);
|
||||
// Anything but a token drops the sender, which the worker reads
|
||||
// as a cancelled sign-in.
|
||||
match verify_human(url).await {
|
||||
Verification::Solved(token) => {
|
||||
let _ = token_tx.send(token);
|
||||
}
|
||||
Verification::Cancelled => {}
|
||||
Verification::Failed => hv_failed.set(true),
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// And for the mailbox password, which only a two-password account has.
|
||||
// The worker asks again after a wrong answer, so this loops too.
|
||||
let ui_mailbox = ui.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
while let Ok((attempt, answer_tx)) = mailbox_req_rx.recv().await {
|
||||
ask_mailbox(&ui_mailbox, attempt > 0, move |answer| {
|
||||
// A cancelled dialog drops the sender, which the worker
|
||||
// reads as a cancelled login.
|
||||
if let Some(answer) = answer {
|
||||
let _ = answer_tx.send(answer);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -174,6 +206,9 @@ pub(crate) fn wire_login(ui: &Rc<Ui>) {
|
||||
let _ = gio::spawn_blocking(service::enable_start).await;
|
||||
refresh(&ui);
|
||||
}
|
||||
Err(_) if verification_failed.get() => ui.login.login_status.set_text(&gettext(
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your system may keep the web view's sandbox from starting; the troubleshooting guide explains what to do.",
|
||||
)),
|
||||
Err(e) => ui.login.login_status.set_text(&e),
|
||||
}
|
||||
});
|
||||
@@ -209,6 +244,12 @@ pub(crate) fn login_error_message(error: &pdfs_core::Error) -> String {
|
||||
pdfs_core::Error::Other(message) if message.contains("two-factor") => {
|
||||
gettext("Sign-in cancelled: no two-factor code was entered.")
|
||||
}
|
||||
pdfs_core::Error::Other(message) if message.contains("mailbox") => {
|
||||
gettext("Sign-in cancelled: no mailbox password was entered.")
|
||||
}
|
||||
pdfs_core::Error::WrongMailboxPassword => {
|
||||
gettext("That mailbox password didn't unlock your account.")
|
||||
}
|
||||
pdfs_core::Error::Other(message) if message.contains("verification") => gettext(
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a new one.",
|
||||
),
|
||||
@@ -220,26 +261,31 @@ pub(crate) fn login_error_message(error: &pdfs_core::Error) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// What the login worker asks the UI for, and how it reports back.
|
||||
pub(crate) struct LoginChannels {
|
||||
/// The final outcome, once.
|
||||
pub(crate) result: async_channel::Receiver<Result<(), String>>,
|
||||
/// Fires only if the account needs a 2FA code; carries the sender for it.
|
||||
pub(crate) totp: async_channel::Receiver<std::sync::mpsc::Sender<String>>,
|
||||
/// Fires only if the sign-in is gated: the page to show, and the sender for
|
||||
/// the token the user earns on it.
|
||||
pub(crate) hv: async_channel::Receiver<(String, std::sync::mpsc::Sender<String>)>,
|
||||
/// Fires only for a two-password account: how many answers were already
|
||||
/// wrong, and the sender for the password and the "remember" choice.
|
||||
pub(crate) mailbox: async_channel::Receiver<(u32, std::sync::mpsc::Sender<(String, bool)>)>,
|
||||
}
|
||||
|
||||
/// Run the async SRP + optional 2FA login on a dedicated current-thread Tokio
|
||||
/// runtime. Returns two channels: the first yields the final login result once;
|
||||
/// the second fires *only if* the account needs a 2FA code, carrying a
|
||||
/// [`std::sync::mpsc::Sender`] the UI uses to feed the code back. The login
|
||||
/// closure blocks the worker on that sender until the dialog answers, so the
|
||||
/// code is requested lazily and can't expire before the password proof.
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) fn spawn_login(
|
||||
username: String,
|
||||
password: String,
|
||||
) -> (
|
||||
async_channel::Receiver<Result<(), String>>,
|
||||
async_channel::Receiver<std::sync::mpsc::Sender<String>>,
|
||||
async_channel::Receiver<(String, std::sync::mpsc::Sender<String>)>,
|
||||
) {
|
||||
/// runtime. The returned [`LoginChannels`] carry the final result and the lazy
|
||||
/// prompts. Each login closure blocks the worker on a sender the UI answers, so
|
||||
/// a code is requested lazily and can't expire before the password proof.
|
||||
pub(crate) fn spawn_login(username: String, password: String) -> LoginChannels {
|
||||
let (tx, rx) = async_channel::bounded(1);
|
||||
// Two, not one: a CAPTCHA-gated login restarts, so a 2FA account is asked
|
||||
// for a code on each attempt and a single slot would deadlock the worker.
|
||||
let (totp_req_tx, totp_req_rx) = async_channel::bounded(2);
|
||||
let (hv_req_tx, hv_req_rx) = async_channel::bounded(1);
|
||||
let (mailbox_req_tx, mailbox_req_rx) = async_channel::bounded(1);
|
||||
std::thread::spawn(move || {
|
||||
let rt = match tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -267,6 +313,19 @@ pub(crate) fn spawn_login(
|
||||
.recv()
|
||||
.map_err(|_| pdfs_core::Error::Other("two-factor entry cancelled".into()))
|
||||
},
|
||||
|attempt| {
|
||||
let (answer_tx, answer_rx) = std::sync::mpsc::channel::<(String, bool)>();
|
||||
mailbox_req_tx
|
||||
.send_blocking((attempt, answer_tx))
|
||||
.map_err(|_| pdfs_core::Error::Other("mailbox prompt closed".into()))?;
|
||||
let (password, remember) = answer_rx
|
||||
.recv()
|
||||
.map_err(|_| pdfs_core::Error::Other("mailbox entry cancelled".into()))?;
|
||||
Ok(auth::Mailbox {
|
||||
password: password.into(),
|
||||
remember,
|
||||
})
|
||||
},
|
||||
|hv| {
|
||||
// Gated: hand the UI the page to show, block on the token the
|
||||
// user earns by solving it.
|
||||
@@ -287,7 +346,143 @@ pub(crate) fn spawn_login(
|
||||
});
|
||||
let _ = tx.send_blocking(result);
|
||||
});
|
||||
(rx, totp_req_rx, hv_req_rx)
|
||||
LoginChannels {
|
||||
result: rx,
|
||||
totp: totp_req_rx,
|
||||
hv: hv_req_rx,
|
||||
mailbox: mailbox_req_rx,
|
||||
}
|
||||
}
|
||||
|
||||
/// Ask for the mailbox password of a two-password account.
|
||||
///
|
||||
/// `done` gets the password and the "keep unlocked" choice, or `None` when the
|
||||
/// dialog was cancelled. `retry` says the last answer was wrong. The choice
|
||||
/// defaults to off: storing the mailbox unlock in the keyring trades away what
|
||||
/// a separate mailbox password is for, so it is something to opt into.
|
||||
pub(crate) fn ask_mailbox(
|
||||
ui: &Rc<Ui>,
|
||||
retry: bool,
|
||||
done: impl FnOnce(Option<(String, bool)>) + 'static,
|
||||
) {
|
||||
let body = if retry {
|
||||
gettext("That mailbox password didn't unlock your account. Try again.")
|
||||
} else {
|
||||
gettext("This account has a separate mailbox password. Enter it to unlock your files.")
|
||||
};
|
||||
let dialog = adw::AlertDialog::builder()
|
||||
.heading(gettext("Mailbox Password"))
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
let group = adw::PreferencesGroup::new();
|
||||
let entry = adw::PasswordEntryRow::builder()
|
||||
.title(gettext("Mailbox password"))
|
||||
.activates_default(true)
|
||||
.build();
|
||||
let remember = adw::SwitchRow::builder()
|
||||
.title(gettext("Keep unlocked on this computer"))
|
||||
.subtitle(gettext(
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without asking after every login. Otherwise you enter the password once per session.",
|
||||
))
|
||||
.build();
|
||||
group.add(&entry);
|
||||
group.add(&remember);
|
||||
dialog.set_extra_child(Some(&group));
|
||||
|
||||
dialog.add_response("cancel", &gettext("Cancel"));
|
||||
dialog.add_response("unlock", &gettext("Unlock"));
|
||||
dialog.set_response_appearance("unlock", adw::ResponseAppearance::Suggested);
|
||||
dialog.set_default_response(Some("unlock"));
|
||||
dialog.set_close_response("cancel");
|
||||
|
||||
let done = RefCell::new(Some(done));
|
||||
dialog.connect_response(None, move |_, resp| {
|
||||
let Some(done) = done.borrow_mut().take() else {
|
||||
return;
|
||||
};
|
||||
let password = entry.text().to_string();
|
||||
if resp == "unlock" && !password.is_empty() {
|
||||
done(Some((password, remember.is_active())));
|
||||
} else {
|
||||
done(None);
|
||||
}
|
||||
});
|
||||
|
||||
let parent = ui_window(ui).map(|w| w.upcast::<gtk4::Window>());
|
||||
dialog.present(parent.as_ref());
|
||||
}
|
||||
|
||||
/// If the signed-in account is locked, ask for its mailbox password — once per
|
||||
/// run; after a cancel, a toast keeps an Unlock button within reach.
|
||||
///
|
||||
/// The key state is a keyring and kernel-keyring read, so it runs on a worker.
|
||||
pub(crate) fn offer_unlock(ui: &Rc<Ui>) {
|
||||
if ui.unlock_offered.get() {
|
||||
return;
|
||||
}
|
||||
let ui = ui.clone();
|
||||
glib::spawn_future_local(async move {
|
||||
let state = gio::spawn_blocking(|| auth::key_state().ok()).await;
|
||||
if matches!(state, Ok(Some(auth::KeyState::Locked))) && !ui.unlock_offered.replace(true) {
|
||||
prompt_unlock(&ui, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enum UnlockOutcome {
|
||||
Unlocked,
|
||||
Wrong,
|
||||
Failed(String),
|
||||
}
|
||||
|
||||
/// Ask for the mailbox password and unlock the account with it.
|
||||
fn prompt_unlock(ui: &Rc<Ui>, retry: bool) {
|
||||
let ui_done = ui.clone();
|
||||
ask_mailbox(ui, retry, move |answer| {
|
||||
let Some((password, remember)) = answer else {
|
||||
toast_action(
|
||||
&ui_done,
|
||||
&gettext("Proton Drive is locked. Enter your mailbox password to unlock it."),
|
||||
&gettext("Unlock"),
|
||||
|ui| prompt_unlock(ui, false),
|
||||
);
|
||||
return;
|
||||
};
|
||||
glib::spawn_future_local(async move {
|
||||
// Verifying talks to Proton and the restart talks to systemd, so
|
||||
// both run on a worker, never on the main loop.
|
||||
let outcome = gio::spawn_blocking(move || {
|
||||
let rt = match tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
{
|
||||
Ok(rt) => rt,
|
||||
Err(e) => return UnlockOutcome::Failed(e.to_string()),
|
||||
};
|
||||
match rt.block_on(auth::unlock(&password, remember)) {
|
||||
Ok(()) => {
|
||||
service::restart();
|
||||
UnlockOutcome::Unlocked
|
||||
}
|
||||
Err(pdfs_core::Error::WrongMailboxPassword) => UnlockOutcome::Wrong,
|
||||
Err(e) => UnlockOutcome::Failed(login_error_message(&e)),
|
||||
}
|
||||
})
|
||||
.await;
|
||||
match outcome {
|
||||
Ok(UnlockOutcome::Unlocked) => {
|
||||
toast(&ui_done, &gettext("Unlocked."));
|
||||
refresh(&ui_done);
|
||||
}
|
||||
Ok(UnlockOutcome::Wrong) => prompt_unlock(&ui_done, true),
|
||||
Ok(UnlockOutcome::Failed(message)) => {
|
||||
toast_error(&ui_done, &gettext("Couldn't unlock"), &message)
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/// Show the lazy two-factor dialog and feed the entered code back to the waiting
|
||||
@@ -374,6 +569,12 @@ mod tests {
|
||||
assert!(login_error_message(&hv).contains("verification wasn't completed"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_cancelled_mailbox_prompt_is_reported_as_such() {
|
||||
let error = pdfs_core::Error::Other("mailbox entry cancelled".into());
|
||||
assert!(login_error_message(&error).contains("no mailbox password"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unmapped_error_keeps_its_text() {
|
||||
let error = pdfs_core::Error::Other("something odd".into());
|
||||
|
||||
@@ -860,6 +860,7 @@ pub(crate) fn refresh(ui: &Rc<Ui>) {
|
||||
}
|
||||
}
|
||||
|
||||
offer_unlock(ui);
|
||||
refresh_status(ui);
|
||||
refresh_transfers(ui);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! The human-verification (CAPTCHA) dialog.
|
||||
//! The human-verification (CAPTCHA) window.
|
||||
//!
|
||||
//! Proton gates logins it does not recognise — a new IP, a VPN exit — behind a
|
||||
//! CAPTCHA. The API answers the login with a challenge instead of a session, and
|
||||
@@ -8,10 +8,26 @@
|
||||
//! The page is hosted in a `WebKitWebView` rather than handed to the system
|
||||
//! browser because it reports completion by posting a message to its host, not
|
||||
//! by redirecting: a browser has nowhere to post it back to.
|
||||
//!
|
||||
//! The webview runs in a child `pdfs-app` started with [`VERIFY_ARG`], not in the
|
||||
//! app itself. WebKit aborts its whole process when its sandbox cannot start, as
|
||||
//! on hardened systems that keep bubblewrap from the journal socket
|
||||
//! (`docs/BUGS.md` B195); in a child that costs the verification, not the app.
|
||||
//! The URL goes to the child on stdin, so it never shows in a process list, and
|
||||
//! the token comes back on stdout.
|
||||
|
||||
use crate::*;
|
||||
use std::io::{BufRead, BufReader, Write as _};
|
||||
use std::process::{ExitStatus, Stdio};
|
||||
use webkit6::prelude::*;
|
||||
|
||||
/// The argument that makes `pdfs-app` the verification window instead of the app.
|
||||
pub(crate) const VERIFY_ARG: &str = "--human-verification";
|
||||
|
||||
/// Marks the token among whatever else lands on the child's stdout: GLib and
|
||||
/// WebKit write debug output there.
|
||||
const TOKEN_PREFIX: &str = "hv-token ";
|
||||
|
||||
/// Bridge the verification page's `postMessage` to a handler this side can read.
|
||||
///
|
||||
/// The page targets its embedding host (`window.parent`), which in a webview is
|
||||
@@ -26,15 +42,100 @@ window.addEventListener('message', function (event) {
|
||||
});
|
||||
"#;
|
||||
|
||||
/// Present the challenge and hand the solved token back through `token_tx`.
|
||||
///
|
||||
/// Closing the dialog without solving drops the sender, which the waiting login
|
||||
/// worker reads as a cancelled sign-in — the same contract as the 2FA prompt.
|
||||
pub(crate) fn prompt_human_verification(
|
||||
ui: &Rc<Ui>,
|
||||
url: &str,
|
||||
token_tx: std::sync::mpsc::Sender<String>,
|
||||
) {
|
||||
/// How the verification window ended.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(crate) enum Verification {
|
||||
Solved(String),
|
||||
/// Closed without solving.
|
||||
Cancelled,
|
||||
/// Never came up, or died: most likely WebKit could not start its sandbox.
|
||||
Failed,
|
||||
}
|
||||
|
||||
/// Show the challenge in the verification window and wait until it closes.
|
||||
pub(crate) async fn verify_human(url: String) -> Verification {
|
||||
match gio::spawn_blocking(move || run_verification_child(&url)).await {
|
||||
Ok(Ok(verification)) => verification,
|
||||
Ok(Err(e)) => {
|
||||
tracing::error!("cannot run the verification window: {e}");
|
||||
Verification::Failed
|
||||
}
|
||||
Err(_) => Verification::Failed,
|
||||
}
|
||||
}
|
||||
|
||||
fn run_verification_child(url: &str) -> std::io::Result<Verification> {
|
||||
let mut child = Command::new(own_exe())
|
||||
.arg(VERIFY_ARG)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
// A failed write means the child is already gone; its exit status says
|
||||
// how. Dropping `stdin` closes it.
|
||||
let _ = writeln!(stdin, "{url}");
|
||||
}
|
||||
// Stops reading at the token rather than at EOF: WebKit's helper processes
|
||||
// inherit the pipe and may hold it open a moment after the child quits.
|
||||
let token = child
|
||||
.stdout
|
||||
.take()
|
||||
.and_then(|out| find_token(BufReader::new(out)));
|
||||
let status = child.wait()?;
|
||||
Ok(outcome(token, status))
|
||||
}
|
||||
|
||||
/// This very binary, so a development build opens its own window. After an
|
||||
/// upgrade replaced the file, `current_exe` names a deleted path, and the
|
||||
/// installed `pdfs-app` is the next best.
|
||||
fn own_exe() -> PathBuf {
|
||||
std::env::current_exe()
|
||||
.ok()
|
||||
.filter(|path| path.is_file())
|
||||
.unwrap_or_else(|| PathBuf::from("pdfs-app"))
|
||||
}
|
||||
|
||||
fn find_token(out: impl BufRead) -> Option<String> {
|
||||
out.lines()
|
||||
.map_while(Result::ok)
|
||||
.find_map(|line| line.strip_prefix(TOKEN_PREFIX).map(str::to_owned))
|
||||
}
|
||||
|
||||
/// A token wins over the exit status: the user solved the page, even if
|
||||
/// WebKit's teardown crashed after it.
|
||||
fn outcome(token: Option<String>, status: ExitStatus) -> Verification {
|
||||
match token {
|
||||
Some(token) => Verification::Solved(token),
|
||||
None if status.success() => Verification::Cancelled,
|
||||
None => {
|
||||
tracing::error!(%status, "the verification window failed");
|
||||
Verification::Failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Run as the verification window: read the page's URL from stdin, show it, and
|
||||
/// print the token once the user has solved it. Closing the window exits
|
||||
/// without a token, which the app reads as a cancelled sign-in.
|
||||
pub(crate) fn run_verification_window() -> glib::ExitCode {
|
||||
let mut url = String::new();
|
||||
if std::io::stdin().lock().read_line(&mut url).is_err() || url.trim().is_empty() {
|
||||
tracing::error!("{VERIFY_ARG} expects the verification URL on stdin");
|
||||
return glib::ExitCode::FAILURE;
|
||||
}
|
||||
let url = url.trim().to_owned();
|
||||
|
||||
// Not unique: the app that started it already holds APP_ID.
|
||||
let app = adw::Application::builder()
|
||||
.flags(gio::ApplicationFlags::NON_UNIQUE)
|
||||
.build();
|
||||
app.connect_activate(move |app| build_verification_window(app, &url));
|
||||
// GApplication would refuse VERIFY_ARG as an unknown option.
|
||||
let argv0 = std::env::args().next().unwrap_or_default();
|
||||
app.run_with_args(&[argv0])
|
||||
}
|
||||
|
||||
fn build_verification_window(app: &adw::Application, url: &str) {
|
||||
let content = webkit6::UserContentManager::new();
|
||||
content.add_script(&webkit6::UserScript::new(
|
||||
BRIDGE,
|
||||
@@ -53,24 +154,19 @@ pub(crate) fn prompt_human_verification(
|
||||
.hexpand(true)
|
||||
.build();
|
||||
|
||||
let dialog = adw::Dialog::builder()
|
||||
let body = gtk4::Box::new(gtk4::Orientation::Vertical, 0);
|
||||
body.append(&adw::HeaderBar::new());
|
||||
body.append(&webview);
|
||||
let window = adw::ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title(gettext("Verification"))
|
||||
.content_width(420)
|
||||
.content_height(560)
|
||||
.icon_name(APP_ID)
|
||||
.default_width(420)
|
||||
.default_height(560)
|
||||
.content(&body)
|
||||
.build();
|
||||
|
||||
let header = adw::HeaderBar::new();
|
||||
let body = gtk4::Box::new(gtk4::Orientation::Vertical, 0);
|
||||
body.append(&header);
|
||||
body.append(&webview);
|
||||
dialog.set_child(Some(&body));
|
||||
|
||||
// Taken on the first success *or* on close, so the token is sent at most
|
||||
// once and a cancelled dialog always drops the sender.
|
||||
let token_tx = Rc::new(RefCell::new(Some(token_tx)));
|
||||
|
||||
let tx = token_tx.clone();
|
||||
let dlg_weak = dialog.downgrade();
|
||||
let app = app.downgrade();
|
||||
content.connect_script_message_received(Some("hv"), move |_, value| {
|
||||
let Some(token) = extract_token(&value.to_str()) else {
|
||||
// Every `postMessage` on the page reaches here, most of them the
|
||||
@@ -78,25 +174,17 @@ pub(crate) fn prompt_human_verification(
|
||||
// is simply not ours.
|
||||
return;
|
||||
};
|
||||
if let Some(tx) = tx.borrow_mut().take() {
|
||||
let _ = tx.send(token);
|
||||
let mut stdout = std::io::stdout().lock();
|
||||
if let Err(e) = writeln!(stdout, "{TOKEN_PREFIX}{token}").and_then(|()| stdout.flush()) {
|
||||
tracing::error!("cannot hand the verification token back: {e}");
|
||||
}
|
||||
if let Some(dlg) = dlg_weak.upgrade() {
|
||||
dlg.close();
|
||||
if let Some(app) = app.upgrade() {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
// Covers the close button, Escape, and the user giving up.
|
||||
dialog.connect_closed(move |_| {
|
||||
token_tx.borrow_mut().take();
|
||||
});
|
||||
|
||||
webview.load_uri(url);
|
||||
|
||||
let parent = ui.login.login_button.root().and_downcast::<gtk4::Window>();
|
||||
// Returns immediately; the login worker stays blocked on the channel until
|
||||
// the handler above sends, or the dialog closes and drops the sender.
|
||||
dialog.present(parent.as_ref());
|
||||
window.present();
|
||||
}
|
||||
|
||||
/// Pull the verification token out of a message posted by the verification page.
|
||||
@@ -133,7 +221,12 @@ fn extract_token(raw: &str) -> Option<String> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::extract_token;
|
||||
use super::{Verification, extract_token, find_token, outcome};
|
||||
use std::os::unix::process::ExitStatusExt as _;
|
||||
use std::process::ExitStatus;
|
||||
|
||||
/// The wait status of a process killed by SIGABRT.
|
||||
const ABORTED: i32 = 6;
|
||||
|
||||
#[test]
|
||||
fn a_completion_message_yields_its_token() {
|
||||
@@ -163,4 +256,39 @@ mod tests {
|
||||
assert!(extract_token(raw).is_none(), "accepted: {raw}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_token_is_found_among_other_output() {
|
||||
let out = "Gtk-Message: something\nhv-token tok-1\nmore\n";
|
||||
assert_eq!(find_token(out.as_bytes()).as_deref(), Some("tok-1"));
|
||||
assert_eq!(find_token("only chatter\n".as_bytes()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_window_closed_without_a_token_cancels() {
|
||||
assert_eq!(
|
||||
outcome(None, ExitStatus::from_raw(0)),
|
||||
Verification::Cancelled
|
||||
);
|
||||
}
|
||||
|
||||
/// WebKit aborts when its sandbox cannot start (B195). That must read as a
|
||||
/// failure the app explains, not as the user giving up.
|
||||
#[test]
|
||||
fn a_window_that_died_fails() {
|
||||
assert_eq!(
|
||||
outcome(None, ExitStatus::from_raw(ABORTED)),
|
||||
Verification::Failed
|
||||
);
|
||||
let exited_1 = ExitStatus::from_raw(1 << 8);
|
||||
assert_eq!(outcome(None, exited_1), Verification::Failed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_token_counts_even_if_the_window_died_after_it() {
|
||||
assert_eq!(
|
||||
outcome(Some("tok-1".into()), ExitStatus::from_raw(ABORTED)),
|
||||
Verification::Solved("tok-1".into())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -166,6 +166,15 @@ fn poll_state(socket: &Path, default_mountpoint: &Path) -> DriveState {
|
||||
// No daemon: describe login state instead so the menu is still useful.
|
||||
Err(_) => {
|
||||
let (line, phase) = match auth::load() {
|
||||
Ok(s) if matches!(auth::key_state(), Ok(auth::KeyState::Locked)) => (
|
||||
// Translators: {username} is the Proton account name. The
|
||||
// account has a mailbox password that has to be entered.
|
||||
gettext_f(
|
||||
"Signed in as {username} — locked",
|
||||
&[("username", &s.username)],
|
||||
),
|
||||
Phase::Attention,
|
||||
),
|
||||
Ok(s) => (
|
||||
// Translators: {username} is the Proton account name.
|
||||
gettext_f(
|
||||
@@ -476,6 +485,10 @@ fn main() -> Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// The socket lives in the state dir, which nothing has made yet when the app
|
||||
// starts the tray on a fresh install (B194).
|
||||
dirs.ensure().context("create the app's directories")?;
|
||||
|
||||
// Ensure only one instance of the tray runs.
|
||||
let tray_sock = dirs.tray_socket();
|
||||
if std::os::unix::net::UnixStream::connect(&tray_sock).is_ok() {
|
||||
|
||||
@@ -542,7 +542,7 @@ sequenceDiagram
|
||||
actor User
|
||||
participant UI as pdfs-app
|
||||
participant Auth as pdfs-core auth
|
||||
participant Web as WebKitGTK dialog
|
||||
participant Web as pdfs-app --human-verification
|
||||
participant API as Proton API
|
||||
|
||||
User->>UI: email and password
|
||||
@@ -550,9 +550,9 @@ sequenceDiagram
|
||||
Auth->>API: SRP handshake
|
||||
API-->>Auth: 9001, challenge URL
|
||||
Auth-->>UI: HumanVerificationRequired
|
||||
UI->>Web: load challenge
|
||||
UI->>Web: challenge URL (stdin)
|
||||
User->>Web: solve it
|
||||
Web-->>UI: token (postMessage)
|
||||
Web-->>UI: token (stdout)
|
||||
UI->>Auth: login_verified(token)
|
||||
Auth->>API: new SRP handshake with the token
|
||||
API-->>Auth: session
|
||||
@@ -561,6 +561,9 @@ sequenceDiagram
|
||||
- The challenge used up the first SRP handshake, so the retry starts a new one with the token
|
||||
attached.
|
||||
- The page may post the token as an object or as a JSON string; both are accepted.
|
||||
- The page runs in a WebKitGTK view inside a child `pdfs-app`. WebKit aborts its process when its
|
||||
sandbox cannot start, as on hardened systems such as secureblue (B195). In the child, that ends
|
||||
the verification, and the app says why, instead of closing the app.
|
||||
- The CLI has no web view. It fails with a message to sign in once with `pdfs-app`; the stored
|
||||
session then works for the CLI and the service.
|
||||
|
||||
|
||||
+57
-1
@@ -47,7 +47,7 @@ original wording.
|
||||
it in the index in the same change.
|
||||
|
||||
```markdown
|
||||
### B194 — What the user sees, in one line
|
||||
### B196 — What the user sees, in one line
|
||||
|
||||
**Status:** Open
|
||||
**Found:** 2026-10-06, how it was found
|
||||
@@ -100,6 +100,7 @@ a live account since.
|
||||
|
||||
| Entry | Title |
|
||||
|---|---|
|
||||
| [B195](#b195--the-app-crashes-when-proton-asks-for-a-captcha-on-secureblue) | The app crashes when Proton asks for a CAPTCHA on secureblue |
|
||||
| [B193](#b193--deleting-a-file-whose-create-failed-can-trash-a-file-of-the-users-on-drive) | Deleting a file whose create failed can trash a file of the user's on Drive |
|
||||
| [B191](#b191--a-file-deleted-after-its-create-failed-and-was-written-again-can-stay-on-drive) | A file deleted after its create failed and was written again can stay on Drive |
|
||||
| [B190](#b190--a-file-saved-just-before-the-daemon-stops-can-keep-its-old-content-on-drive) | A file saved just before the daemon stops can keep its old content on Drive |
|
||||
@@ -214,6 +215,7 @@ a live account since.
|
||||
|
||||
| Entry | Title |
|
||||
|---|---|
|
||||
| [B194](#b194--on-a-fresh-install-the-tray-exits-and-the-takeout-page-cannot-remember-its-archives) | On a fresh install the tray exits and the Takeout page cannot remember its archives |
|
||||
| [B192](#b192--a-new-file-closed-empty-reaches-drive-only-half-a-minute-later) | A new file closed empty reaches Drive only half a minute later |
|
||||
| [B181](#b181--the-app-shows-a-queued-edit-kept-as-a-conflict-copy-in-english) | The app shows a queued edit kept as a conflict copy in English |
|
||||
| [B180](#b180--a-stop-waits-10-s-for-a-drain-worker-that-slept-through-it) | A stop waits 10 s for a drain worker that slept through it |
|
||||
@@ -296,6 +298,60 @@ a live account since.
|
||||
|
||||
Newest first.
|
||||
|
||||
### B195 — The app crashes when Proton asks for a CAPTCHA on secureblue
|
||||
|
||||
**Status:** Fixed (unverified). Nobody has run the fix on secureblue yet.
|
||||
**Found:** 2026-10-07, [#29](https://github.com/narrrl/proton-drive-linux/issues/29). On
|
||||
secureblue 44 (a hardened Fedora Atomic), `pdfs-app` aborted a few seconds after the sign-in, with
|
||||
`bwrap: Can't get type of source /run/systemd/journal/socket: Permission denied` and
|
||||
`Failed to fully launch dbus-proxy`.
|
||||
**Where:** `crates/pdfs-gui/src/app/pages/verify.rs`, `crates/pdfs-gui/src/app/pages/login.rs`
|
||||
|
||||
**Repro:** Sign in on secureblue from a network Proton asks a CAPTCHA for, such as a VPN.
|
||||
|
||||
**Cause.** The CAPTCHA page runs in a WebKitGTK view (B8). Before it loads anything, WebKit starts
|
||||
its sandbox: bubblewrap, with the journal socket bound in, and `xdg-dbus-proxy`. secureblue keeps
|
||||
bubblewrap from the socket, the proxy does not start, and WebKit ends its process with `g_error`.
|
||||
The view was in the app's own process, so the whole app went down, and nothing in our code can
|
||||
catch that.
|
||||
|
||||
**Fix.** The view runs in a child, `pdfs-app --human-verification`, that reads the URL on stdin
|
||||
and prints the token on stdout. A child that exits without a token after a crash or a non-zero
|
||||
status ends the sign-in with a message that says the page could not be opened. TROUBLESHOOTING.md
|
||||
gives the cause and a one-time workaround. The sandbox is not switched off by the app: users choose
|
||||
a hardened system for that isolation.
|
||||
|
||||
**Test:** unit tests `a_window_that_died_fails`, `a_window_closed_without_a_token_cancels`,
|
||||
`a_token_counts_even_if_the_window_died_after_it` and `the_token_is_found_among_other_output`.
|
||||
On 2026-10-08 the child ran under real WebKit on Arch against a local page that posts a completion,
|
||||
and handed back its token.
|
||||
|
||||
---
|
||||
|
||||
### B194 — On a fresh install the tray exits and the Takeout page cannot remember its archives
|
||||
|
||||
**Status:** Fixed.
|
||||
**Found:** 2026-10-07, in the log of [#29](https://github.com/narrrl/proton-drive-linux/issues/29):
|
||||
`failed to bind tray single-instance socket: No such file or directory` and
|
||||
`cannot remember staged Takeout archives: No such file or directory`.
|
||||
**Where:** `crates/pdfs-gui/src/main.rs`, `build_window` in `crates/pdfs-gui/src/app/main.rs`
|
||||
|
||||
**Repro:** Start `pdfs-app` with no `~/.local/state/proton-drive-linux`, as on a fresh install. The
|
||||
tray is gone, and staging a Takeout archive logs the warning.
|
||||
|
||||
**Cause.** Both write to the state directory, and only the daemon and the CLI made it
|
||||
(`AppDirs::ensure`). The app starts the tray before the first sign-in, so before the daemon has
|
||||
ever run.
|
||||
|
||||
**Fix.** `pdfs-tray` and `pdfs-app` call `AppDirs::ensure` at start, which also makes the
|
||||
directories owner-only (B6).
|
||||
|
||||
**Verified:** 2026-10-08, `pdfs-tray` with `XDG_STATE_HOME`, `XDG_CONFIG_HOME` and
|
||||
`XDG_CACHE_HOME` pointing at an empty directory. It exited with the error before the fix, and
|
||||
afterwards ran with `tray.sock` in a `0700` state directory.
|
||||
|
||||
---
|
||||
|
||||
### B193 — Deleting a file whose create failed can trash a file of the user's on Drive
|
||||
|
||||
**Status:** Fixed (unverified).
|
||||
|
||||
@@ -11,6 +11,68 @@ scratch (user data in `staging/` and `recovery/` is never touched by this).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **The app crashed when Proton asked for a CAPTCHA on hardened systems.** On secureblue, WebKit
|
||||
cannot start the sandbox for the verification page and ends its process, which took the app
|
||||
down with it. The page now opens in a separate window process: if that process fails, the
|
||||
sign-in stops with a message that says why, and TROUBLESHOOTING.md has a workaround.
|
||||
([#29](https://github.com/narrrl/proton-drive-linux/issues/29))
|
||||
- **On a fresh install the tray icon did not start.** The tray and the app now create their state
|
||||
directory themselves instead of waiting for the service to do it. This also lets the Takeout
|
||||
page remember staged archives before the first mount.
|
||||
([#29](https://github.com/narrrl/proton-drive-linux/issues/29))
|
||||
|
||||
## [3.1.1] — 2026-10-07
|
||||
|
||||
Schema: **42**, unchanged.
|
||||
|
||||
### Changed
|
||||
- **The client identifies itself with its release.** Sign-in and every API call used to send the
|
||||
fixed `external-drive-linux@0.1.0-alpha` and `proton-drive-linux/0.1.0`. If Proton retired that
|
||||
version, every release would fail to sign in at once and no update could fix it. The client now
|
||||
sends `external-drive-linux@<version>-stable` and `proton-drive-linux/<version>`. `app_version`
|
||||
and `user_agent` in `config.json` are optional overrides now. The fixed values that releases up
|
||||
to 3.1.0 wrote there count as unset and are removed on the next save. A value you set by hand is
|
||||
kept.
|
||||
- The About dialog shows the release version, and its debug info shows the identity that is
|
||||
actually sent.
|
||||
|
||||
## [3.1.0] — 2026-10-07
|
||||
|
||||
Schema: **42**, unchanged.
|
||||
|
||||
### Added
|
||||
- **Two-password accounts.** An account with a separate mailbox password now signs in: the app
|
||||
and `pdfs login` ask for it after the login password and check it against the account, so a
|
||||
typo is a retry and not a daemon that never mounts. The mailbox password is never stored.
|
||||
What it unlocks is kept in kernel memory for the login session, so it is asked for once per
|
||||
session and is gone after a reboot or when you log out of the machine.
|
||||
- **`pdfs unlock` and `pdfs lock`.** `pdfs unlock` enters the mailbox password of a locked
|
||||
account and starts the daemon's mount; `pdfs lock` forgets it again. `--remember` on `login`
|
||||
and `unlock` (and the "Keep unlocked on this computer" switch in the app) keeps the unlock in
|
||||
the system keyring instead, so the daemon starts without asking; `pdfs lock --forget` removes
|
||||
it. Off by default: it gives up the separation a second password is for.
|
||||
- **Locked state.** `pdfs status`, `pdfs diagnose` and the tray say when the account is waiting
|
||||
for its mailbox password, and the app asks for it when it opens.
|
||||
|
||||
### Changed
|
||||
- **The keyring no longer holds a password.** The session blob keeps the keys' passphrases
|
||||
instead of the mailbox password, and a blob written by 3.0.x is converted on the first start.
|
||||
A stored password the account rejects (a two-password account that was signed in with only
|
||||
its login password) leaves the account locked instead of failing every start.
|
||||
- **The daemon is not dumpable.** It holds the unlock in memory, so core dumps and same-user
|
||||
`ptrace` are off for it.
|
||||
- **The offline cache is re-keyed** from the new secret, so the first start after the update
|
||||
reads it as cold and fetches the tree again once.
|
||||
|
||||
### Fixed
|
||||
- **systemd killed a daemon that was only retrying.** `WatchdogSec` was answered only once a
|
||||
mount existed, so a daemon waiting for a login or retrying a failed mount was aborted after
|
||||
two minutes and restarted in a loop, hiding the error it logged. It now answers the watchdog
|
||||
while it waits. ([#26](https://github.com/narrrl/proton-drive-linux/issues/26))
|
||||
- **A refreshed token could overwrite a newer unlock or revive a signed-out session.** Token
|
||||
rotation now updates only the tokens in the stored blob.
|
||||
|
||||
## [3.0.0] — 2026-10-05
|
||||
|
||||
Schema: **42**. The queue table is rebuilt so an id is never given out twice; queued changes
|
||||
@@ -1599,6 +1661,10 @@ First stable release: FUSE files-on-demand mount, sync daemon under `proton-driv
|
||||
- The outstanding FUSE defects tracked in `docs/BUGS.md`, plus a truncate defect, validated
|
||||
by a new POSIX compliance suite for the filesystem.
|
||||
|
||||
[3.1.1]: https://github.com/narrrl/proton-drive-linux/releases/tag/v3.1.1
|
||||
|
||||
[3.1.0]: https://github.com/narrrl/proton-drive-linux/releases/tag/v3.1.0
|
||||
|
||||
[3.0.0]: https://github.com/narrrl/proton-drive-linux/releases/tag/v3.0.0
|
||||
|
||||
[2.10.0]: https://github.com/narrrl/proton-drive-linux/releases/tag/v2.10.0
|
||||
|
||||
@@ -89,7 +89,11 @@ fix it.
|
||||
| `open_with` | object | `xdg-open` | — | See [`open_with`](#open_with) |
|
||||
| `prompt` | object | built-in window | — | See [`prompt`](#prompt) |
|
||||
|
||||
`app_version` and `user_agent` identify the client to Proton. Leave them alone.
|
||||
`app_version` and `user_agent` identify the client to Proton. When the keys are absent, the
|
||||
client sends its own release (`external-drive-linux@<version>-stable`, `proton-drive-linux/<version>`).
|
||||
Leave them out unless a support case asks for a different value. The fixed
|
||||
`external-drive-linux@0.1.0-alpha` and `proton-drive-linux/0.1.0` that releases up to 3.1.0 wrote
|
||||
here are treated as absent and removed on the next save.
|
||||
|
||||
### `ignore_patterns`
|
||||
|
||||
|
||||
@@ -72,6 +72,20 @@ pdfs status
|
||||
unfamiliar network. The CLI cannot show it. Sign in with `pdfs-app`, which displays the challenge;
|
||||
the stored session then works for the CLI too.
|
||||
|
||||
**"The verification page couldn't be opened"** — WebKit, which shows the CAPTCHA page, could not
|
||||
start its sandbox. Hardened systems such as secureblue keep its bubblewrap from the journal socket,
|
||||
and the log then shows `bwrap: Can't get type of source /run/systemd/journal/socket: Permission
|
||||
denied` and `Failed to fully launch dbus-proxy`. Check that `bwrap` and `xdg-dbus-proxy` are
|
||||
installed. If they are, sign in once with the sandbox switched off for this one run:
|
||||
|
||||
```bash
|
||||
WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1 pdfs-app
|
||||
```
|
||||
|
||||
Quit the app first, so this starts a new instance. The page then runs without WebKit's isolation,
|
||||
so use this only for the sign-in. The stored session keeps working without it. Signing in from
|
||||
your usual network, without a VPN, often avoids the CAPTCHA in the first place.
|
||||
|
||||
**Sign-in works but is forgotten after a restart** — no Secret Service provider is running, or its
|
||||
keyring is locked. Install and unlock GNOME Keyring, KWallet or KeePassXC (with Secret Service
|
||||
enabled). `pdfs diagnose` shows `keyring session` as failing in that case.
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
# Build + install: cd packaging && makepkg -fi
|
||||
|
||||
pkgname=proton-drive-linux
|
||||
pkgver=3.0.0
|
||||
pkgver=3.1.1
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client for Linux: files-on-demand FUSE mount, CLI, GTK4 app + tray"
|
||||
arch=('x86_64')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux-bin
|
||||
pkgdesc = Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (binaries)
|
||||
pkgver = 3.0.0
|
||||
pkgver = 3.1.0
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
arch = x86_64
|
||||
@@ -21,21 +21,21 @@ pkgbase = proton-drive-for-linux-bin
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-for-linux=3.0.0
|
||||
provides = proton-drive-linux=3.0.0
|
||||
provides = proton-drive-for-linux=3.1.0
|
||||
provides = proton-drive-linux=3.1.0
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux
|
||||
conflicts = proton-drive-for-linux-git
|
||||
options = !strip
|
||||
options = !debug
|
||||
source = proton-drive-linux-3.0.0-x86_64.tar.gz::https://github.com/narrrl/proton-drive-linux/releases/download/v3.0.0/proton-drive-linux-3.0.0-x86_64.tar.gz
|
||||
source = io.narl.proton-drive-linux-3.0.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.0.0/packaging/io.narl.proton-drive-linux.desktop
|
||||
source = io.narl.proton-drive-linux-tray-3.0.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.0.0/packaging/io.narl.proton-drive-linux-tray.desktop
|
||||
source = io.narl.proton-drive-linux-3.0.0.svg::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.0.0/packaging/io.narl.proton-drive-linux.svg
|
||||
source = proton-drive-3.0.0.service::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.0.0/packaging/proton-drive.service
|
||||
source = LICENSE-3.0.0::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.0.0/LICENSE
|
||||
sha256sums = 4d72420f287e0a9b1d65dfc2954779b2df1bf367cb41ffe28519b2791451b6ed
|
||||
source = proton-drive-linux-3.1.0-x86_64.tar.gz::https://github.com/narrrl/proton-drive-linux/releases/download/v3.1.0/proton-drive-linux-3.1.0-x86_64.tar.gz
|
||||
source = io.narl.proton-drive-linux-3.1.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.1.0/packaging/io.narl.proton-drive-linux.desktop
|
||||
source = io.narl.proton-drive-linux-tray-3.1.0.desktop::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.1.0/packaging/io.narl.proton-drive-linux-tray.desktop
|
||||
source = io.narl.proton-drive-linux-3.1.0.svg::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.1.0/packaging/io.narl.proton-drive-linux.svg
|
||||
source = proton-drive-3.1.0.service::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.1.0/packaging/proton-drive.service
|
||||
source = LICENSE-3.1.0::https://raw.githubusercontent.com/narrrl/proton-drive-linux/v3.1.0/LICENSE
|
||||
sha256sums = bd124e249089d2817101e4f8b705ac511decb79a410ab26b0eac9125888f7300
|
||||
sha256sums = d190d6771fff0b975271fb62fd3fb0fa8bbf17d7278c10853c18557855b0c123
|
||||
sha256sums = 1d95e250370220e3bb6aead6ce34d1d6cc759f42c4803b75f1667e78ff47c6c0
|
||||
sha256sums = e598a93c2715c3a9fdc7fb937902083d4a1135e8fbdfe6fe7e37f0383ebbd828
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux-bin
|
||||
pkgver=3.0.0
|
||||
pkgver=3.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (binaries)"
|
||||
arch=('x86_64')
|
||||
@@ -34,7 +34,7 @@ source=("proton-drive-linux-$pkgver-x86_64.tar.gz::$_repo/releases/download/$_ta
|
||||
"io.narl.proton-drive-linux-$pkgver.svg::$_raw/packaging/io.narl.proton-drive-linux.svg"
|
||||
"proton-drive-$pkgver.service::$_raw/packaging/proton-drive.service"
|
||||
"LICENSE-$pkgver::$_raw/LICENSE")
|
||||
sha256sums=('4d72420f287e0a9b1d65dfc2954779b2df1bf367cb41ffe28519b2791451b6ed'
|
||||
sha256sums=('bd124e249089d2817101e4f8b705ac511decb79a410ab26b0eac9125888f7300'
|
||||
'd190d6771fff0b975271fb62fd3fb0fa8bbf17d7278c10853c18557855b0c123'
|
||||
'1d95e250370220e3bb6aead6ce34d1d6cc759f42c4803b75f1667e78ff47c6c0'
|
||||
'e598a93c2715c3a9fdc7fb937902083d4a1135e8fbdfe6fe7e37f0383ebbd828'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux-git
|
||||
pkgdesc = Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (git)
|
||||
pkgver = 3.0.0.r0.g2177383
|
||||
pkgver = 3.1.0.r0.g274bfd0
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
arch = x86_64
|
||||
@@ -24,8 +24,8 @@ pkgbase = proton-drive-for-linux-git
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-for-linux=3.0.0.r0.g2177383
|
||||
provides = proton-drive-linux=3.0.0.r0.g2177383
|
||||
provides = proton-drive-for-linux=3.1.0.r0.g274bfd0
|
||||
provides = proton-drive-linux=3.1.0.r0.g274bfd0
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux-git
|
||||
pkgver=3.0.0.r0.g2177383
|
||||
pkgver=3.1.0.r0.g274bfd0
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: FUSE files-on-demand mount, CLI, GTK4 app, tray (git)"
|
||||
arch=('x86_64')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pkgbase = proton-drive-for-linux
|
||||
pkgdesc = Unofficial Proton Drive client: files-on-demand FUSE mount, CLI, GTK4 app and tray
|
||||
pkgver = 3.0.0
|
||||
pkgver = 3.1.0
|
||||
pkgrel = 1
|
||||
url = https://proton-drive.narl.io
|
||||
arch = x86_64
|
||||
@@ -23,13 +23,13 @@ pkgbase = proton-drive-for-linux
|
||||
optdepends = xdg-utils: "Open folder" action in the tray menu
|
||||
optdepends = fzf: search-as-you-type launcher (pdfs-prompt --fzf)
|
||||
optdepends = foot: terminal that hosts pdfs-prompt --fzf when started from a keybinding
|
||||
provides = proton-drive-linux=3.0.0
|
||||
provides = proton-drive-linux=3.1.0
|
||||
provides = pdfs
|
||||
conflicts = proton-drive-linux
|
||||
conflicts = proton-drive-for-linux-bin
|
||||
conflicts = proton-drive-for-linux-git
|
||||
options = !lto
|
||||
source = proton-drive-for-linux-3.0.0.tar.gz::https://github.com/narrrl/proton-drive-linux/archive/refs/tags/v3.0.0.tar.gz
|
||||
sha256sums = 3a9ca82adae6b03e2b33af520ec49f702a3b4c83151ccc70ae3c21645b719ab5
|
||||
source = proton-drive-for-linux-3.1.0.tar.gz::https://github.com/narrrl/proton-drive-linux/archive/refs/tags/v3.1.0.tar.gz
|
||||
sha256sums = c7c6710e6f55d2ae3dbc29dd4a552a3e676bf4ecb2ff47ac2486dd90bd354ce2
|
||||
|
||||
pkgname = proton-drive-for-linux
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Nils Pukropp <contact@narl.io>
|
||||
|
||||
pkgname=proton-drive-for-linux
|
||||
pkgver=3.0.0
|
||||
pkgver=3.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Unofficial Proton Drive client: files-on-demand FUSE mount, CLI, GTK4 app and tray"
|
||||
arch=('x86_64')
|
||||
@@ -24,7 +24,7 @@ conflicts=('proton-drive-linux' 'proton-drive-for-linux-bin' 'proton-drive-for-l
|
||||
# LTO has broken GTK/Rust links for this workspace; the release profile keeps it off.
|
||||
options=('!lto')
|
||||
source=("$pkgname-$pkgver.tar.gz::$_repo/archive/refs/tags/v$pkgver.tar.gz")
|
||||
sha256sums=('3a9ca82adae6b03e2b33af520ec49f702a3b4c83151ccc70ae3c21645b719ab5')
|
||||
sha256sums=('c7c6710e6f55d2ae3dbc29dd4a552a3e676bf4ecb2ff47ac2486dd90bd354ce2')
|
||||
|
||||
_srcname="proton-drive-linux-$pkgver"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: German\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d. %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A, %-d. %B %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A, %-d. %B %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Meine Dateien"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Fotos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Mit mir geteilt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Von mir geteilt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Papierkorb"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Synchronisierung"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Keine Internetverbindung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Das ist nicht mehr vorhanden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Kein Zugriff darauf"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Etwas anderes hat dies zuerst geändert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Das Proton Drive ist voll"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Tastenkürzel"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "Info zu Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Hauptmenü"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -166,23 +166,23 @@ msgstr ""
|
||||
"Inoffizieller Client – nicht mit Proton AG verbunden, von Proton AG "
|
||||
"unterstützt oder befürwortet."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Quellcode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Nutzungsbedingungen von Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Datenschutzerklärung von Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Haftungsausschluss"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -207,7 +207,7 @@ msgstr ""
|
||||
"bereitgestellt. Daten, deren Verlust nicht hinnehmbar ist, sollten "
|
||||
"zusätzlich gesichert werden."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -217,7 +217,7 @@ msgstr ""
|
||||
"\">GeoNames</a>, lizenziert unter <a href=\"https://creativecommons.org/"
|
||||
"licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -227,7 +227,7 @@ msgstr ""
|
||||
"href=\"https://www.naturalearthdata.com/\">Natural Earth</a> gezeichnet, die "
|
||||
"gemeinfrei sind."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -243,15 +243,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Mitwirkende an Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Proton Drive beenden?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -260,7 +260,7 @@ msgstr ""
|
||||
"eine Verbindung hergestellt wird. Proton Drive startet bei der nächsten "
|
||||
"Anmeldung erneut."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -275,7 +275,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -290,30 +291,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Beenden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Proton Drive konnte nicht beendet werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "Der Proton-Drive-Dienst wurde nicht beendet."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Allgemein"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Drive durchsuchen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -322,38 +323,38 @@ msgstr "Drive durchsuchen"
|
||||
msgid "Refresh"
|
||||
msgstr "Aktualisieren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Tastenkürzel"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Dateien"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Neuer Ordner"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Dateien hochladen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Zurück / Vor"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Übergeordneter Ordner"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Raster / Liste"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -362,7 +363,7 @@ msgstr "Raster / Liste"
|
||||
msgid "Rename"
|
||||
msgstr "Umbenennen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -372,73 +373,73 @@ msgstr "Umbenennen"
|
||||
msgid "Move to Trash"
|
||||
msgstr "In den Papierkorb verschieben"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Auswahl aufheben"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Größere Vorschaubilder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Kleinere Vorschaubilder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Vorschaubildgröße zurücksetzen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Alles auswählen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Fotobetrachter"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Vorheriges / nächstes Foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Erstes / letztes Foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Details anzeigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Vollbild"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Zum Umbenennen genau ein Element auswählen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Nicht verbunden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Der Proton-Drive-Dienst läuft nicht."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Verbindung wird hergestellt …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Warten auf den Start des Proton-Drive-Dienstes."
|
||||
|
||||
@@ -1287,7 +1288,7 @@ msgstr "Alben konnten nicht geladen werden"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1555,7 +1556,7 @@ msgid "Make available offline"
|
||||
msgstr "Offline verfügbar machen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Nur online verfügbar machen"
|
||||
|
||||
@@ -2724,7 +2725,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisierung bis zur Fortsetzung pausiert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisierung pausiert"
|
||||
|
||||
@@ -3200,25 +3201,36 @@ msgstr "E-Mail-Adresse und Passwort eingeben."
|
||||
msgid "Signing in…"
|
||||
msgstr "Anmeldung läuft …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Zum Fortfahren die Überprüfung abschließen …"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "Anmeldung abgebrochen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"Die Überprüfungsseite konnte nicht geöffnet werden, daher wurde die "
|
||||
"Anmeldung abgebrochen. Möglicherweise verhindert das System, dass die "
|
||||
"Sandbox der Webansicht startet; die Anleitung zur Fehlerbehebung erklärt, "
|
||||
"was zu tun ist."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr "Zu viele Anmeldeversuche. Einige Minuten warten und erneut versuchen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Proton ist nicht erreichbar. Bitte die Internetverbindung prüfen und erneut "
|
||||
"versuchen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3227,11 +3239,19 @@ msgstr ""
|
||||
"gespeichert werden. Bitte sicherstellen, dass ein Schlüsselbund (GNOME "
|
||||
"Keyring oder KWallet) läuft und entsperrt ist."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Anmeldung abgebrochen: Es wurde kein Zwei-Faktor-Code eingegeben."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Anmeldung abgebrochen: Es wurde kein Postfach-Passwort eingegeben."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "Das Postfach-Passwort hat Ihr Konto nicht entsperrt."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3240,35 +3260,87 @@ msgstr ""
|
||||
"neue Überprüfung erneut anmelden."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Anmeldung fehlgeschlagen: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"Das Postfach-Passwort hat Ihr Konto nicht entsperrt. Versuchen Sie es erneut."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Dieses Konto hat ein separates Postfach-Passwort. Geben Sie es ein, um Ihre "
|
||||
"Dateien zu entsperren."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Postfach-Passwort"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Postfach-Passwort"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Auf diesem Computer entsperrt lassen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Speichert die Entsperrung im System-Schlüsselbund, sodass sich Proton Drive "
|
||||
"nach jeder Anmeldung ohne Nachfrage öffnet. Andernfalls geben Sie das "
|
||||
"Passwort einmal pro Sitzung ein."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Entsperren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive ist gesperrt. Geben Sie Ihr Postfach-Passwort ein, um es zu "
|
||||
"entsperren."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Entsperrt."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Entsperren fehlgeschlagen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Zwei-Faktor-Authentifizierung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Den Code aus der Authentifizierungs-App oder einen der "
|
||||
"Wiederherstellungscodes eingeben."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Authentifizierungscode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Bestätigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Abmelden?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3277,7 +3349,7 @@ msgstr ""
|
||||
"nächsten Anmeldung. Dateien, die sich bereits auf diesem Computer befinden, "
|
||||
"bleiben, wo sie sind."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
@@ -4645,40 +4717,40 @@ msgid "Restart Now"
|
||||
msgstr "Jetzt neu starten"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} belegt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} von {total} belegt ({percent} %)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive verbunden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Deine Dateien sind verfügbar."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive getrennt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"Der Proton-Drive-Dienst wurde beendet. Dateien sind erst nach seinem "
|
||||
"Neustart wieder verfügbar."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Synchronisierung abgeschlossen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4687,27 +4759,27 @@ msgstr[1] "Übertragung von {n} Dateien abgeschlossen."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} – {done} von {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} – {detail} ({done} von {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title} …"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} – {detail} …"
|
||||
@@ -4715,7 +4787,7 @@ msgstr "{title} – {detail} …"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} – {done} ({speed}/s)"
|
||||
@@ -4723,118 +4795,118 @@ msgstr "{arrow} {name} – {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} – {done} von {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} zwischengespeichert – keine Grenze festgelegt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} von {limit} belegt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · wird {time} fortgesetzt"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Wird {time} fortgesetzt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Bis zur manuellen Fortsetzung"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} Änderung erfordert Aufmerksamkeit"
|
||||
msgstr[1] "{n} Änderungen erfordern Aufmerksamkeit"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Nur zwischengespeicherte Dateien"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Wird synchronisiert"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Auf dem neuesten Stand"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive läuft nicht"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Reagiert nicht"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive braucht zu lange für eine Antwort"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "später"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "um %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "am %a um %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "am %-d. %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Keine offline verfügbaren Dateien"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
"Mit einem Rechtsklick auf eine Datei „Offline verfügbar machen“ auswählen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Konnte nicht auf „nur online“ umgestellt werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Weniger anzeigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5266,7 +5338,7 @@ msgstr "Papierkorb geleert"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Der Papierkorb konnte nicht geleert werden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Überprüfung"
|
||||
|
||||
@@ -5898,40 +5970,45 @@ msgstr[1] "↑ {n} werden hochgeladen"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive reagiert nicht"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Angemeldet als {username} – gesperrt"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Angemeldet als {username} – nicht verbunden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Nicht angemeldet"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Fehler: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive hat unerwartet geantwortet"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Aktuell in {mountpoint} ({n} angeheftet)"
|
||||
msgstr[1] "Aktuell in {mountpoint} ({n} angeheftet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Wird synchronisiert – {queued} ({n} angeheftet)"
|
||||
msgstr[1] "Wird synchronisiert – {queued} ({n} angeheftet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5939,52 +6016,52 @@ msgstr[0] "Offline – nur zwischengespeicherte Dateien ({n} angeheftet)"
|
||||
msgstr[1] "Offline – nur zwischengespeicherte Dateien ({n} angeheftet)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline – {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} Problem – Anzeigen"
|
||||
msgstr[1] "{n} Probleme – Anzeigen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Anmelden …"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Proton Drive öffnen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Ordner öffnen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Synchronisierung fortsetzen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Synchronisierung pausieren"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Symbol im Benachrichtigungsfeld ausblenden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Proton Drive beenden …"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Beenden"
|
||||
|
||||
|
||||
+212
-141
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: English (United Kingdom)\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A %-d %B %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A %-d %B %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "My files"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Photos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Shared with me"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Shared by me"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Computers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Trash"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Sync"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "You're offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "That's not there any more"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "You don't have access to that"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Something changed this first"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Your Proton Drive is full"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Preferences"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Keyboard Shortcuts"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "About Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Main menu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -166,23 +166,23 @@ msgstr ""
|
||||
"Unofficial client — not affiliated with, endorsed by, or supported by Proton "
|
||||
"AG."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Source Code"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Proton Terms of Service"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Proton Privacy Policy"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Disclaimer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -204,7 +204,7 @@ msgstr ""
|
||||
"This software is provided “as is”, without warranty of any kind. Keep a copy "
|
||||
"of any data you cannot afford to lose."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -214,7 +214,7 @@ msgstr ""
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
"licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -224,7 +224,7 @@ msgstr ""
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
"public domain."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -240,15 +240,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Proton Drive for Linux contributors"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Stop Proton Drive?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -256,7 +256,7 @@ msgstr ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -271,7 +271,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -286,30 +287,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Stop"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Couldn't stop Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "The Proton Drive service did not stop."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Search Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -318,38 +319,38 @@ msgstr "Search Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Refresh"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Keyboard shortcuts"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Files"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "New folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Upload files"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Back / forward"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Parent folder"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Grid / list"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -358,7 +359,7 @@ msgstr "Grid / list"
|
||||
msgid "Rename"
|
||||
msgstr "Rename"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -368,73 +369,73 @@ msgstr "Rename"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Move to Trash"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Clear the selection"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Larger thumbnails"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Smaller thumbnails"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Reset thumbnail size"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Select all"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Photo Viewer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Previous / next photo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "First / last photo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Show details"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Fullscreen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Close"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Select a single item to rename it"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Not connected"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "The Proton Drive service isn't running."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Connecting…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Waiting for the Proton Drive service to start."
|
||||
|
||||
@@ -1275,7 +1276,7 @@ msgstr "Couldn't load albums"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1543,7 +1544,7 @@ msgid "Make available offline"
|
||||
msgstr "Make available offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Make online only"
|
||||
|
||||
@@ -2686,7 +2687,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sync paused until you resume"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Sync paused"
|
||||
|
||||
@@ -3149,23 +3150,33 @@ msgstr "Enter your email and password."
|
||||
msgid "Signing in…"
|
||||
msgstr "Signing in…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Complete the verification to continue…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "login cancelled"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr "Couldn't reach Proton. Check your internet connection and try again."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3173,11 +3184,19 @@ msgstr ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Sign-in cancelled: no two-factor code was entered."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Sign-in cancelled: no mailbox password was entered."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "That mailbox password didn't unlock your account."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3186,34 +3205,81 @@ msgstr ""
|
||||
"new one."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Sign-in failed: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr "That mailbox password didn't unlock your account. Try again."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Mailbox Password"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Mailbox password"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Keep unlocked on this computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Unlock"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Unlocked."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Couldn't unlock"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Two-Factor Authentication"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Authentication code"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Confirm"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Sign Out?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3221,7 +3287,7 @@ msgstr ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Sign Out"
|
||||
|
||||
@@ -4556,39 +4622,39 @@ msgid "Restart Now"
|
||||
msgstr "Restart Now"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} used"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} of {total} used ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive connected"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Your files are available."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive disconnected"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Sync complete"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4597,27 +4663,27 @@ msgstr[1] "{n} files finished transferring."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} — {done} of {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} — {detail} ({done} of {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} — {detail}…"
|
||||
@@ -4625,7 +4691,7 @@ msgstr "{title} — {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
@@ -4633,117 +4699,117 @@ msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} cached — no limit set"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} of {limit} used"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · resumes {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Resumes {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Until you resume"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} change needs attention"
|
||||
msgstr[1] "{n} changes need attention"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Cached files only"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Syncing"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Up to date"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive isn't running"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Not responding"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive is taking too long to answer"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "later"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "at %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%e %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "No files kept offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr "Right-click a file and choose “Make available offline”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Couldn't make it online only"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Show fewer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5163,7 +5229,7 @@ msgstr "Trash emptied"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Couldn't empty the trash"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Verification"
|
||||
|
||||
@@ -5788,40 +5854,45 @@ msgstr[1] "↑ {n} uploading"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive isn't responding"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Signed in as {username} — locked"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Signed in as {username} — not connected"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Not signed in"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Error: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive sent an unexpected reply"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[1] "Up to date in {mountpoint} ({n} pinned)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[1] "Syncing — {queued} ({n} pinned)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5829,52 +5900,52 @@ msgstr[0] "Offline — cached files only ({n} pinned)"
|
||||
msgstr[1] "Offline — cached files only ({n} pinned)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} issue — View"
|
||||
msgstr[1] "{n} issues — View"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Sign In…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Open Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Open Folder"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Resume Sync"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pause Sync"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Connect"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Hide Tray Icon"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Stop Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Quit"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Spanish\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A, %-d de %B de %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A, %-d de %B de %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Mis archivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Fotos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Compartido conmigo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Compartido por mí"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Equipos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Papelera"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Sincronización"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Está sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Eso ya no existe"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "No tiene acceso a eso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Algo lo cambió antes"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Su Proton Drive está lleno"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Atajos del teclado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "Acerca de Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Menú principal"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -166,23 +166,23 @@ msgstr ""
|
||||
"Cliente no oficial: no está afiliado a Proton AG, ni respaldado ni mantenido "
|
||||
"por esta."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Código fuente"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Condiciones del servicio de Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Política de privacidad de Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Aviso legal"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -205,7 +205,7 @@ msgstr ""
|
||||
"Este software se proporciona “tal cual”, sin garantía de ningún tipo. Guarde "
|
||||
"una copia de los datos que no pueda permitirse perder."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -215,7 +215,7 @@ msgstr ""
|
||||
"www.geonames.org/\">GeoNames</a>, con licencia <a href=\"https://"
|
||||
"creativecommons.org/licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -225,7 +225,7 @@ msgstr ""
|
||||
"fronteras de países de <a href=\"https://www.naturalearthdata.com/\">Natural "
|
||||
"Earth</a>, que son de dominio público."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -241,15 +241,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Colaboradores de Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "¿Detener Proton Drive?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -258,7 +258,7 @@ msgstr ""
|
||||
"a conectarse. Proton Drive se iniciará de nuevo en su próximo inicio de "
|
||||
"sesión."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -273,7 +273,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -288,30 +289,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Detener"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "No se pudo detener Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "El servicio de Proton Drive no se detuvo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "General"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Buscar en Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -320,38 +321,38 @@ msgstr "Buscar en Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Atajos del teclado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Archivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Carpeta nueva"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Subir archivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Atrás / adelante"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Carpeta superior"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Cuadrícula / lista"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -360,7 +361,7 @@ msgstr "Cuadrícula / lista"
|
||||
msgid "Rename"
|
||||
msgstr "Renombrar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -370,73 +371,73 @@ msgstr "Renombrar"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Mover a la papelera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Anular la selección"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Miniaturas más grandes"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Miniaturas más pequeñas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Restablecer el tamaño de las miniaturas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Seleccionar todo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Visor de fotos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Foto anterior / siguiente"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Primera / última foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Mostrar detalles"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Pantalla completa"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Seleccione un único elemento para renombrarlo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "El servicio de Proton Drive no está en ejecución."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Conectando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Esperando a que se inicie el servicio de Proton Drive."
|
||||
|
||||
@@ -1281,7 +1282,7 @@ msgstr "No se pudieron cargar los álbumes"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1549,7 +1550,7 @@ msgid "Make available offline"
|
||||
msgstr "Hacer disponible sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Hacer solo en línea"
|
||||
|
||||
@@ -2707,7 +2708,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronización en pausa hasta que la reanude"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronización en pausa"
|
||||
|
||||
@@ -3174,27 +3175,37 @@ msgstr "Introduzca su correo electrónico y su contraseña."
|
||||
msgid "Signing in…"
|
||||
msgstr "Iniciando sesión…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Complete la verificación para continuar…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "inicio de sesión cancelado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"No se pudo abrir la página de verificación, así que se canceló el inicio de "
|
||||
"sesión. Es posible que su sistema impida que se inicie el entorno aislado de "
|
||||
"la vista web; la guía de solución de problemas explica qué hacer."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr ""
|
||||
"Demasiados intentos de inicio de sesión. Espere unos minutos e inténtelo de "
|
||||
"nuevo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"No se pudo contactar con Proton. Compruebe su conexión a Internet e "
|
||||
"inténtelo de nuevo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3203,12 +3214,20 @@ msgstr ""
|
||||
"sistema. Asegúrese de que un depósito de claves (GNOME Keyring o KWallet) "
|
||||
"esté en ejecución y desbloqueado."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr ""
|
||||
"Inicio de sesión cancelado: no se introdujo ningún código de dos factores."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Inicio de sesión cancelado: no se introdujo la contraseña del buzón."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "Esa contraseña del buzón no desbloqueó tu cuenta."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3217,35 +3236,86 @@ msgstr ""
|
||||
"sesión para obtener una nueva."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Falló el inicio de sesión: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr "Esa contraseña del buzón no desbloqueó tu cuenta. Inténtalo de nuevo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Esta cuenta tiene una contraseña del buzón independiente. Introdúcela para "
|
||||
"desbloquear tus archivos."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Contraseña del buzón"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Contraseña del buzón"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Mantener desbloqueado en este equipo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Guarda el desbloqueo en el llavero del sistema, para que Proton Drive se "
|
||||
"abra sin preguntar después de cada inicio de sesión. De lo contrario, "
|
||||
"introduces la contraseña una vez por sesión."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Desbloquear"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive está bloqueado. Introduce la contraseña del buzón para "
|
||||
"desbloquearlo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Desbloqueado."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "No se pudo desbloquear"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticación en dos pasos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Introduzca el código de su aplicación de autenticación o uno de sus códigos "
|
||||
"de recuperación."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Código de autenticación"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "¿Cerrar la sesión?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3254,7 +3324,7 @@ msgstr ""
|
||||
"iniciar sesión. Los archivos que ya están en este equipo se quedan donde "
|
||||
"están."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Cerrar la sesión"
|
||||
|
||||
@@ -4606,40 +4676,40 @@ msgid "Restart Now"
|
||||
msgstr "Reiniciar ahora"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} usados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} de {total} usados ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive conectado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Sus archivos están disponibles."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive desconectado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"El servicio de Proton Drive se detuvo. Los archivos no estarán disponibles "
|
||||
"hasta que se reinicie."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Sincronización completada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4648,27 +4718,27 @@ msgstr[1] "{n} archivos terminaron de transferirse."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title}: {done} de {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title}: {detail} ({done} de {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title}: {detail}…"
|
||||
@@ -4676,7 +4746,7 @@ msgstr "{title}: {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name}: {done} ({speed}/s)"
|
||||
@@ -4684,119 +4754,119 @@ msgstr "{arrow} {name}: {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name}: {done} de {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} en caché — sin límite"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} de {limit} usados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · se reanuda {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Se reanuda {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Hasta que la reanude"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} cambio requiere atención"
|
||||
msgstr[1] "{n} cambios requieren atención"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Solo archivos en caché"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Sincronizando"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Actualizado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive no está en ejecución"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "No responde"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive está tardando demasiado en responder"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "más tarde"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "a las %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%-d %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "No hay archivos disponibles sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
"Pulse con el botón derecho en un archivo y elija “Hacer disponible sin "
|
||||
"conexión”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "No se pudo hacer solo en línea"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Mostrar menos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5224,7 +5294,7 @@ msgstr "Papelera vaciada"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "No se pudo vaciar la papelera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Verificación"
|
||||
|
||||
@@ -5858,40 +5928,45 @@ msgstr[1] "↑ {n} subiendo"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive no responde"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Sesión iniciada como {username} — bloqueado"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Sesión iniciada como {username} — sin conexión"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Sesión no iniciada"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Error: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive envió una respuesta inesperada"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Actualizado en {mountpoint} ({n} fijado)"
|
||||
msgstr[1] "Actualizado en {mountpoint} ({n} fijados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizando: {queued} ({n} anclado)"
|
||||
msgstr[1] "Sincronizando: {queued} ({n} anclados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5899,52 +5974,52 @@ msgstr[0] "Sin conexión: solo archivos en caché ({n} anclado)"
|
||||
msgstr[1] "Sin conexión: solo archivos en caché ({n} anclados)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Sin conexión: {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema: ver"
|
||||
msgstr[1] "{n} problemas: ver"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Iniciar sesión…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Abrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Abrir carpeta"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Reanudar la sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pausar la sincronización"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ocultar el icono de la bandeja"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Detener Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Salir"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: French\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A %-d %B %Y à %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A %-d %B %Y à %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Mes fichiers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Photos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Partagés avec moi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Partagés par moi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Ordinateurs"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Corbeille"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Synchronisation"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what} : {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Vous êtes hors ligne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Cet élément n’existe plus"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Vous n’avez pas accès à cet élément"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Quelque chose l’a modifié entre-temps"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Votre Proton Drive est plein"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Préférences"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Raccourcis clavier"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "À propos de Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Menu principal"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -166,23 +166,23 @@ msgstr ""
|
||||
"Client non officiel — non affilié à Proton AG, ni approuvé ni pris en charge "
|
||||
"par Proton AG."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Code source"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Conditions d’utilisation de Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Politique de confidentialité de Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Avertissement"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -206,7 +206,7 @@ msgstr ""
|
||||
"une copie de toutes les données que vous ne pouvez pas vous permettre de "
|
||||
"perdre."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -216,7 +216,7 @@ msgstr ""
|
||||
"www.geonames.org/\">GeoNames</a>, sous licence <a href=\"https://"
|
||||
"creativecommons.org/licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -226,7 +226,7 @@ msgstr ""
|
||||
"frontières des pays de <a href=\"https://www.naturalearthdata.com/\">Natural "
|
||||
"Earth</a>, qui sont dans le domaine public."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -243,15 +243,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Les contributeurs de Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Arrêter Proton Drive ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -260,7 +260,7 @@ msgstr ""
|
||||
"vous reconnectez pas. Proton Drive redémarrera à votre prochaine ouverture "
|
||||
"de session."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -275,7 +275,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -290,30 +291,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Arrêter"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Impossible d’arrêter Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "Le service Proton Drive ne s’est pas arrêté."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Général"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Rechercher dans Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -322,38 +323,38 @@ msgstr "Rechercher dans Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Actualiser"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Raccourcis clavier"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Fichiers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Nouveau dossier"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Téléverser des fichiers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Précédent / suivant"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Dossier parent"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Grille / liste"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -362,7 +363,7 @@ msgstr "Grille / liste"
|
||||
msgid "Rename"
|
||||
msgstr "Renommer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -372,73 +373,73 @@ msgstr "Renommer"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Mettre à la corbeille"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Effacer la sélection"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Miniatures plus grandes"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Miniatures plus petites"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Réinitialiser la taille des miniatures"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Tout sélectionner"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Visionneuse de photos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Photo précédente / suivante"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Première / dernière photo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Afficher les détails"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Plein écran"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Sélectionnez un seul élément pour le renommer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Non connecté"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Le service Proton Drive n’est pas en cours d’exécution."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Connexion…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "En attente du démarrage du service Proton Drive."
|
||||
|
||||
@@ -1292,7 +1293,7 @@ msgstr "Impossible de charger les albums"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1560,7 +1561,7 @@ msgid "Make available offline"
|
||||
msgstr "Rendre disponible hors ligne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Garder en ligne uniquement"
|
||||
|
||||
@@ -2724,7 +2725,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisation en pause jusqu’à la reprise"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisation en pause"
|
||||
|
||||
@@ -3200,25 +3201,35 @@ msgstr "Saisissez votre adresse électronique et votre mot de passe."
|
||||
msgid "Signing in…"
|
||||
msgstr "Connexion…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Terminez la vérification pour continuer…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "connexion annulée"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"La page de vérification n’a pas pu s’ouvrir, la connexion a donc été "
|
||||
"annulée. Votre système empêche peut-être le démarrage du bac à sable de la "
|
||||
"vue web ; le guide de dépannage explique la marche à suivre."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr ""
|
||||
"Trop de tentatives de connexion. Patientez quelques minutes et réessayez."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Impossible de joindre Proton. Vérifiez votre connexion Internet et réessayez."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3227,11 +3238,21 @@ msgstr ""
|
||||
"système. Assurez-vous qu’un trousseau (GNOME Keyring ou KWallet) est en "
|
||||
"cours d’exécution et déverrouillé."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Connexion annulée : aucun code à deux facteurs n’a été saisi."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr ""
|
||||
"Connexion annulée : aucun mot de passe de boîte aux lettres n’a été saisi."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr ""
|
||||
"Ce mot de passe de boîte aux lettres n’a pas déverrouillé votre compte."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3240,35 +3261,88 @@ msgstr ""
|
||||
"pour en obtenir une nouvelle."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Échec de la connexion : {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"Ce mot de passe de boîte aux lettres n’a pas déverrouillé votre compte. "
|
||||
"Réessayez."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Ce compte a un mot de passe de boîte aux lettres distinct. Saisissez-le pour "
|
||||
"déverrouiller vos fichiers."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Mot de passe de la boîte aux lettres"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Mot de passe de la boîte aux lettres"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Garder déverrouillé sur cet ordinateur"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Enregistre le déverrouillage dans le trousseau de clés du système, afin que "
|
||||
"Proton Drive s’ouvre sans demande après chaque connexion. Sinon, vous "
|
||||
"saisissez le mot de passe une fois par session."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Déverrouiller"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive est verrouillé. Saisissez votre mot de passe de boîte aux "
|
||||
"lettres pour le déverrouiller."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Déverrouillé."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Impossible de déverrouiller"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Authentification à deux facteurs"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Saisissez le code de votre application d’authentification ou l’un de vos "
|
||||
"codes de récupération."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Code d’authentification"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Se déconnecter ?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3277,7 +3351,7 @@ msgstr ""
|
||||
"vous vous reconnectiez. Les fichiers déjà présents sur cet ordinateur "
|
||||
"restent en place."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Se déconnecter"
|
||||
|
||||
@@ -4643,40 +4717,40 @@ msgid "Restart Now"
|
||||
msgstr "Redémarrer maintenant"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} utilisés"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} utilisés sur {total} ({percent} %)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive connecté"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Vos fichiers sont disponibles."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive déconnecté"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"Le service Proton Drive s’est arrêté. Les fichiers ne sont pas disponibles "
|
||||
"tant qu’il n’a pas redémarré."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Synchronisation terminée"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4685,27 +4759,27 @@ msgstr[1] "Le transfert de {n} fichiers est terminé."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} — {done} sur {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} — {detail} ({done} sur {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} — {detail}…"
|
||||
@@ -4713,7 +4787,7 @@ msgstr "{title} — {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
@@ -4721,119 +4795,119 @@ msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} sur {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} en cache — aucune limite définie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} utilisés sur {limit}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · reprise {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Reprise {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Jusqu’à la reprise"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} modification requiert votre attention"
|
||||
msgstr[1] "{n} modifications requièrent votre attention"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Hors ligne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Fichiers en cache uniquement"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "À jour"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive n’est pas en cours d’exécution"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Ne répond pas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive met trop de temps à répondre"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "plus tard"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "à %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%e %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Aucun fichier disponible hors ligne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
"Faites un clic droit sur un fichier et choisissez « Rendre disponible hors "
|
||||
"ligne »."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Impossible de le garder en ligne uniquement"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Afficher moins"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5264,7 +5338,7 @@ msgstr "Corbeille vidée"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Impossible de vider la corbeille"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Vérification"
|
||||
|
||||
@@ -5899,40 +5973,45 @@ msgstr[1] "↑ {n} en téléversement"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive ne répond pas"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Connecté en tant que {username} — verrouillé"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Connecté en tant que {username} — non connecté"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Non connecté"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Erreur : {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive a envoyé une réponse inattendue"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "À jour dans {mountpoint} ({n} épinglé)"
|
||||
msgstr[1] "À jour dans {mountpoint} ({n} épinglés)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Synchronisation — {queued} ({n} épinglé)"
|
||||
msgstr[1] "Synchronisation — {queued} ({n} épinglés)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5940,52 +6019,52 @@ msgstr[0] "Hors ligne — fichiers en cache uniquement ({n} épinglé)"
|
||||
msgstr[1] "Hors ligne — fichiers en cache uniquement ({n} épinglés)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Hors ligne — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problème — Afficher"
|
||||
msgstr[1] "{n} problèmes — Afficher"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Se connecter…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Ouvrir Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Ouvrir le dossier"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Reprendre la synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Mettre en pause la synchronisation"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Connecter"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Masquer l’icône de la zone de notification"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Arrêter Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Quitter"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Italian\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A %-d %B %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A %-d %B %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "I miei file"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Condivisi con me"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Condivisi da me"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Cestino"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Sincronizzazione"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Sei offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Non esiste più"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Non hai accesso a questo elemento"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "È stato modificato prima da qualcos'altro"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Il tuo Proton Drive è pieno"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Preferenze"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Scorciatoie da tastiera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "Informazioni su Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Menu principale"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -165,23 +165,23 @@ msgstr ""
|
||||
"\n"
|
||||
"Client non ufficiale: non affiliato, approvato né supportato da Proton AG."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Codice sorgente"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Termini di servizio di Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Informativa sulla privacy di Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Esclusione di responsabilità"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -204,7 +204,7 @@ msgstr ""
|
||||
"Questo software è fornito “così com’è”, senza alcuna garanzia. Conserva una "
|
||||
"copia dei dati che non puoi permetterti di perdere."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -214,7 +214,7 @@ msgstr ""
|
||||
"\">GeoNames</a>, con licenza <a href=\"https://creativecommons.org/licenses/"
|
||||
"by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -224,7 +224,7 @@ msgstr ""
|
||||
"confini nazionali di <a href=\"https://www.naturalearthdata.com/\">Natural "
|
||||
"Earth</a>, che sono di pubblico dominio."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -240,15 +240,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Collaboratori di Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Arrestare Proton Drive?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -256,7 +256,7 @@ msgstr ""
|
||||
"I miei file andranno offline e nulla verrà sincronizzato finché non ti "
|
||||
"riconnetti. Proton Drive si riavvierà al prossimo accesso."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -271,7 +271,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -286,30 +287,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Annulla"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Arresta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Impossibile arrestare Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "Il servizio di Proton Drive non si è arrestato."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Generale"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Cerca in Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -318,38 +319,38 @@ msgstr "Cerca in Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Aggiorna"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Scorciatoie da tastiera"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "File"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Nuova cartella"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Carica file"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Indietro / avanti"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Cartella superiore"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Griglia / elenco"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -358,7 +359,7 @@ msgstr "Griglia / elenco"
|
||||
msgid "Rename"
|
||||
msgstr "Rinomina"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -368,73 +369,73 @@ msgstr "Rinomina"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Sposta nel cestino"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Annulla la selezione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Miniature più grandi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Miniature più piccole"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Ripristina la dimensione delle miniature"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Seleziona tutto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Visualizzatore di foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Foto precedente / successiva"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Prima / ultima foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Mostra dettagli"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Schermo intero"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Chiudi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Seleziona un solo elemento per rinominarlo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Non connesso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Il servizio di Proton Drive non è in esecuzione."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Connessione…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "In attesa dell’avvio del servizio di Proton Drive."
|
||||
|
||||
@@ -1286,7 +1287,7 @@ msgstr "Impossibile caricare gli album"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1554,7 +1555,7 @@ msgid "Make available offline"
|
||||
msgstr "Rendi disponibile offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Rendi solo online"
|
||||
|
||||
@@ -2722,7 +2723,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronizzazione in pausa finché non riprendi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronizzazione in pausa"
|
||||
|
||||
@@ -3192,25 +3193,35 @@ msgstr "Inserisci la tua email e la password."
|
||||
msgid "Signing in…"
|
||||
msgstr "Accesso in corso…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Completa la verifica per continuare…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "accesso annullato"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"Impossibile aprire la pagina di verifica, quindi l'accesso è stato "
|
||||
"annullato. Il sistema potrebbe impedire l'avvio della sandbox della vista "
|
||||
"web; la guida alla risoluzione dei problemi spiega cosa fare."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr "Troppi tentativi di accesso. Attendi qualche minuto e riprova."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Impossibile raggiungere Proton. Controlla la connessione a Internet e "
|
||||
"riprova."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3219,13 +3230,24 @@ msgstr ""
|
||||
"portachiavi di sistema. Assicurati che un portachiavi (GNOME Keyring o "
|
||||
"KWallet) sia in esecuzione e sbloccato."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr ""
|
||||
"Accesso annullato: non è stato inserito alcun codice di autenticazione a due "
|
||||
"fattori."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr ""
|
||||
"Accesso annullato: non è stata inserita alcuna password della casella di "
|
||||
"posta."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr ""
|
||||
"Quella password della casella di posta non ha sbloccato il tuo account."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3234,35 +3256,88 @@ msgstr ""
|
||||
"riceverne una nuova."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Accesso non riuscito: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"Quella password della casella di posta non ha sbloccato il tuo account. "
|
||||
"Riprova."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Questo account ha una password della casella di posta separata. Inseriscila "
|
||||
"per sbloccare i tuoi file."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Password della casella di posta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Password della casella di posta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Mantieni sbloccato su questo computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Salva lo sblocco nel portachiavi di sistema, così Proton Drive si apre senza "
|
||||
"chiedere dopo ogni accesso. Altrimenti inserisci la password una volta per "
|
||||
"sessione."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Sblocca"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive è bloccato. Inserisci la password della casella di posta per "
|
||||
"sbloccarlo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Sbloccato."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Impossibile sbloccare"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticazione a due fattori"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Inserisci il codice dell'app di autenticazione o uno dei tuoi codici di "
|
||||
"recupero."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Codice di autenticazione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Conferma"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Disconnettersi?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3270,7 +3345,7 @@ msgstr ""
|
||||
"Proton Drive si disconnetterà e interromperà la sincronizzazione finché non "
|
||||
"accedi di nuovo. I file già presenti su questo computer restano dove sono."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Disconnetti"
|
||||
|
||||
@@ -4621,40 +4696,40 @@ msgid "Restart Now"
|
||||
msgstr "Riavvia ora"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} utilizzati"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} di {total} utilizzati ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive connesso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "I tuoi file sono disponibili."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive disconnesso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"Il servizio di Proton Drive si è arrestato. I file non sono disponibili "
|
||||
"finché non si riavvia."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Sincronizzazione completata"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4663,27 +4738,27 @@ msgstr[1] "Trasferimento di {n} file completato."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title}: {done} di {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title}: {detail} ({done} di {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title}: {detail}…"
|
||||
@@ -4691,7 +4766,7 @@ msgstr "{title}: {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name}: {done} ({speed}/s)"
|
||||
@@ -4699,117 +4774,117 @@ msgstr "{arrow} {name}: {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name}: {done} di {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} in cache — nessun limite impostato"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} di {limit} utilizzati"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · riprende {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Riprende {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Finché non riprendi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} modifica richiede attenzione"
|
||||
msgstr[1] "{n} modifiche richiedono attenzione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Solo file in cache"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Sincronizzazione in corso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Aggiornato"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive non è in esecuzione"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Non risponde"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive impiega troppo tempo a rispondere"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "più tardi"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "alle %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%e %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Nessun file mantenuto offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr "Fai clic destro su un file e scegli “Rendi disponibile offline”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Impossibile renderlo solo online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Mostra meno"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5244,7 +5319,7 @@ msgstr "Cestino svuotato"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Impossibile svuotare il cestino"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Verifica"
|
||||
|
||||
@@ -5876,40 +5951,45 @@ msgstr[1] "↑ {n} in caricamento"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive non risponde"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Accesso effettuato come {username} — bloccato"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Accesso effettuato come {username} — non connesso"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Accesso non eseguito"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Errore: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive ha inviato una risposta inattesa"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Aggiornato in {mountpoint} ({n} fissato)"
|
||||
msgstr[1] "Aggiornato in {mountpoint} ({n} fissati)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizzazione: {queued} ({n} fissato)"
|
||||
msgstr[1] "Sincronizzazione: {queued} ({n} fissati)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5917,52 +5997,52 @@ msgstr[0] "Offline: solo file in cache ({n} fissato)"
|
||||
msgstr[1] "Offline: solo file in cache ({n} fissati)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline: {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema: visualizza"
|
||||
msgstr[1] "{n} problemi: visualizza"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Accedi…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Apri Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Apri cartella"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Riprendi sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Metti in pausa sincronizzazione"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Connetti"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Nascondi icona nell'area di notifica"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Arresta Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Esci"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Dutch\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A %-d %B %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A %-d %B %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Mijn bestanden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Foto's"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Gedeeld met mij"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Gedeeld door mij"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Computers"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Prullenbak"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Synchronisatie"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Je bent offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Dat bestaat niet meer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Je hebt daar geen toegang toe"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Er is eerst iets anders gewijzigd"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Je Proton Drive is vol"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Voorkeuren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Sneltoetsen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "Over Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Hoofdmenu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -166,23 +166,23 @@ msgstr ""
|
||||
"Onofficiële client — niet gelieerd aan, onderschreven door of ondersteund "
|
||||
"door Proton AG."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Broncode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Servicevoorwaarden van Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Privacybeleid van Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Disclaimer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -205,7 +205,7 @@ msgstr ""
|
||||
"Deze software wordt geleverd “zoals ze is”, zonder enige garantie. Bewaar "
|
||||
"een kopie van gegevens die je niet kwijt wilt raken."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -215,7 +215,7 @@ msgstr ""
|
||||
"\">GeoNames</a>, gelicentieerd onder <a href=\"https://creativecommons.org/"
|
||||
"licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -225,7 +225,7 @@ msgstr ""
|
||||
"href=\"https://www.naturalearthdata.com/\">Natural Earth</a>, die in het "
|
||||
"publieke domein vallen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -241,15 +241,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Bijdragers aan Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Proton Drive stoppen?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -257,7 +257,7 @@ msgstr ""
|
||||
"Mijn bestanden gaat offline en er wordt niets gesynchroniseerd tot je weer "
|
||||
"verbinding maakt. Proton Drive start opnieuw bij je volgende aanmelding."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -272,7 +272,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -287,30 +288,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Stoppen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Kon Proton Drive niet stoppen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "De Proton Drive-service is niet gestopt."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Algemeen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Drive doorzoeken"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -319,38 +320,38 @@ msgstr "Drive doorzoeken"
|
||||
msgid "Refresh"
|
||||
msgstr "Verversen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Sneltoetsen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Bestanden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Nieuwe map"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Bestanden uploaden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Terug / vooruit"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Bovenliggende map"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Raster / lijst"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -359,7 +360,7 @@ msgstr "Raster / lijst"
|
||||
msgid "Rename"
|
||||
msgstr "Hernoemen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -369,73 +370,73 @@ msgstr "Hernoemen"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Naar prullenbak verplaatsen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Selectie wissen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Grotere miniaturen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Kleinere miniaturen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Miniatuurgrootte herstellen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Alles selecteren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Fotoweergave"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Vorige / volgende foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Eerste / laatste foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Details tonen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Volledig scherm"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Sluiten"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Selecteer één item om het te hernoemen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Niet verbonden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "De Proton Drive-service draait niet."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Verbinden…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Wachten tot de Proton Drive-service is gestart."
|
||||
|
||||
@@ -1282,7 +1283,7 @@ msgstr "Kon albums niet laden"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1550,7 +1551,7 @@ msgid "Make available offline"
|
||||
msgstr "Offline beschikbaar maken"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Alleen online maken"
|
||||
|
||||
@@ -2713,7 +2714,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Synchronisatie gepauzeerd totdat je hervat"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Synchronisatie gepauzeerd"
|
||||
|
||||
@@ -3185,26 +3186,37 @@ msgstr "Voer je e-mailadres en wachtwoord in."
|
||||
msgid "Signing in…"
|
||||
msgstr "Aanmelden…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Voltooi de verificatie om verder te gaan…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "aanmelden geannuleerd"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"De verificatiepagina kon niet worden geopend, dus het aanmelden is "
|
||||
"geannuleerd. Mogelijk verhindert je systeem dat de sandbox van de "
|
||||
"webweergave start; de handleiding voor probleemoplossing legt uit wat je "
|
||||
"kunt doen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr ""
|
||||
"Te veel aanmeldpogingen. Wacht een paar minuten en probeer het opnieuw."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Kon Proton niet bereiken. Controleer je internetverbinding en probeer het "
|
||||
"opnieuw."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3213,11 +3225,19 @@ msgstr ""
|
||||
"opgeslagen. Zorg dat een sleutelbos (GNOME Keyring of KWallet) actief en "
|
||||
"ontgrendeld is."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Aanmelden geannuleerd: er is geen tweestapscode ingevoerd."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Aanmelden geannuleerd: er is geen mailboxwachtwoord ingevoerd."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "Dat mailboxwachtwoord heeft je account niet ontgrendeld."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3226,33 +3246,85 @@ msgstr ""
|
||||
"om een nieuwe te krijgen."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Aanmelden mislukt: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"Dat mailboxwachtwoord heeft je account niet ontgrendeld. Probeer het opnieuw."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Dit account heeft een apart mailboxwachtwoord. Voer het in om je bestanden "
|
||||
"te ontgrendelen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Mailboxwachtwoord"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Mailboxwachtwoord"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Ontgrendeld houden op deze computer"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Bewaart de ontgrendeling in de sleutelhanger van het systeem, zodat Proton "
|
||||
"Drive na elke aanmelding opent zonder te vragen. Anders voer je het "
|
||||
"wachtwoord één keer per sessie in."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Ontgrendelen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive is vergrendeld. Voer je mailboxwachtwoord in om het te "
|
||||
"ontgrendelen."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Ontgrendeld."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Ontgrendelen mislukt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Tweestapsverificatie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr "Voer de code uit je authenticator-app in, of een van je herstelcodes."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Verificatiecode"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Bevestigen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Afmelden?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3261,7 +3333,7 @@ msgstr ""
|
||||
"je opnieuw aanmeldt. Bestanden die al op deze computer staan, blijven waar "
|
||||
"ze zijn."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Afmelden"
|
||||
|
||||
@@ -4620,40 +4692,40 @@ msgid "Restart Now"
|
||||
msgstr "Nu opnieuw starten"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} gebruikt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} van {total} gebruikt ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive verbonden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Je bestanden zijn beschikbaar."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Verbinding met Proton Drive verbroken"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"De Proton Drive-service is gestopt. Bestanden zijn pas weer beschikbaar als "
|
||||
"hij opnieuw start."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Synchronisatie voltooid"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4662,27 +4734,27 @@ msgstr[1] "{n} bestanden zijn klaar met overdragen."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} — {done} van {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} — {detail} ({done} van {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} — {detail}…"
|
||||
@@ -4690,7 +4762,7 @@ msgstr "{title} — {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
@@ -4698,117 +4770,117 @@ msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} van {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} in cache — geen limiet ingesteld"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} van {limit} gebruikt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · hervat {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Hervat {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Totdat je hervat"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} wijziging vereist aandacht"
|
||||
msgstr[1] "{n} wijzigingen vereisen aandacht"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Alleen bestanden in cache"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Synchroniseren"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Bijgewerkt"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive draait niet"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Reageert niet"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive doet er te lang over om te antwoorden"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "later"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "om %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%e %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Geen offline bewaarde bestanden"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr "Klik met rechts op een bestand en kies “Offline beschikbaar maken”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Kon het niet alleen online maken"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Minder tonen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5237,7 +5309,7 @@ msgstr "Prullenbak geleegd"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Kon de prullenbak niet legen"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Verificatie"
|
||||
|
||||
@@ -5868,40 +5940,45 @@ msgstr[1] "↑ {n} worden geüpload"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive reageert niet"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Aangemeld als {username} — vergrendeld"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Aangemeld als {username} — niet verbonden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Niet aangemeld"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Fout: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive gaf een onverwacht antwoord"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Bijgewerkt in {mountpoint} ({n} vastgezet)"
|
||||
msgstr[1] "Bijgewerkt in {mountpoint} ({n} vastgezet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Synchroniseren — {queued} ({n} vastgezet)"
|
||||
msgstr[1] "Synchroniseren — {queued} ({n} vastgezet)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5909,52 +5986,52 @@ msgstr[0] "Offline — alleen bestanden in cache ({n} vastgezet)"
|
||||
msgstr[1] "Offline — alleen bestanden in cache ({n} vastgezet)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} probleem — Bekijken"
|
||||
msgstr[1] "{n} problemen — Bekijken"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Aanmelden…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Proton Drive openen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Map openen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Synchronisatie hervatten"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Synchronisatie pauzeren"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Verbinden"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Pictogram in systeemvak verbergen"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Proton Drive stoppen…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Afsluiten"
|
||||
|
||||
|
||||
+207
-142
@@ -6,9 +6,9 @@
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.10.0\n"
|
||||
"Project-Id-Version: proton-drive-linux 3.1.1\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -60,7 +60,7 @@ msgstr ""
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -73,91 +73,91 @@ msgstr ""
|
||||
msgid "My files"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -165,23 +165,23 @@ msgid ""
|
||||
"AG."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -194,21 +194,21 @@ msgid ""
|
||||
"of any data you cannot afford to lose."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
"licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
"public domain."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -219,21 +219,21 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -248,7 +248,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -263,30 +264,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -295,38 +296,38 @@ msgstr ""
|
||||
msgid "Refresh"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -335,7 +336,7 @@ msgstr ""
|
||||
msgid "Rename"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -345,73 +346,73 @@ msgstr ""
|
||||
msgid "Move to Trash"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr ""
|
||||
|
||||
@@ -1240,7 +1241,7 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1508,7 +1509,7 @@ msgid "Make available offline"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr ""
|
||||
|
||||
@@ -2616,7 +2617,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr ""
|
||||
|
||||
@@ -3052,72 +3053,131 @@ msgstr ""
|
||||
msgid "Signing in…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr ""
|
||||
|
||||
@@ -4433,38 +4493,38 @@ msgid "Restart Now"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4473,27 +4533,27 @@ msgstr[1] ""
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr ""
|
||||
@@ -4501,7 +4561,7 @@ msgstr ""
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr ""
|
||||
@@ -4509,117 +4569,117 @@ msgstr ""
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5023,7 +5083,7 @@ msgstr ""
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr ""
|
||||
|
||||
@@ -5644,40 +5704,45 @@ msgstr[1] ""
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5685,52 +5750,52 @@ msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr ""
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Polish\n"
|
||||
@@ -59,7 +59,7 @@ msgstr "%-d %b %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A, %-d %B %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -72,91 +72,91 @@ msgstr "%A, %-d %B %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Moje pliki"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Zdjęcia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Udostępnione mi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Udostępnione przeze mnie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Komputery"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Kosz"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Synchronizacja"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Brak połączenia z siecią"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Ten element już nie istnieje"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Brak dostępu do tego elementu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Coś zmieniło ten element wcześniej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Proton Drive jest pełny"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencje"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Skróty klawiszowe"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "O programie Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Menu główne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -168,23 +168,23 @@ msgstr ""
|
||||
"Nieoficjalny klient — niepowiązany z Proton AG, niepopierany ani "
|
||||
"niewspierany przez tę firmę."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Kod źródłowy"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Warunki korzystania z usług Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Polityka prywatności Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Zastrzeżenia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -208,7 +208,7 @@ msgstr ""
|
||||
"gwarancji. Zachowaj kopię danych, na których utratę nie możesz sobie "
|
||||
"pozwolić."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -218,7 +218,7 @@ msgstr ""
|
||||
"\">GeoNames</a> udostępnionych na licencji <a href=\"https://"
|
||||
"creativecommons.org/licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -228,7 +228,7 @@ msgstr ""
|
||||
"www.naturalearthdata.com/\">Natural Earth</a>, które należą do domeny "
|
||||
"publicznej."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -244,15 +244,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Współtwórcy programu Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Zatrzymać Proton Drive?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -261,7 +261,7 @@ msgstr ""
|
||||
"ponownego połączenia. Proton Drive uruchomi się ponownie przy następnym "
|
||||
"logowaniu."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -276,7 +276,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -291,30 +292,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Anuluj"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Zatrzymaj"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Nie można zatrzymać Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "Usługa Proton Drive nie zatrzymała się."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Ogólne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Przeszukaj Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -323,38 +324,38 @@ msgstr "Przeszukaj Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Odśwież"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Skróty klawiszowe"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Pliki"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Nowy katalog"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Wyślij pliki"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Wstecz/dalej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Katalog nadrzędny"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Siatka/lista"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -363,7 +364,7 @@ msgstr "Siatka/lista"
|
||||
msgid "Rename"
|
||||
msgstr "Zmień nazwę"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -373,73 +374,73 @@ msgstr "Zmień nazwę"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Przenieś do kosza"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Wyczyść zaznaczenie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Większe miniatury"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Mniejsze miniatury"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Przywróć rozmiar miniatur"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Zaznacz wszystko"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Przeglądarka zdjęć"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Poprzednie/następne zdjęcie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Pierwsze/ostatnie zdjęcie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Wyświetl szczegóły"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Pełny ekran"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Zamknij"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Należy zaznaczyć jeden element, aby zmienić jego nazwę"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Brak połączenia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "Usługa Proton Drive nie jest uruchomiona."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Łączenie…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Oczekiwanie na uruchomienie usługi Proton Drive."
|
||||
|
||||
@@ -1313,7 +1314,7 @@ msgstr "Nie można wczytać albumów"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1586,7 +1587,7 @@ msgid "Make available offline"
|
||||
msgstr "Oznacz jako dostępne offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Oznacz jako tylko online"
|
||||
|
||||
@@ -2770,7 +2771,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Wstrzymano synchronizację do czasu wznowienia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Wstrzymano synchronizację"
|
||||
|
||||
@@ -3242,26 +3243,36 @@ msgstr "Proszę podać adres e-mail i hasło."
|
||||
msgid "Signing in…"
|
||||
msgstr "Logowanie…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Proszę ukończyć weryfikację, aby kontynuować…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "anulowano logowanie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"Nie można otworzyć strony weryfikacji, więc logowanie zostało anulowane. "
|
||||
"System może blokować uruchomienie piaskownicy widoku internetowego; poradnik "
|
||||
"rozwiązywania problemów wyjaśnia, co zrobić."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr ""
|
||||
"Za dużo prób logowania. Proszę odczekać kilka minut i spróbować ponownie."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Nie można połączyć się z Proton. Proszę sprawdzić połączenie z Internetem i "
|
||||
"spróbować ponownie."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3270,11 +3281,19 @@ msgstr ""
|
||||
"upewnić, że baza kluczy (GNOME Keyring lub KWallet) jest uruchomiona i "
|
||||
"odblokowana."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Anulowano logowanie: nie wpisano kodu uwierzytelniania dwuetapowego."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Anulowano logowanie: nie wpisano hasła skrzynki pocztowej."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "To hasło skrzynki pocztowej nie odblokowało Twojego konta."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3283,35 +3302,87 @@ msgstr ""
|
||||
"ponownie, aby otrzymać nową."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Logowanie się nie powiodło: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"To hasło skrzynki pocztowej nie odblokowało Twojego konta. Spróbuj ponownie."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"To konto ma osobne hasło skrzynki pocztowej. Wpisz je, aby odblokować swoje "
|
||||
"pliki."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Hasło skrzynki pocztowej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Hasło skrzynki pocztowej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Pozostaw odblokowane na tym komputerze"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Zapisuje odblokowanie w systemowym breloku kluczy, aby Proton Drive otwierał "
|
||||
"się bez pytania po każdym logowaniu. W przeciwnym razie wpisujesz hasło raz "
|
||||
"na sesję."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Odblokuj"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"Proton Drive jest zablokowany. Wpisz hasło skrzynki pocztowej, aby go "
|
||||
"odblokować."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Odblokowano."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Nie udało się odblokować"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Uwierzytelnianie dwuskładnikowe"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Proszę wpisać kod z aplikacji uwierzytelniającej lub jeden z kodów "
|
||||
"odzyskiwania."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Kod uwierzytelniania"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Potwierdź"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Wylogować się?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3319,7 +3390,7 @@ msgstr ""
|
||||
"Proton Drive rozłączy się i przestanie synchronizować do czasu ponownego "
|
||||
"zalogowania. Pliki znajdujące się już na tym komputerze pozostaną na miejscu."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Wyloguj się"
|
||||
|
||||
@@ -4689,40 +4760,40 @@ msgid "Restart Now"
|
||||
msgstr "Uruchom ponownie teraz"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "Użyto {size}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "Użyto {used} z {total} ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Połączono z Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Twoje pliki są dostępne."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Rozłączono z Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"Usługa Proton Drive zatrzymała się. Pliki będą niedostępne do jej ponownego "
|
||||
"uruchomienia."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Ukończono synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4732,27 +4803,27 @@ msgstr[2] "Ukończono przesyłanie {n} plików."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} — {done} z {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} — {detail} ({done} z {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} — {detail}…"
|
||||
@@ -4760,7 +4831,7 @@ msgstr "{title} — {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
@@ -4768,38 +4839,38 @@ msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} z {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} w pamięci podręcznej — bez limitu"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "Użyto {used} z {limit}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · wznowienie {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Wznowienie {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Do czasu wznowienia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
@@ -4807,81 +4878,81 @@ msgstr[0] "{n} zmiana wymaga uwagi"
|
||||
msgstr[1] "{n} zmiany wymagają uwagi"
|
||||
msgstr[2] "{n} zmian wymaga uwagi"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Tylko pliki w pamięci podręcznej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Synchronizowanie"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Aktualne"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "Proton Drive nie jest uruchomiony"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Nie odpowiada"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "Proton Drive zbyt długo nie odpowiada"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "później"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "o %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "%-d %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Brak plików dostępnych offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
"Należy kliknąć plik prawym przyciskiem myszy i wybrać „Oznacz jako dostępne "
|
||||
"offline”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Nie można oznaczyć jako tylko online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Wyświetl mniej"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5320,7 +5391,7 @@ msgstr "Opróżniono kosz"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Nie można opróżnić kosza"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Weryfikacja"
|
||||
|
||||
@@ -5959,26 +6030,31 @@ msgstr[2] "↑ wysyłanie: {n}"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "Proton Drive nie odpowiada"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Zalogowano jako {username} — zablokowane"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Zalogowano jako {username} — brak połączenia"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Nie zalogowano"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Błąd: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "Proton Drive wysłał nieoczekiwaną odpowiedź"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
@@ -5986,7 +6062,7 @@ msgstr[0] "Aktualne w {mountpoint} ({n} przypięty)"
|
||||
msgstr[1] "Aktualne w {mountpoint} ({n} przypięte)"
|
||||
msgstr[2] "Aktualne w {mountpoint} ({n} przypiętych)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
@@ -5994,7 +6070,7 @@ msgstr[0] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
msgstr[1] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
msgstr[2] "Synchronizowanie — {queued} (przypięte: {n})"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -6003,13 +6079,13 @@ msgstr[1] "Offline — tylko pliki w pamięci podręcznej (przypięte: {n})"
|
||||
msgstr[2] "Offline — tylko pliki w pamięci podręcznej (przypięte: {n})"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
@@ -6017,39 +6093,39 @@ msgstr[0] "{n} problem — wyświetl"
|
||||
msgstr[1] "{n} problemy — wyświetl"
|
||||
msgstr[2] "{n} problemów — wyświetl"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Zaloguj się…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Otwórz Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Otwórz katalog"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Wznów synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Wstrzymaj synchronizację"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Połącz"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ukryj ikonę w obszarze powiadamiania"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Zatrzymaj Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Zakończ"
|
||||
|
||||
|
||||
+217
-141
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: proton-drive-linux 2.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n"
|
||||
"POT-Creation-Date: 2026-10-05 01:01+0200\n"
|
||||
"POT-Creation-Date: 2026-10-08 10:15+0200\n"
|
||||
"PO-Revision-Date: 2026-09-23 12:00+0200\n"
|
||||
"Last-Translator: Proton Drive for Linux contributors\n"
|
||||
"Language-Team: Portuguese (Brazil)\n"
|
||||
@@ -57,7 +57,7 @@ msgstr "%-d de %b de %Y"
|
||||
msgid "%A, %B %-d, %Y, %H:%M"
|
||||
msgstr "%A, %-d de %B de %Y, %H:%M"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:743
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/pages/activity_text.rs:539
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:454
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:819
|
||||
@@ -70,91 +70,91 @@ msgstr "%A, %-d de %B de %Y, %H:%M"
|
||||
msgid "My files"
|
||||
msgstr "Meus arquivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:746 crates/pdfs-gui/src/app/main.rs:1390
|
||||
#: crates/pdfs-gui/src/app/main.rs:763 crates/pdfs-gui/src/app/main.rs:1407
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:638
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:842
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:441
|
||||
msgid "Photos"
|
||||
msgstr "Fotos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:751
|
||||
#: crates/pdfs-gui/src/app/main.rs:768
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:168
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:482
|
||||
msgid "Shared with me"
|
||||
msgstr "Compartilhados comigo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:756
|
||||
#: crates/pdfs-gui/src/app/main.rs:773
|
||||
#: crates/pdfs-gui/src/app/pages/shared_by_me.rs:120
|
||||
msgid "Shared by me"
|
||||
msgstr "Compartilhados por mim"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:759
|
||||
#: crates/pdfs-gui/src/app/main.rs:776
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:140
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:481
|
||||
msgid "Computers"
|
||||
msgstr "Computadores"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:760
|
||||
#: crates/pdfs-gui/src/app/main.rs:777
|
||||
#: crates/pdfs-gui/src/app/pages/trash.rs:101
|
||||
msgid "Trash"
|
||||
msgstr "Lixeira"
|
||||
|
||||
#. Translators: sidebar entry for the page listing this computer's synced folders.
|
||||
#: crates/pdfs-gui/src/app/main.rs:762
|
||||
#: crates/pdfs-gui/src/app/main.rs:779
|
||||
msgid "Sync"
|
||||
msgstr "Sincronização"
|
||||
|
||||
#. Translators: a failed action's toast. {what} says what failed, such as
|
||||
#. "Couldn't rename"; {detail} is the reason, usually untranslated text
|
||||
#. from the mount service.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1079
|
||||
#: crates/pdfs-gui/src/app/main.rs:1096
|
||||
#, rust-format
|
||||
msgid "{what}: {detail}"
|
||||
msgstr "{what}: {detail}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1098
|
||||
#: crates/pdfs-gui/src/app/main.rs:1115
|
||||
msgid "You're offline"
|
||||
msgstr "Você está offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1099
|
||||
#: crates/pdfs-gui/src/app/main.rs:1116
|
||||
msgid "That's not there any more"
|
||||
msgstr "Isso não existe mais"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1100
|
||||
#: crates/pdfs-gui/src/app/main.rs:1117
|
||||
msgid "You don't have access to that"
|
||||
msgstr "Você não tem acesso a isso"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1101
|
||||
#: crates/pdfs-gui/src/app/main.rs:1118
|
||||
msgid "Something changed this first"
|
||||
msgstr "Algo alterou isso antes"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1102
|
||||
#: crates/pdfs-gui/src/app/main.rs:1119
|
||||
msgid "Your Proton Drive is full"
|
||||
msgstr "Seu Proton Drive está cheio"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1143 crates/pdfs-gui/src/app/main.rs:1372
|
||||
#: crates/pdfs-gui/src/app/main.rs:1160 crates/pdfs-gui/src/app/main.rs:1389
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:385
|
||||
msgid "Preferences"
|
||||
msgstr "Preferências"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1144
|
||||
#: crates/pdfs-gui/src/app/main.rs:1161
|
||||
#: crates/pdfs-gui/src/app/widgets/compat.rs:262
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr "Atalhos de teclado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1146
|
||||
#: crates/pdfs-gui/src/app/main.rs:1163
|
||||
msgid "About Proton Drive for Linux"
|
||||
msgstr "Sobre o Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1151
|
||||
#: crates/pdfs-gui/src/app/main.rs:1168
|
||||
msgid "Main menu"
|
||||
msgstr "Menu principal"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1207
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
msgid "Proton Drive for Linux"
|
||||
msgstr "Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1215
|
||||
#: crates/pdfs-gui/src/app/main.rs:1232
|
||||
msgid ""
|
||||
"Files-on-demand Proton Drive for the Linux desktop.\n"
|
||||
"\n"
|
||||
@@ -165,23 +165,23 @@ msgstr ""
|
||||
"\n"
|
||||
"Cliente não oficial — sem afiliação, endosso ou suporte da Proton AG."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1220
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
msgid "Source Code"
|
||||
msgstr "Código-fonte"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1224
|
||||
#: crates/pdfs-gui/src/app/main.rs:1241
|
||||
msgid "Proton Terms of Service"
|
||||
msgstr "Termos de Serviço da Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1228
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
msgid "Proton Privacy Policy"
|
||||
msgstr "Política de Privacidade da Proton"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1233
|
||||
#: crates/pdfs-gui/src/app/main.rs:1250
|
||||
msgid "Disclaimer"
|
||||
msgstr "Aviso legal"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1237
|
||||
#: crates/pdfs-gui/src/app/main.rs:1254
|
||||
msgid ""
|
||||
"This is an unofficial, community-built client. It is not affiliated with, "
|
||||
"endorsed by, or supported by Proton AG.\n"
|
||||
@@ -204,7 +204,7 @@ msgstr ""
|
||||
"Este software é fornecido “no estado em que se encontra”, sem garantia de "
|
||||
"qualquer tipo. Mantenha uma cópia de todos os dados que você não pode perder."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1245
|
||||
#: crates/pdfs-gui/src/app/main.rs:1262
|
||||
msgid ""
|
||||
"Places are named with data from <a href=\"https://www.geonames.org/"
|
||||
"\">GeoNames</a>, licensed under <a href=\"https://creativecommons.org/"
|
||||
@@ -214,7 +214,7 @@ msgstr ""
|
||||
"\">GeoNames</a>, licenciados sob <a href=\"https://creativecommons.org/"
|
||||
"licenses/by/4.0/\">CC BY 4.0</a>."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1253
|
||||
#: crates/pdfs-gui/src/app/main.rs:1270
|
||||
msgid ""
|
||||
"The places map is drawn from <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a> land outlines and country borders, which are in the "
|
||||
@@ -224,7 +224,7 @@ msgstr ""
|
||||
"fronteiras de países do <a href=\"https://www.naturalearthdata.com/"
|
||||
"\">Natural Earth</a>, que são de domínio público."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1261
|
||||
#: crates/pdfs-gui/src/app/main.rs:1278
|
||||
msgid ""
|
||||
"The street map, when turned on, comes from <a href=\"https://openfreemap.org/"
|
||||
"\">OpenFreeMap</a> in the <a href=\"https://www.openmaptiles.org/"
|
||||
@@ -240,15 +240,15 @@ msgstr ""
|
||||
|
||||
#. Translators: replace with your name(s) and email address(es), one
|
||||
#. per line, to be credited in the About dialog.
|
||||
#: crates/pdfs-gui/src/app/main.rs:1272
|
||||
#: crates/pdfs-gui/src/app/main.rs:1289
|
||||
msgid "translator-credits"
|
||||
msgstr "Colaboradores do Proton Drive for Linux"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1310
|
||||
#: crates/pdfs-gui/src/app/main.rs:1327
|
||||
msgid "Stop Proton Drive?"
|
||||
msgstr "Parar o Proton Drive?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1311
|
||||
#: crates/pdfs-gui/src/app/main.rs:1328
|
||||
msgid ""
|
||||
"My files goes offline and nothing syncs until you connect again. Proton "
|
||||
"Drive starts again at your next login."
|
||||
@@ -256,7 +256,7 @@ msgstr ""
|
||||
"Meus arquivos fica offline e nada é sincronizado até você se conectar "
|
||||
"novamente. O Proton Drive será iniciado de novo no seu próximo login."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1313 crates/pdfs-gui/src/app/main.rs:1588
|
||||
#: crates/pdfs-gui/src/app/main.rs:1330 crates/pdfs-gui/src/app/main.rs:1605
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:243
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:428
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1892
|
||||
@@ -271,7 +271,8 @@ msgstr ""
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1013
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1488
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:1538
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:312
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:393
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:507
|
||||
#: crates/pdfs-gui/src/app/pages/photos.rs:2055
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:946
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1027
|
||||
@@ -286,30 +287,30 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1314
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
msgctxt "verb"
|
||||
msgid "Stop"
|
||||
msgstr "Parar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1331
|
||||
#: crates/pdfs-gui/src/app/main.rs:1348
|
||||
msgid "Couldn't stop Proton Drive"
|
||||
msgstr "Não foi possível parar o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1332
|
||||
#: crates/pdfs-gui/src/app/main.rs:1349
|
||||
msgid "The Proton Drive service did not stop."
|
||||
msgstr "O serviço do Proton Drive não parou."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1368
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:254
|
||||
msgid "General"
|
||||
msgstr "Geral"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1370
|
||||
#: crates/pdfs-gui/src/app/main.rs:1387
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:247
|
||||
msgid "Search Drive"
|
||||
msgstr "Pesquisar no Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1371
|
||||
#: crates/pdfs-gui/src/app/main.rs:1388
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:957
|
||||
#: crates/pdfs-gui/src/app/pages/devices.rs:554
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:586
|
||||
@@ -318,38 +319,38 @@ msgstr "Pesquisar no Drive"
|
||||
msgid "Refresh"
|
||||
msgstr "Atualizar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1373
|
||||
#: crates/pdfs-gui/src/app/main.rs:1390
|
||||
msgid "Keyboard shortcuts"
|
||||
msgstr "Atalhos de teclado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1377
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
msgid "Files"
|
||||
msgstr "Arquivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1379
|
||||
#: crates/pdfs-gui/src/app/main.rs:1396
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:294
|
||||
msgid "New folder"
|
||||
msgstr "Nova pasta"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1380
|
||||
#: crates/pdfs-gui/src/app/main.rs:1397
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:290
|
||||
msgid "Upload files"
|
||||
msgstr "Enviar arquivos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1381
|
||||
#: crates/pdfs-gui/src/app/main.rs:1398
|
||||
msgid "Back / forward"
|
||||
msgstr "Voltar / avançar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1382
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1943
|
||||
msgid "Parent folder"
|
||||
msgstr "Pasta superior"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1383
|
||||
#: crates/pdfs-gui/src/app/main.rs:1400
|
||||
msgid "Grid / list"
|
||||
msgstr "Grade / lista"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1384
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1871
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:1893
|
||||
@@ -358,7 +359,7 @@ msgstr "Grade / lista"
|
||||
msgid "Rename"
|
||||
msgstr "Renomear"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1385 crates/pdfs-gui/src/app/main.rs:1405
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402 crates/pdfs-gui/src/app/main.rs:1422
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:357
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:900
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:932
|
||||
@@ -368,73 +369,73 @@ msgstr "Renomear"
|
||||
msgid "Move to Trash"
|
||||
msgstr "Mover para a lixeira"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1386
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
msgid "Clear the selection"
|
||||
msgstr "Limpar a seleção"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1392
|
||||
#: crates/pdfs-gui/src/app/main.rs:1409
|
||||
msgid "Larger thumbnails"
|
||||
msgstr "Miniaturas maiores"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1393
|
||||
#: crates/pdfs-gui/src/app/main.rs:1410
|
||||
msgid "Smaller thumbnails"
|
||||
msgstr "Miniaturas menores"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1394
|
||||
#: crates/pdfs-gui/src/app/main.rs:1411
|
||||
msgid "Reset thumbnail size"
|
||||
msgstr "Redefinir tamanho das miniaturas"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1395
|
||||
#: crates/pdfs-gui/src/app/main.rs:1412
|
||||
msgid "Select all"
|
||||
msgstr "Selecionar tudo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1399
|
||||
#: crates/pdfs-gui/src/app/main.rs:1416
|
||||
msgid "Photo Viewer"
|
||||
msgstr "Visualizador de fotos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1401
|
||||
#: crates/pdfs-gui/src/app/main.rs:1418
|
||||
msgid "Previous / next photo"
|
||||
msgstr "Foto anterior / próxima"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1402
|
||||
#: crates/pdfs-gui/src/app/main.rs:1419
|
||||
msgid "First / last photo"
|
||||
msgstr "Primeira / última foto"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1403
|
||||
#: crates/pdfs-gui/src/app/main.rs:1420
|
||||
msgid "Show details"
|
||||
msgstr "Mostrar detalhes"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1404
|
||||
#: crates/pdfs-gui/src/app/main.rs:1421
|
||||
msgid "Fullscreen"
|
||||
msgstr "Tela cheia"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1406
|
||||
#: crates/pdfs-gui/src/app/main.rs:1423
|
||||
msgid "Close"
|
||||
msgstr "Fechar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1496
|
||||
#: crates/pdfs-gui/src/app/main.rs:1513
|
||||
msgid "Select a single item to rename it"
|
||||
msgstr "Selecione um único item para renomeá-lo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1656
|
||||
#: crates/pdfs-gui/src/app/main.rs:1673
|
||||
#: crates/pdfs-gui/src/app/pages/albums.rs:85
|
||||
#: crates/pdfs-gui/src/app/pages/places.rs:104
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1370
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
msgid "Not connected"
|
||||
msgstr "Não conectado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1657
|
||||
#: crates/pdfs-gui/src/app/main.rs:1674
|
||||
msgid "The Proton Drive service isn't running."
|
||||
msgstr "O serviço do Proton Drive não está em execução."
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1665
|
||||
#: crates/pdfs-gui/src/app/main.rs:1682
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:336
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:274 crates/pdfs-gui/src/hud/mod.rs:595
|
||||
#: crates/pdfs-gui/src/main.rs:444
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
msgid "Connecting…"
|
||||
msgstr "Conectando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/main.rs:1666
|
||||
#: crates/pdfs-gui/src/app/main.rs:1683
|
||||
msgid "Waiting for the Proton Drive service to start."
|
||||
msgstr "Aguardando o serviço do Proton Drive iniciar."
|
||||
|
||||
@@ -1283,7 +1284,7 @@ msgstr "Não foi possível carregar os álbuns"
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1006
|
||||
#: crates/pdfs-gui/src/app/pages/shared.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:750
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1518
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:424
|
||||
#: crates/pdfs-gui/src/app/pages/takeout.rs:617
|
||||
#: crates/pdfs-gui/src/app/widgets/share_dialog.rs:438
|
||||
@@ -1551,7 +1552,7 @@ msgid "Make available offline"
|
||||
msgstr "Disponibilizar offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/browser.rs:347
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1493
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1494
|
||||
msgid "Make online only"
|
||||
msgstr "Tornar somente online"
|
||||
|
||||
@@ -2708,7 +2709,7 @@ msgid "Sync paused until you resume"
|
||||
msgstr "Sincronização pausada até você retomar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/locations.rs:529
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1323 crates/pdfs-gui/src/main.rs:237
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1324 crates/pdfs-gui/src/main.rs:246
|
||||
msgid "Sync paused"
|
||||
msgstr "Sincronização pausada"
|
||||
|
||||
@@ -3177,25 +3178,35 @@ msgstr "Digite seu e-mail e senha."
|
||||
msgid "Signing in…"
|
||||
msgstr "Entrando…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:155
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:164
|
||||
msgid "Complete the verification to continue…"
|
||||
msgstr "Conclua a verificação para continuar…"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:165
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:197
|
||||
msgid "login cancelled"
|
||||
msgstr "login cancelado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:198
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
msgid ""
|
||||
"The verification page couldn't be opened, so the sign-in was cancelled. Your "
|
||||
"system may keep the web view's sandbox from starting; the troubleshooting "
|
||||
"guide explains what to do."
|
||||
msgstr ""
|
||||
"Não foi possível abrir a página de verificação, então a entrada foi "
|
||||
"cancelada. Seu sistema pode estar impedindo que a sandbox da visualização "
|
||||
"web inicie; o guia de solução de problemas explica o que fazer."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:233
|
||||
msgid "Too many sign-in attempts. Wait a few minutes and try again."
|
||||
msgstr "Muitas tentativas de entrar. Aguarde alguns minutos e tente novamente."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:204
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:239
|
||||
msgid "Couldn't reach Proton. Check your internet connection and try again."
|
||||
msgstr ""
|
||||
"Não foi possível acessar o Proton. Verifique sua conexão com a internet e "
|
||||
"tente novamente."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:207
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:242
|
||||
msgid ""
|
||||
"Signed in, but the session couldn't be saved to the system keyring. Make "
|
||||
"sure a keyring (GNOME Keyring or KWallet) is running and unlocked."
|
||||
@@ -3204,11 +3215,19 @@ msgstr ""
|
||||
"Certifique-se de que um chaveiro (GNOME Keyring ou KWallet) esteja em "
|
||||
"execução e desbloqueado."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:210
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:245
|
||||
msgid "Sign-in cancelled: no two-factor code was entered."
|
||||
msgstr "Entrada cancelada: nenhum código de dois fatores foi digitado."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:213
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:248
|
||||
msgid "Sign-in cancelled: no mailbox password was entered."
|
||||
msgstr "Entrada cancelada: nenhuma senha da caixa de correio foi digitada."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:251
|
||||
msgid "That mailbox password didn't unlock your account."
|
||||
msgstr "Essa senha da caixa de correio não desbloqueou sua conta."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:254
|
||||
msgid ""
|
||||
"Sign-in cancelled: the verification wasn't completed. Sign in again to get a "
|
||||
"new one."
|
||||
@@ -3217,35 +3236,87 @@ msgstr ""
|
||||
"receber uma nova."
|
||||
|
||||
#. Translators: {error} is an error message, usually in English.
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:218
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:259
|
||||
#, rust-format
|
||||
msgid "Sign-in failed: {error}"
|
||||
msgstr "Falha ao entrar: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:298
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:369
|
||||
msgid "That mailbox password didn't unlock your account. Try again."
|
||||
msgstr ""
|
||||
"Essa senha da caixa de correio não desbloqueou sua conta. Tente novamente."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:371
|
||||
msgid ""
|
||||
"This account has a separate mailbox password. Enter it to unlock your files."
|
||||
msgstr ""
|
||||
"Esta conta tem uma senha da caixa de correio separada. Digite-a para "
|
||||
"desbloquear seus arquivos."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:374
|
||||
msgid "Mailbox Password"
|
||||
msgstr "Senha da caixa de correio"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:380
|
||||
msgid "Mailbox password"
|
||||
msgstr "Senha da caixa de correio"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:384
|
||||
msgid "Keep unlocked on this computer"
|
||||
msgstr "Manter desbloqueado neste computador"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:386
|
||||
msgid ""
|
||||
"Stores the unlock in the system keyring, so Proton Drive opens without "
|
||||
"asking after every login. Otherwise you enter the password once per session."
|
||||
msgstr ""
|
||||
"Guarda o desbloqueio no chaveiro do sistema, para que o Proton Drive abra "
|
||||
"sem perguntar após cada login. Caso contrário, você digita a senha uma vez "
|
||||
"por sessão."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:394
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:447
|
||||
msgid "Unlock"
|
||||
msgstr "Desbloquear"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:446
|
||||
msgid "Proton Drive is locked. Enter your mailbox password to unlock it."
|
||||
msgstr ""
|
||||
"O Proton Drive está bloqueado. Digite a senha da caixa de correio para "
|
||||
"desbloqueá-lo."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:475
|
||||
msgid "Unlocked."
|
||||
msgstr "Desbloqueado."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:480
|
||||
msgid "Couldn't unlock"
|
||||
msgstr "Não foi possível desbloquear"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:493
|
||||
msgid "Two-Factor Authentication"
|
||||
msgstr "Autenticação de dois fatores"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:300
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:495
|
||||
msgid ""
|
||||
"Enter the code from your authenticator app, or one of your recovery codes."
|
||||
msgstr ""
|
||||
"Digite o código do seu aplicativo autenticador ou um dos seus códigos de "
|
||||
"recuperação."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:306
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:501
|
||||
msgid "Authentication code"
|
||||
msgstr "Código de autenticação"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:313
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:508
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:341
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:536
|
||||
msgid "Sign Out?"
|
||||
msgstr "Sair?"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:343
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:538
|
||||
msgid ""
|
||||
"Proton Drive will disconnect and stop syncing until you sign in again. Files "
|
||||
"already on this computer stay where they are."
|
||||
@@ -3253,7 +3324,7 @@ msgstr ""
|
||||
"O Proton Drive será desconectado e deixará de sincronizar até você entrar "
|
||||
"novamente. Os arquivos que já estão neste computador permanecem onde estão."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:345
|
||||
#: crates/pdfs-gui/src/app/pages/login.rs:540
|
||||
msgid "Sign Out"
|
||||
msgstr "Sair"
|
||||
|
||||
@@ -4604,40 +4675,40 @@ msgid "Restart Now"
|
||||
msgstr "Reiniciar agora"
|
||||
|
||||
#. Translators: {size} is an amount of storage, such as "1.2 GiB".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:912
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:913
|
||||
#, rust-format
|
||||
msgid "{size} used"
|
||||
msgstr "{size} usados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:923
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:924
|
||||
#, rust-format
|
||||
msgid "{used} of {total} used ({percent}%)"
|
||||
msgstr "{used} de {total} usados ({percent}%)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:961
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
msgid "Proton Drive connected"
|
||||
msgstr "Proton Drive conectado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:962
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:963
|
||||
msgid "Your files are available."
|
||||
msgstr "Seus arquivos estão disponíveis."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:967
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
msgid "Proton Drive disconnected"
|
||||
msgstr "Proton Drive desconectado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:968
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:969
|
||||
msgid ""
|
||||
"The Proton Drive service stopped. Files aren't available until it restarts."
|
||||
msgstr ""
|
||||
"O serviço do Proton Drive parou. Os arquivos ficarão indisponíveis até ele "
|
||||
"reiniciar."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1037
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1038
|
||||
msgid "Sync complete"
|
||||
msgstr "Sincronização concluída"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1039
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1040
|
||||
#, rust-format
|
||||
msgid "{n} file finished transferring."
|
||||
msgid_plural "{n} files finished transferring."
|
||||
@@ -4646,27 +4717,27 @@ msgstr[1] "{n} arquivos terminaram de ser transferidos."
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, such as
|
||||
#. "Scanning Photos"; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1117
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1118
|
||||
#, rust-format
|
||||
msgid "{title} — {done} of {total}"
|
||||
msgstr "{title} — {done} de {total}"
|
||||
|
||||
#. Translators: a background job's progress. {title} is the job, {detail}
|
||||
#. what it is working on; {done} and {total} are counts.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1120
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1121
|
||||
#, rust-format
|
||||
msgid "{title} — {detail} ({done} of {total})"
|
||||
msgstr "{title} — {detail} ({done} de {total})"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1122
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1123
|
||||
#, rust-format
|
||||
msgid "{title}…"
|
||||
msgstr "{title}…"
|
||||
|
||||
#. Translators: a background job still running. {title} is the job,
|
||||
#. {detail} what it is working on.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1125
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1126
|
||||
#, rust-format
|
||||
msgid "{title} — {detail}…"
|
||||
msgstr "{title} — {detail}…"
|
||||
@@ -4674,7 +4745,7 @@ msgstr "{title} — {detail}…"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} the size moved so far and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1154
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1155
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
@@ -4682,118 +4753,118 @@ msgstr "{arrow} {name} — {done} ({speed}/s)"
|
||||
#. Translators: a file being transferred. {arrow} is ↑ or ↓, {name} the
|
||||
#. file name, {done} and {total} sizes and {speed} a size such as
|
||||
#. "1.2 MiB"; "/s" means per second.
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1162
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1163
|
||||
#, rust-format
|
||||
msgid "{arrow} {name} — {done} of {total} ({speed}/s)"
|
||||
msgstr "{arrow} {name} — {done} de {total} ({speed}/s)"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1254
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1255
|
||||
#, rust-format
|
||||
msgid "{used} cached — no limit set"
|
||||
msgstr "{used} em cache — sem limite definido"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1260
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1261
|
||||
#, rust-format
|
||||
msgid "{used} of {limit} used"
|
||||
msgstr "{used} de {limit} usados"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1328
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1329
|
||||
#, rust-format
|
||||
msgid "{queued} · resumes {time}"
|
||||
msgstr "{queued} · retoma {time}"
|
||||
|
||||
#. Translators: {time} is when syncing resumes, such as "at 14:30"
|
||||
#. or "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1333
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1334
|
||||
#, rust-format
|
||||
msgid "Resumes {time}"
|
||||
msgstr "Retoma {time}"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1335
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1336
|
||||
msgid "Until you resume"
|
||||
msgstr "Até você retomar"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1342 crates/pdfs-gui/src/main.rs:239
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1343 crates/pdfs-gui/src/main.rs:248
|
||||
#, rust-format
|
||||
msgid "{n} change needs attention"
|
||||
msgid_plural "{n} changes need attention"
|
||||
msgstr[0] "{n} alteração requer atenção"
|
||||
msgstr[1] "{n} alterações requerem atenção"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1352
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/widgets/details.rs:108
|
||||
msgctxt "state"
|
||||
msgid "Offline"
|
||||
msgstr "Offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1353
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1354
|
||||
msgid "Cached files only"
|
||||
msgstr "Somente arquivos em cache"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1358
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1359
|
||||
msgctxt "state"
|
||||
msgid "Syncing"
|
||||
msgstr "Sincronizando"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1364
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1365
|
||||
msgid "Up to date"
|
||||
msgstr "Atualizado"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1371
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1372
|
||||
#: crates/pdfs-gui/src/hud/mod.rs:608 crates/pdfs-gui/src/hud/mod.rs:622
|
||||
msgid "Proton Drive isn't running"
|
||||
msgstr "O Proton Drive não está em execução"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1376
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
msgid "Not responding"
|
||||
msgstr "Não está respondendo"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1377
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1378
|
||||
msgid "Proton Drive is taking too long to answer"
|
||||
msgstr "O Proton Drive está demorando demais para responder"
|
||||
|
||||
#. Translators: stands in for a time that could not be read, as in
|
||||
#. "Resumes later".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1415
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1430
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1416
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1431
|
||||
msgid "later"
|
||||
msgstr "mais tarde"
|
||||
|
||||
#. Translators: strftime format for a time later today, such as "at 14:30".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1419
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1420
|
||||
msgid "at %H:%M"
|
||||
msgstr "às %H:%M"
|
||||
|
||||
#. Translators: strftime format for a time within the next week, such as
|
||||
#. "Tue 09:00".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1423
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1424
|
||||
msgid "%a %H:%M"
|
||||
msgstr "%a às %H:%M"
|
||||
|
||||
#. Translators: strftime format for a date further ahead, such as "23 Sep".
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1426
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1427
|
||||
msgid "%e %b"
|
||||
msgstr "em %-d de %b"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1456
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1457
|
||||
msgid "No files kept offline"
|
||||
msgstr "Nenhum arquivo mantido offline"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1458
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1459
|
||||
msgid "Right-click a file and choose “Make available offline”."
|
||||
msgstr ""
|
||||
"Clique com o botão direito em um arquivo e escolha “Disponibilizar offline”."
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1509
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1516
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1510
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1517
|
||||
msgid "Couldn't make it online only"
|
||||
msgstr "Não foi possível torná-lo somente online"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1533
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1534
|
||||
msgid "Show fewer"
|
||||
msgstr "Mostrar menos"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1536
|
||||
#: crates/pdfs-gui/src/app/pages/status.rs:1537
|
||||
#, rust-format
|
||||
msgid "Show all {n} file"
|
||||
msgid_plural "Show all {n} files"
|
||||
@@ -5223,7 +5294,7 @@ msgstr "Lixeira esvaziada"
|
||||
msgid "Couldn't empty the trash"
|
||||
msgstr "Não foi possível esvaziar a lixeira"
|
||||
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:57
|
||||
#: crates/pdfs-gui/src/app/pages/verify.rs:162
|
||||
msgid "Verification"
|
||||
msgstr "Verificação"
|
||||
|
||||
@@ -5855,40 +5926,45 @@ msgstr[1] "↑ {n} enviando"
|
||||
msgid "Proton Drive isn't responding"
|
||||
msgstr "O Proton Drive não está respondendo"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:172
|
||||
#: crates/pdfs-gui/src/main.rs:173
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — locked"
|
||||
msgstr "Conectado como {username} — bloqueado"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:181
|
||||
#, rust-format
|
||||
msgid "Signed in as {username} — not connected"
|
||||
msgstr "Conectado como {username} — sem conexão"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:177
|
||||
#: crates/pdfs-gui/src/main.rs:186
|
||||
msgid "Not signed in"
|
||||
msgstr "Não conectado"
|
||||
|
||||
#. Translators: {error} is an error message, in English.
|
||||
#: crates/pdfs-gui/src/main.rs:180
|
||||
#: crates/pdfs-gui/src/main.rs:189
|
||||
#, rust-format
|
||||
msgid "Error: {error}"
|
||||
msgstr "Erro: {error}"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:201
|
||||
#: crates/pdfs-gui/src/main.rs:210
|
||||
msgid "Proton Drive sent an unexpected reply"
|
||||
msgstr "O Proton Drive enviou uma resposta inesperada"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:246
|
||||
#: crates/pdfs-gui/src/main.rs:255
|
||||
#, rust-format
|
||||
msgid "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgid_plural "Up to date in {mountpoint} ({n} pinned)"
|
||||
msgstr[0] "Atualizado em {mountpoint} ({n} fixado)"
|
||||
msgstr[1] "Atualizado em {mountpoint} ({n} fixados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:253
|
||||
#: crates/pdfs-gui/src/main.rs:262
|
||||
#, rust-format
|
||||
msgid "Syncing — {queued} ({n} pinned)"
|
||||
msgid_plural "Syncing — {queued} ({n} pinned)"
|
||||
msgstr[0] "Sincronizando — {queued} ({n} fixado)"
|
||||
msgstr[1] "Sincronizando — {queued} ({n} fixados)"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:260
|
||||
#: crates/pdfs-gui/src/main.rs:269
|
||||
#, rust-format
|
||||
msgid "Offline — cached files only ({n} pinned)"
|
||||
msgid_plural "Offline — cached files only ({n} pinned)"
|
||||
@@ -5896,52 +5972,52 @@ msgstr[0] "Offline — somente arquivos em cache ({n} fixado)"
|
||||
msgstr[1] "Offline — somente arquivos em cache ({n} fixados)"
|
||||
|
||||
#. Translators: {queued} is a queue summary such as "3 uploads queued".
|
||||
#: crates/pdfs-gui/src/main.rs:266
|
||||
#: crates/pdfs-gui/src/main.rs:275
|
||||
#, rust-format
|
||||
msgid "Offline — {queued}"
|
||||
msgstr "Offline — {queued}"
|
||||
|
||||
#. Translators: a menu item that opens the list of failing changes.
|
||||
#: crates/pdfs-gui/src/main.rs:296
|
||||
#: crates/pdfs-gui/src/main.rs:305
|
||||
#, rust-format
|
||||
msgid "{n} issue — View"
|
||||
msgid_plural "{n} issues — View"
|
||||
msgstr[0] "{n} problema — Ver"
|
||||
msgstr[1] "{n} problemas — Ver"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:402
|
||||
#: crates/pdfs-gui/src/main.rs:411
|
||||
msgid "Sign In…"
|
||||
msgstr "Entrar…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:403
|
||||
#: crates/pdfs-gui/src/main.rs:412
|
||||
msgid "Open Proton Drive"
|
||||
msgstr "Abrir o Proton Drive"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:409
|
||||
#: crates/pdfs-gui/src/main.rs:418
|
||||
msgid "Open Folder"
|
||||
msgstr "Abrir pasta"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:421
|
||||
#: crates/pdfs-gui/src/main.rs:430
|
||||
msgid "Resume Sync"
|
||||
msgstr "Retomar sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:423
|
||||
#: crates/pdfs-gui/src/main.rs:432
|
||||
msgid "Pause Sync"
|
||||
msgstr "Pausar sincronização"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:442
|
||||
#: crates/pdfs-gui/src/main.rs:451
|
||||
msgid "Connect"
|
||||
msgstr "Conectar"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:449
|
||||
#: crates/pdfs-gui/src/main.rs:458
|
||||
msgid "Hide Tray Icon"
|
||||
msgstr "Ocultar ícone da bandeja"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:453
|
||||
#: crates/pdfs-gui/src/main.rs:462
|
||||
msgid "Stop Proton Drive…"
|
||||
msgstr "Parar o Proton Drive…"
|
||||
|
||||
#: crates/pdfs-gui/src/main.rs:457
|
||||
#: crates/pdfs-gui/src/main.rs:466
|
||||
msgid "Quit"
|
||||
msgstr "Sair"
|
||||
|
||||
|
||||
Reference in new issue
Block a user