diff --git a/.dockerignore b/.dockerignore index 0b6e9acc9..b1042809d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -32,6 +32,7 @@ /fluxer_docs/.astro/ /fluxer_app/.devserver-cache.json /fluxer_app/pkgs/libfluxcore/ +/fluxer_app/pkgs/libfluxwebp/ /fluxer_app/src/features/i18n/locales/*/messages.mjs /fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts /fluxer_app/src/features/theme/styles/generated/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 47357c0af..70e052dac 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -123,12 +123,16 @@ jobs: with: path: | fluxer_app/pkgs/libfluxcore + fluxer_app/pkgs/libfluxwebp fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts key: >- app-wasm-${{ runner.os }}-1.98.1-${{ hashFiles('Cargo.lock', 'tools/ci/src/app_wasm.rs', 'tools/ci/templates/libfluxcore_wrapper.js', 'tools/ci/templates/libfluxcore_wrapper.d.ts', 'fluxer_app/rust/libfluxcore/Cargo.toml', 'fluxer_app/rust/libfluxcore/Cargo.lock', 'fluxer_app/rust/libfluxcore/.cargo/config.toml', 'fluxer_app/rust/libfluxcore/src/**', + 'fluxer_app/rust/libfluxwebp/Cargo.toml', 'fluxer_app/rust/libfluxwebp/Cargo.lock', + 'fluxer_app/rust/libfluxwebp/src/**', 'fluxer_app/rust/libfluxwebp/shim/**', + 'fluxer_app/rust/libfluxwebp/simd/**', 'packages/markdown_parser/rust/Cargo.toml', 'packages/markdown_parser/rust/.cargo/config.toml', 'packages/markdown_parser/rust/src/**') }} @@ -142,12 +146,16 @@ jobs: with: path: | fluxer_app/pkgs/libfluxcore + fluxer_app/pkgs/libfluxwebp fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts key: >- app-wasm-${{ runner.os }}-1.98.1-${{ hashFiles('Cargo.lock', 'tools/ci/src/app_wasm.rs', 'tools/ci/templates/libfluxcore_wrapper.js', 'tools/ci/templates/libfluxcore_wrapper.d.ts', 'fluxer_app/rust/libfluxcore/Cargo.toml', 'fluxer_app/rust/libfluxcore/Cargo.lock', 'fluxer_app/rust/libfluxcore/.cargo/config.toml', 'fluxer_app/rust/libfluxcore/src/**', + 'fluxer_app/rust/libfluxwebp/Cargo.toml', 'fluxer_app/rust/libfluxwebp/Cargo.lock', + 'fluxer_app/rust/libfluxwebp/src/**', 'fluxer_app/rust/libfluxwebp/shim/**', + 'fluxer_app/rust/libfluxwebp/simd/**', 'packages/markdown_parser/rust/Cargo.toml', 'packages/markdown_parser/rust/.cargo/config.toml', 'packages/markdown_parser/rust/src/**') }} @@ -190,6 +198,9 @@ jobs: - name: Check Rust dependencies run: cargo deny --locked check -D warnings + - name: Check libfluxwebp dependencies + run: cargo deny --manifest-path fluxer_app/rust/libfluxwebp/Cargo.toml --config deny.toml --locked check licenses bans sources + - name: Check desktop native dependencies run: tools/ci/check-desktop-native-workspaces.sh dependencies @@ -242,6 +253,9 @@ jobs: - name: Check formatting run: cargo fmt --all -- --check + - name: Check formatting (libfluxwebp) + run: cargo fmt --manifest-path fluxer_app/rust/libfluxwebp/Cargo.toml -- --check + - name: Check formatting (desktop native workspaces) run: tools/ci/check-desktop-native-workspaces.sh fmt @@ -398,12 +412,16 @@ jobs: with: path: | fluxer_app/pkgs/libfluxcore + fluxer_app/pkgs/libfluxwebp fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts key: >- app-wasm-${{ runner.os }}-1.98.1-${{ hashFiles('Cargo.lock', 'tools/ci/src/app_wasm.rs', 'tools/ci/templates/libfluxcore_wrapper.js', 'tools/ci/templates/libfluxcore_wrapper.d.ts', 'fluxer_app/rust/libfluxcore/Cargo.toml', 'fluxer_app/rust/libfluxcore/Cargo.lock', 'fluxer_app/rust/libfluxcore/.cargo/config.toml', 'fluxer_app/rust/libfluxcore/src/**', + 'fluxer_app/rust/libfluxwebp/Cargo.toml', 'fluxer_app/rust/libfluxwebp/Cargo.lock', + 'fluxer_app/rust/libfluxwebp/src/**', 'fluxer_app/rust/libfluxwebp/shim/**', + 'fluxer_app/rust/libfluxwebp/simd/**', 'packages/markdown_parser/rust/Cargo.toml', 'packages/markdown_parser/rust/.cargo/config.toml', 'packages/markdown_parser/rust/src/**') }} @@ -417,12 +435,16 @@ jobs: with: path: | fluxer_app/pkgs/libfluxcore + fluxer_app/pkgs/libfluxwebp fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts key: >- app-wasm-${{ runner.os }}-1.98.1-${{ hashFiles('Cargo.lock', 'tools/ci/src/app_wasm.rs', 'tools/ci/templates/libfluxcore_wrapper.js', 'tools/ci/templates/libfluxcore_wrapper.d.ts', 'fluxer_app/rust/libfluxcore/Cargo.toml', 'fluxer_app/rust/libfluxcore/Cargo.lock', 'fluxer_app/rust/libfluxcore/.cargo/config.toml', 'fluxer_app/rust/libfluxcore/src/**', + 'fluxer_app/rust/libfluxwebp/Cargo.toml', 'fluxer_app/rust/libfluxwebp/Cargo.lock', + 'fluxer_app/rust/libfluxwebp/src/**', 'fluxer_app/rust/libfluxwebp/shim/**', + 'fluxer_app/rust/libfluxwebp/simd/**', 'packages/markdown_parser/rust/Cargo.toml', 'packages/markdown_parser/rust/.cargo/config.toml', 'packages/markdown_parser/rust/src/**') }} diff --git a/.gitignore b/.gitignore index 931dcc3fc..64ced687d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ /fluxer_app/.devserver-cache.json /fluxer_app/pkgs/libfluxcore/ +/fluxer_app/pkgs/libfluxwebp/ /fluxer_app/src/features/i18n/locales/*/messages.mjs /fluxer_app/src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts /fluxer_app/src/features/theme/styles/generated/ diff --git a/fluxer_api/src/api/infrastructure/StorageObjectHelpers.test.ts b/fluxer_api/src/api/infrastructure/StorageObjectHelpers.test.ts index 2aee484b9..3025aa4cc 100644 --- a/fluxer_api/src/api/infrastructure/StorageObjectHelpers.test.ts +++ b/fluxer_api/src/api/infrastructure/StorageObjectHelpers.test.ts @@ -84,6 +84,41 @@ describe('stripNonJpegImageMetadataForUpload', () => { }); }); +function riffChunk(type: string, data: Uint8Array): Uint8Array { + const out = new Uint8Array(8 + data.length + (data.length & 1)); + out.set(textBytes(type), 0); + new DataView(out.buffer).setUint32(4, data.length, true); + out.set(data, 8); + return out; +} + +function webp(chunks: ReadonlyArray): Uint8Array { + const body = concatBytes(chunks); + const header = concatBytes([textBytes('RIFF'), new Uint8Array(4), textBytes('WEBP')]); + new DataView(header.buffer).setUint32(4, 4 + body.length, true); + return concatBytes([header, body]); +} + +describe('stripNonJpegImageMetadataForUpload for WebP', () => { + it('drops EXIF and XMP chunks without re-encoding frames', async () => { + const vp8x = new Uint8Array(10); + vp8x[0] = 0x02 | 0x08 | 0x04; + const anmf = riffChunk('ANMF', new Uint8Array([9, 8, 7])); + const input = webp([ + riffChunk('VP8X', vp8x), + riffChunk('ANIM', new Uint8Array(6)), + anmf, + riffChunk('EXIF', textBytes('GPS=1,2')), + riffChunk('XMP ', textBytes('private metadata')), + ]); + const stripped = await stripNonJpegImageMetadataForUpload(input, 'image/webp'); + const expectedVp8x = new Uint8Array(10); + expectedVp8x[0] = 0x02; + expect(stripped.contentType).toBe('image/webp'); + expect(stripped.body).toEqual(webp([riffChunk('VP8X', expectedVp8x), riffChunk('ANIM', new Uint8Array(6)), anmf])); + }); +}); + describe('buildProcessedMediaObject', () => { it('leaves non-media objects for plain copy', async () => { await expect(buildProcessedMediaObject(textBytes('plain text'), 'text/plain')).resolves.toBeNull(); diff --git a/fluxer_api/src/api/infrastructure/StorageObjectHelpers.ts b/fluxer_api/src/api/infrastructure/StorageObjectHelpers.ts index c4d811429..7d6c6ab84 100644 --- a/fluxer_api/src/api/infrastructure/StorageObjectHelpers.ts +++ b/fluxer_api/src/api/infrastructure/StorageObjectHelpers.ts @@ -162,6 +162,8 @@ export async function stripNonJpegImageMetadataForUpload( contentType: normalizedContentType === 'image/apng' ? 'image/apng' : 'image/png', }; } + const strippedWebp = isWebp(data) ? stripWebpMetadataChunks(data) : null; + if (strippedWebp) return {body: strippedWebp, contentType: 'image/webp'}; const image = sharp(data, {animated: true}); const metadata = await image.metadata(); switch (metadata.format) { @@ -242,6 +244,50 @@ function stripPngMetadataChunks(data: Uint8Array): Uint8Array { return output; } +const WEBP_CHUNKS_TO_KEEP = new Set(['VP8 ', 'VP8L', 'VP8X', 'ALPH', 'ANIM', 'ANMF', 'ICCP']); +const WEBP_VP8X_EXIF_FLAG = 0x08; +const WEBP_VP8X_XMP_FLAG = 0x04; + +function readFourCc(data: Uint8Array, offset: number): string { + return String.fromCharCode(data[offset]!, data[offset + 1]!, data[offset + 2]!, data[offset + 3]!); +} + +function readU32LE(data: Uint8Array, offset: number): number { + return (data[offset]! | (data[offset + 1]! << 8) | (data[offset + 2]! << 16) | (data[offset + 3]! << 24)) >>> 0; +} + +function isWebp(data: Uint8Array): boolean { + return data.length >= 12 && readFourCc(data, 0) === 'RIFF' && readFourCc(data, 8) === 'WEBP'; +} + +function stripWebpMetadataChunks(data: Uint8Array): Uint8Array | null { + const riffEnd = Math.min(data.length, 8 + readU32LE(data, 4)); + const chunks: Array = []; + let offset = 12; + while (offset + 8 <= riffEnd) { + const length = readU32LE(data, offset + 4); + const chunkEnd = offset + 8 + length + (length & 1); + if (offset + 8 + length > riffEnd) return null; + const type = readFourCc(data, offset); + if (WEBP_CHUNKS_TO_KEEP.has(type)) { + const chunk = data.slice(offset, Math.min(chunkEnd, riffEnd)); + if (type === 'VP8X' && length > 0) chunk[8] = (chunk[8] ?? 0) & ~(WEBP_VP8X_EXIF_FLAG | WEBP_VP8X_XMP_FLAG); + chunks.push(chunk); + } + offset = chunkEnd; + } + const bodyLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0); + const output = new Uint8Array(12 + bodyLength); + output.set(data.subarray(0, 12)); + new DataView(output.buffer).setUint32(4, 4 + bodyLength, true); + let cursor = 12; + for (const chunk of chunks) { + output.set(chunk, cursor); + cursor += chunk.length; + } + return output; +} + function imageExtensionForContentType(contentType: string): string { if (contentType.includes('svg')) return 'svg'; if (contentType.includes('tiff')) return 'tiff'; diff --git a/fluxer_app/rspack.config.mjs b/fluxer_app/rspack.config.mjs index 278c001ad..47099ab6a 100644 --- a/fluxer_app/rspack.config.mjs +++ b/fluxer_app/rspack.config.mjs @@ -433,6 +433,7 @@ export default () => { staticFilesPlugin({ staticCdnEndpoint: normalizedStaticCdnEndpoint, fontsDir: path.join(MONOREPO_ROOT, 'packages', 'fonts'), + wasmCratesDir: path.join(ROOT_DIR, 'rust'), }), new DefinePlugin({ __FLUXER_PRECACHE_MANIFEST__: JSON.stringify([]), diff --git a/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-RS.txt b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-RS.txt new file mode 100644 index 000000000..93223ef4a --- /dev/null +++ b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-RS.txt @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2026, Alexandre Bury + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-SYS.txt b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-SYS.txt new file mode 100644 index 000000000..4f3f20620 --- /dev/null +++ b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD-SYS.txt @@ -0,0 +1,32 @@ +The auto-generated bindings are under the 3-clause BSD license: + +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/fluxer_app/rust/libfluxcore/LICENSE-ZSTD.txt b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD.txt new file mode 100644 index 000000000..75800288c --- /dev/null +++ b/fluxer_app/rust/libfluxcore/LICENSE-ZSTD.txt @@ -0,0 +1,30 @@ +BSD License + +For Zstandard software + +Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook, nor Meta, nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/fluxer_app/rust/libfluxcore/NOTICE.md b/fluxer_app/rust/libfluxcore/NOTICE.md new file mode 100644 index 000000000..061fee4a7 --- /dev/null +++ b/fluxer_app/rust/libfluxcore/NOTICE.md @@ -0,0 +1,12 @@ +# libfluxcore licenses + +`libfluxcore_bg.wasm` is built from this crate and bundled into the app. It +contains third-party code that keeps its upstream license. + +| Component | Source | License | +| --- | --- | --- | +| Zstandard 1.5.7 | Vendored by the `zstd-sys` 2.1.0 crate | BSD-3-Clause, see `LICENSE-ZSTD.txt` (Zstandard is dual licensed, Fluxer uses it under BSD-3-Clause) | +| `zstd-sys` 2.1.0 | Rust bindings, build script and WebAssembly libc shim | BSD-3-Clause, see `LICENSE-ZSTD-SYS.txt` | +| `zstd` 0.14.0 | Rust wrapper | BSD-3-Clause, see `LICENSE-ZSTD-RS.txt` | + +No Fluxer license notice grants rights to third-party trademarks or brand names. diff --git a/fluxer_app/rust/libfluxcore/src/formats.rs b/fluxer_app/rust/libfluxcore/src/formats.rs index d6b94a346..9a599f205 100644 --- a/fluxer_app/rust/libfluxcore/src/formats.rs +++ b/fluxer_app/rust/libfluxcore/src/formats.rs @@ -16,6 +16,22 @@ pub fn is_animated_image_bytes(input: &[u8]) -> bool { false } +pub fn sniff_image_format_bytes(input: &[u8]) -> u8 { + if is_png(input) { + 1 + } else if is_gif(input) { + 2 + } else if is_webp(input) { + 3 + } else if is_avif_file(input) { + 4 + } else if input.starts_with(&[0xff, 0xd8, 0xff]) { + 5 + } else { + 0 + } +} + fn is_gif(input: &[u8]) -> bool { input.starts_with(b"GIF89a") || input.starts_with(b"GIF87a") } @@ -35,7 +51,16 @@ fn is_avif_file(input: &[u8]) -> bool { } fn has_avif_anim(input: &[u8]) -> bool { - is_avif_file(input) && &input[8..12] == b"avis" + if !is_avif_file(input) { + return false; + } + if &input[8..12] == b"avis" { + return true; + } + let box_end = read_u32_be(input, 0).map_or(0, |size| (size as usize).min(input.len())); + input + .get(16..box_end) + .is_some_and(|brands| brands.as_chunks::<4>().0.contains(b"avis")) } fn has_apng_actl(input: &[u8]) -> bool { @@ -243,13 +268,53 @@ mod tests { #[test] fn detects_avif_sequence_brand() { - let avif = b"\x00\x00\x00\x18ftypavif\x00\x00\x00\x00avis"; - assert!(!is_animated_image_bytes(avif)); + let still = b"\x00\x00\x00\x18ftypavif\x00\x00\x00\x00mif1miaf"; + assert!(!is_animated_image_bytes(still)); let avis = b"\x00\x00\x00\x18ftypavis\x00\x00\x00\x00avif"; assert!(is_animated_image_bytes(avis)); } + #[test] + fn detects_avis_among_compatible_brands() { + let compat = b"\x00\x00\x00\x1cftypavif\x00\x00\x00\x00mif1avismsf1"; + assert!(is_animated_image_bytes(compat)); + + let outside_ftyp = b"\x00\x00\x00\x14ftypavif\x00\x00\x00\x00mif1avis"; + assert!(!is_animated_image_bytes(outside_ftyp)); + + let truncated = b"\x00\x00\x00\x40ftypavif\x00\x00\x00\x00mif1av"; + assert!(!is_animated_image_bytes(truncated)); + } + + #[test] + fn sniffs_image_formats_from_magic_bytes() { + assert_eq!(sniff_image_format_bytes(b""), 0); + assert_eq!(sniff_image_format_bytes(b" Result<(), JsValue> { + crop_rotate_rgba_into( + input, + output, + TransformRequest { + src_width, + src_height, + x, + y, + width, + height, + rotation_deg, + resize_width: output_width, + resize_height: output_height, + }, + ) + .map_err(|error| JsValue::from_str(error.message())) +} + #[wasm_bindgen] pub fn decompress_zstd_frame(input: &[u8]) -> Result, JsValue> { zstd_frame::decompress(input).map_err(zstd_error_to_js) @@ -106,6 +139,11 @@ pub fn is_animated_image(input: &[u8]) -> bool { is_animated_image_bytes(input) } +#[wasm_bindgen] +pub fn sniff_image_format(input: &[u8]) -> u8 { + sniff_image_format_bytes(input) +} + fn optional_dimension_to_abi(value: Option) -> u32 { value.filter(|dimension| *dimension > 0).unwrap_or(u32::MAX) } diff --git a/fluxer_app/rust/libfluxcore/src/rgba.rs b/fluxer_app/rust/libfluxcore/src/rgba.rs index 508117b7a..38909bfbd 100644 --- a/fluxer_app/rust/libfluxcore/src/rgba.rs +++ b/fluxer_app/rust/libfluxcore/src/rgba.rs @@ -22,6 +22,7 @@ pub struct TransformRequest { pub enum TransformError { InvalidDimensions, InvalidRgbaLength, + InvalidOutputLength, EmptyCrop, EmptyTarget, ImageTooLarge, @@ -33,6 +34,7 @@ impl TransformError { match self { Self::InvalidDimensions => "invalid RGBA dimensions", Self::InvalidRgbaLength => "RGBA input length does not match dimensions", + Self::InvalidOutputLength => "RGBA output length does not match target dimensions", Self::EmptyCrop => "Crop area is empty", Self::EmptyTarget => "Target dimensions are empty", Self::ImageTooLarge => "Image is too large to crop", @@ -75,12 +77,7 @@ pub fn crop_rotate_rgba_alloc( input: &[u8], request: TransformRequest, ) -> Result, TransformError> { - let geometry = output_geometry(request)?; - let expected_len = rgba_byte_len(request.src_width, request.src_height, 0)?; - if input.len() != expected_len { - return Err(TransformError::InvalidRgbaLength); - } - + let geometry = checked_geometry(input, request)?; let output_len = rgba_byte_len( geometry.target_width, geometry.target_height, @@ -89,8 +86,45 @@ pub fn crop_rotate_rgba_alloc( let mut output = try_zeroed_vec(output_len)?; write_u32_le(&mut output, 0, geometry.target_width); write_u32_le(&mut output, 4, geometry.target_height); + write_transformed( + input, + &mut output[RGBA_RESULT_HEADER_BYTES..], + request, + geometry, + ); + Ok(output) +} - let dst = &mut output[RGBA_RESULT_HEADER_BYTES..]; +pub fn crop_rotate_rgba_into( + input: &[u8], + output: &mut [u8], + request: TransformRequest, +) -> Result<(), TransformError> { + let geometry = checked_geometry(input, request)?; + if output.len() != rgba_byte_len(geometry.target_width, geometry.target_height, 0)? { + return Err(TransformError::InvalidOutputLength); + } + write_transformed(input, output, request, geometry); + Ok(()) +} + +fn checked_geometry( + input: &[u8], + request: TransformRequest, +) -> Result { + let geometry = output_geometry(request)?; + if input.len() != rgba_byte_len(request.src_width, request.src_height, 0)? { + return Err(TransformError::InvalidRgbaLength); + } + Ok(geometry) +} + +fn write_transformed( + input: &[u8], + dst: &mut [u8], + request: TransformRequest, + geometry: OutputGeometry, +) { if geometry.target_width == geometry.base_width && geometry.target_height == geometry.base_height { @@ -98,8 +132,6 @@ pub fn crop_rotate_rgba_alloc( } else { copy_rotated_with_nearest_resize(input, dst, request, geometry); } - - Ok(output) } fn output_geometry(request: TransformRequest) -> Result { @@ -463,6 +495,30 @@ mod tests { assert!(crop_rotate_rgba_alloc(&rgba(&[1, 2, 3, 4]), empty_target).is_ok()); } + #[test] + fn into_writes_the_same_pixels_as_alloc() { + let input = rgba(&[1, 2, 3, 4, 5, 6]); + for rotation_deg in [0, 90, 180, 270] { + let mut transform = request(2, 3); + transform.rotation_deg = rotation_deg; + transform.resize_width = 5; + transform.resize_height = 4; + let expected = crop_rotate_rgba_alloc(&input, transform).unwrap(); + let mut output = vec![0xaa; 5 * 4 * RGBA_BYTES_PER_PIXEL]; + crop_rotate_rgba_into(&input, &mut output, transform).unwrap(); + assert_eq!(output, payload(&expected)); + } + } + + #[test] + fn into_rejects_an_output_of_the_wrong_length() { + let mut output = vec![0; 3 * RGBA_BYTES_PER_PIXEL]; + assert_eq!( + crop_rotate_rgba_into(&rgba(&[1, 2, 3, 4]), &mut output, request(2, 2)).unwrap_err(), + TransformError::InvalidOutputLength + ); + } + proptest! { #[test] fn identity_transform_preserves_pixels(width in 1u32..16, height in 1u32..16) { diff --git a/fluxer_app/rust/libfluxwebp/Cargo.lock b/fluxer_app/rust/libfluxwebp/Cargo.lock new file mode 100644 index 000000000..b6c2f08cf --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/Cargo.lock @@ -0,0 +1,160 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cc" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54413ede23c2daf518f35156dfde027feb2374004d63bd497f983c8db9c0e313" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "find-msvc-tools" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25905e51abafe4dcea6c15fec58c57b601cdbd0ee53d22ea1d3016c587d39b" + +[[package]] +name = "glob" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" + +[[package]] +name = "libfluxwebp" +version = "0.1.0" +dependencies = [ + "libwebp-sys", + "wasm-bindgen", +] + +[[package]] +name = "libwebp-sys" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3a87b44e34d17161e4f17d92a463d596cb13825dcd1758ed18fd3a721e189c" +dependencies = [ + "cc", + "glob", + "pkg-config", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954" + +[[package]] +name = "wasm-bindgen" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" +dependencies = [ + "unicode-ident", +] diff --git a/fluxer_app/rust/libfluxwebp/Cargo.toml b/fluxer_app/rust/libfluxwebp/Cargo.toml new file mode 100644 index 000000000..95cd0ecf5 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "libfluxwebp" +version = "0.1.0" +edition = "2024" +license = "AGPL-3.0-or-later" +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = "=0.2.128" +libwebp-sys = {version = "=0.14.4", default-features = false} + +[profile.release] +codegen-units = 1 +lto = true +opt-level = "z" +panic = "abort" +strip = true + +[workspace] diff --git a/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP-SYS.txt b/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP-SYS.txt new file mode 100644 index 000000000..5075522ea --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP-SYS.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) the libwebp-sys authors (XianYou, Kornel LesiƄski and contributors) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP.txt b/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP.txt new file mode 100644 index 000000000..7a6f99547 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/LICENSE-LIBWEBP.txt @@ -0,0 +1,30 @@ +Copyright (c) 2010, Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/fluxer_app/rust/libfluxwebp/NOTICE.md b/fluxer_app/rust/libfluxwebp/NOTICE.md new file mode 100644 index 000000000..7e11262f4 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/NOTICE.md @@ -0,0 +1,16 @@ +# libfluxwebp licenses + +`libfluxwebp_bg.wasm` and `libfluxwebp_simd_bg.wasm` are built from this crate +and bundled into the app. They contain third-party code that keeps its upstream +license. + +| Component | Source | License | +| --- | --- | --- | +| libwebp 1.6.0 | Vendored by the `libwebp-sys` 0.14.4 crate | BSD-3-Clause, see `LICENSE-LIBWEBP.txt`, with the additional patent grant in `PATENTS-LIBWEBP.txt` | +| `libwebp-sys` 0.14.4 | Rust bindings and build script | MIT, see `LICENSE-LIBWEBP-SYS.txt` | +| `simd/xmmintrin.h`, `simd/emmintrin.h` | Emscripten 4.0.15 SSE compatibility headers | MIT or University of Illinois/NCSA, see `simd/LICENSE` | + +The SIMD build compiles libwebp's SSE2 code paths through the Emscripten +headers, unmodified. The headers in `shim/` and `src/shim.rs` are Fluxer code. + +No Fluxer license notice grants rights to third-party trademarks or brand names. diff --git a/fluxer_app/rust/libfluxwebp/PATENTS-LIBWEBP.txt b/fluxer_app/rust/libfluxwebp/PATENTS-LIBWEBP.txt new file mode 100644 index 000000000..caedf607e --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/PATENTS-LIBWEBP.txt @@ -0,0 +1,23 @@ +Additional IP Rights Grant (Patents) +------------------------------------ + +"These implementations" means the copyrightable works that implement the WebM +codecs distributed by Google as part of the WebM Project. + +Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent license to +make, have made, use, offer to sell, sell, import, transfer, and otherwise +run, modify and propagate the contents of these implementations of WebM, where +such license applies only to those patent claims, both currently owned by +Google and acquired in the future, licensable by Google that are necessarily +infringed by these implementations of WebM. This grant does not include claims +that would be infringed only as a consequence of further modification of these +implementations. If you or your agent or exclusive licensee institute or order +or agree to the institution of patent litigation or any other patent +enforcement activity against any entity (including a cross-claim or +counterclaim in a lawsuit) alleging that any of these implementations of WebM +or any code incorporated within any of these implementations of WebM +constitute direct or contributory patent infringement, or inducement of +patent infringement, then any patent rights granted to you under this License +for these implementations of WebM shall terminate as of the date such +litigation is filed. diff --git a/fluxer_app/rust/libfluxwebp/shim/assert.h b/fluxer_app/rust/libfluxwebp/shim/assert.h new file mode 100644 index 000000000..d47669376 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/assert.h @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_ASSERT_H +#define FLUXWEBP_ASSERT_H +#define assert(expr) ((void)0) +#endif diff --git a/fluxer_app/rust/libfluxwebp/shim/inttypes.h b/fluxer_app/rust/libfluxwebp/shim/inttypes.h new file mode 100644 index 000000000..e73f9198d --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/inttypes.h @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_INTTYPES_H +#define FLUXWEBP_INTTYPES_H +#include +#endif diff --git a/fluxer_app/rust/libfluxwebp/shim/math.h b/fluxer_app/rust/libfluxwebp/shim/math.h new file mode 100644 index 000000000..8a25c5516 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/math.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_MATH_H +#define FLUXWEBP_MATH_H +double fluxwebp_shim_pow(double x, double y); +double fluxwebp_shim_log(double x); +float fluxwebp_shim_expf(float x); +double fluxwebp_shim_log10(double x); +float fluxwebp_shim_logf(float x); +double fluxwebp_shim_round(double x); +#define pow(x, y) fluxwebp_shim_pow(x, y) +#define log(x) fluxwebp_shim_log(x) +#define expf(x) fluxwebp_shim_expf(x) +#define log10(x) fluxwebp_shim_log10(x) +#define logf(x) fluxwebp_shim_logf(x) +#define round(x) fluxwebp_shim_round(x) +#define fabs(x) __builtin_fabs(x) +#define floor(x) __builtin_floor(x) +#define ceil(x) __builtin_ceil(x) +#define sqrt(x) __builtin_sqrt(x) +#define sqrtf(x) __builtin_sqrtf(x) +#define rint(x) __builtin_rint(x) +#define rintf(x) __builtin_rintf(x) +#define fabsf(x) __builtin_fabsf(x) +#define floorf(x) __builtin_floorf(x) +#define ceilf(x) __builtin_ceilf(x) +#define isnan(x) __builtin_isnan(x) +#define isinf(x) __builtin_isinf(x) +#define lrint(x) ((long)__builtin_rint(x)) +#define llrint(x) ((long long)__builtin_rint(x)) +#define lrintf(x) ((long)__builtin_rintf(x)) +#define llrintf(x) ((long long)__builtin_rintf(x)) +#endif diff --git a/fluxer_app/rust/libfluxwebp/shim/stdio.h b/fluxer_app/rust/libfluxwebp/shim/stdio.h new file mode 100644 index 000000000..a4e645783 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/stdio.h @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_STDIO_H +#define FLUXWEBP_STDIO_H +#include +#include +typedef struct FluxWebpFile FILE; +#define stderr ((FILE*)0) +#define stdout ((FILE*)0) +#define fprintf(f, ...) ((void)0) +#define printf(...) ((void)0) +#define fflush(f) ((void)0) + +static inline void fluxwebp_shim_put(char* buf, size_t cap, size_t* n, char c) { + if (*n + 1 < cap) buf[*n] = c; + (*n)++; +} + +static inline int snprintf(char* buf, size_t cap, const char* fmt, ...) { + va_list ap; + size_t n = 0; + va_start(ap, fmt); + for (; *fmt; fmt++) { + if (*fmt != '%') { + fluxwebp_shim_put(buf, cap, &n, *fmt); + continue; + } + fmt++; + if (*fmt == 's') { + const char* s = va_arg(ap, const char*); + while (s && *s) fluxwebp_shim_put(buf, cap, &n, *s++); + } else if (*fmt == 'd') { + int v = va_arg(ap, int); + char tmp[12]; + int i = 0; + unsigned int u = v < 0 ? 0u - (unsigned int)v : (unsigned int)v; + if (v < 0) fluxwebp_shim_put(buf, cap, &n, '-'); + do { tmp[i++] = (char)('0' + u % 10); u /= 10; } while (u); + while (i) fluxwebp_shim_put(buf, cap, &n, tmp[--i]); + } else if (*fmt == '%') { + fluxwebp_shim_put(buf, cap, &n, '%'); + } else { + break; + } + } + va_end(ap); + if (cap) buf[n < cap ? n : cap - 1] = '\0'; + return (int)n; +} +#endif diff --git a/fluxer_app/rust/libfluxwebp/shim/stdlib.h b/fluxer_app/rust/libfluxwebp/shim/stdlib.h new file mode 100644 index 000000000..56007aabe --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/stdlib.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_STDLIB_H +#define FLUXWEBP_STDLIB_H +#include +void* fluxwebp_shim_malloc(size_t size); +void* fluxwebp_shim_calloc(size_t nmemb, size_t size); +void fluxwebp_shim_free(void* ptr); +void fluxwebp_shim_qsort(void* base, size_t nitems, size_t size, int (*compar)(const void*, const void*)); +#define malloc(size) fluxwebp_shim_malloc(size) +#define calloc(nmemb, size) fluxwebp_shim_calloc(nmemb, size) +#define free(ptr) fluxwebp_shim_free(ptr) +#define qsort(base, nitems, size, compar) fluxwebp_shim_qsort(base, nitems, size, compar) +#define abort() __builtin_trap() +static inline int abs(int x) { return x < 0 ? -x : x; } +#endif diff --git a/fluxer_app/rust/libfluxwebp/shim/string.h b/fluxer_app/rust/libfluxwebp/shim/string.h new file mode 100644 index 000000000..b9bed95d3 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/shim/string.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#ifndef FLUXWEBP_STRING_H +#define FLUXWEBP_STRING_H +#include +#define memcpy(d, s, n) __builtin_memcpy(d, s, n) +#define memmove(d, s, n) __builtin_memmove(d, s, n) +#define memset(d, c, n) __builtin_memset(d, c, n) +#define memcmp(a, b, n) __builtin_memcmp(a, b, n) +#define strlen(s) __builtin_strlen(s) +#endif diff --git a/fluxer_app/rust/libfluxwebp/simd/LICENSE b/fluxer_app/rust/libfluxwebp/simd/LICENSE new file mode 100644 index 000000000..70cabe388 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/simd/LICENSE @@ -0,0 +1,102 @@ +Emscripten is available under 2 licenses, the MIT license and the +University of Illinois/NCSA Open Source License. + +Both are permissive open source licenses, with little if any +practical difference between them. + +The reason for offering both is that (1) the MIT license is +well-known, while (2) the University of Illinois/NCSA Open Source +License allows Emscripten's code to be integrated upstream into +LLVM, which uses that license, should the opportunity arise. + +The full text of both licenses follows. + +============================================================================== + +Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +============================================================================== + +Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal with the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimers + in the documentation and/or other materials provided with the + distribution. + + Neither the names of Mozilla, + nor the names of its contributors may be used to endorse + or promote products derived from this Software without specific prior + written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. + +============================================================================== + +This program uses portions of Node.js source code located in src/library_path.js, +in accordance with the terms of the MIT license. Node's license follows: + + """ + Copyright Joyent, Inc. and other Node contributors. All rights reserved. + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. + """ + +The musl libc project is bundled in this repo, and it has the MIT license, see +system/lib/libc/musl/COPYRIGHT + +The third_party/ subdirectory contains code with other licenses. None of it is +used by default, but certain options use it (e.g., the optional closure compiler +flag will run closure compiler from third_party/). + diff --git a/fluxer_app/rust/libfluxwebp/simd/emmintrin.h b/fluxer_app/rust/libfluxwebp/simd/emmintrin.h new file mode 100644 index 000000000..0b844d8ee --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/simd/emmintrin.h @@ -0,0 +1,1515 @@ +/* + * Copyright 2020 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ +#ifndef __emscripten_emmintrin_h__ +#define __emscripten_emmintrin_h__ + +#ifndef __SSE2__ +#error "SSE2 instruction set not enabled" +#endif + +#include + +// Alias different (functionally) equivalent intrinsics. +#define _mm_set_epi64x _mm_set_epi64 +#define _mm_cvtsd_si64x _mm_cvtsd_si64 +#define _mm_cvtsi128_si64x _mm_cvtsi128_si64 +#define _mm_cvtsi64x_sd _mm_cvtsi64_sd +#define _mm_cvtsi64x_si128 _mm_cvtsi64_si128 +#define _mm_cvttsd_si64x _mm_cvttsd_si64 +#define _mm_store_pd1 _mm_store1_pd + +typedef __f64x2 __m128d; + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_move_sd(__m128d __a, __m128d __b) +{ + return (__m128d){ __b[0], __a[1] }; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_add_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_add_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_add_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_sub_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_sub_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_sub_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_mul_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_mul((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_mul_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_mul_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_div_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_div((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_div_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_div_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_pd(__m128d __a) +{ + return (__m128d)wasm_f64x2_sqrt((v128_t)__a); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_sqrt_pd(__b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_min_pd(__m128d __a, __m128d __b) +{ +// return (__m128d)wasm_f32x4_pmin((v128_t)__a, (v128_t)__b); // TODO: Migrate to this, once it works in VMs + return (__m128d)wasm_v128_bitselect((v128_t)__a, (v128_t)__b, (v128_t)wasm_f64x2_lt((v128_t)__a, (v128_t)__b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_min_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_min_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_max_pd(__m128d __a, __m128d __b) +{ +// return (__m128)wasm_f32x4_pmax((v128_t)__a, (v128_t)__b); // TODO: Migrate to this, once it works in VMs + return (__m128d)wasm_v128_bitselect((v128_t)__a, (v128_t)__b, (v128_t)wasm_f64x2_gt((v128_t)__a, (v128_t)__b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_max_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_max_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_and_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_and((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_andnot_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_andnot((v128_t)__b, (v128_t)__a); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_or_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_or((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_xor_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_xor((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_eq((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_lt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmple_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_le((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_gt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpge_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_ge((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpord_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_and(wasm_f64x2_eq((v128_t)__a, (v128_t)__a), + wasm_f64x2_eq((v128_t)__b, (v128_t)__b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpunord_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_or(wasm_f64x2_ne((v128_t)__a, (v128_t)__a), + wasm_f64x2_ne((v128_t)__b, (v128_t)__b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpneq_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_f64x2_ne((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnlt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_not((v128_t)_mm_cmplt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnle_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_not((v128_t)_mm_cmple_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpngt_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_not((v128_t)_mm_cmpgt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnge_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_v128_not((v128_t)_mm_cmpge_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpeq_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmplt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmple_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmple_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpgt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpge_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpge_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpord_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpord_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpunord_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpunord_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpneq_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpneq_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnlt_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpnlt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnle_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpnle_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpngt_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpngt_pd(__a, __b)); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnge_sd(__m128d __a, __m128d __b) +{ + return _mm_move_sd(__a, _mm_cmpnge_pd(__a, __b)); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comieq_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) == wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comilt_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) < wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comile_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) <= wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comigt_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) > wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comige_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) >= wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_comineq_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) != wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomieq_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) == wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomilt_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) < wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomile_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) <= wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomigt_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) > wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomige_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) >= wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_ucomineq_sd(__m128d __a, __m128d __b) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0) != wasm_f64x2_extract_lane((v128_t)__b, 0); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cvtpd_ps(__m128d __a) +{ + return (__m128)wasm_f32x4_demote_f64x2_zero((v128_t)__a); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cvtps_pd(__m128 __a) +{ + return (__m128d)wasm_f64x2_promote_low_f32x4((v128_t)__a); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cvtepi32_pd(__m128i __a) +{ + return (__m128d)wasm_f64x2_convert_low_i32x4((v128_t)__a); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvtpd_epi32(__m128d __a) +{ + // TODO: OPTIMIZE! + int m[2]; + for(int i = 0; i < 2; ++i) + { + double e = __a[i]; + int x = lrint(e); + if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0)) + m[i] = x; + else + m[i] = (int)0x80000000; + } + return wasm_i32x4_make(m[0], m[1], 0, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsd_si32(__m128d __a) +{ + // TODO: OPTIMIZE! + double e = __a[0]; + int x = lrint(e); + if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0)) + return x; + else + return (int)0x80000000; +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsd_ss(__m128 __a, __m128d __b) +{ + __a[0] = __b[0]; + return __a; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi32_sd(__m128d __a, int __b) +{ + __a[0] = __b; + return __a; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cvtss_sd(__m128d __a, __m128 __b) +{ + __a[0] = __b[0]; + return __a; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvttpd_epi32(__m128d __a) +{ + // TODO: OPTIMIZE! + int m[2]; + for(int i = 0; i < 2; ++i) + { + double elem = __a[i]; + if (elem < 2147483648.0 && elem >= -2147483648.0 && (lrint(elem) != 0 || fabs(elem) < 2.0)) + // Use the trapping instruction here since we have explicit bounds checks + // above. + m[i] = __builtin_wasm_trunc_s_i32_f64(elem); + else + m[i] = (int)0x80000000; + } + return wasm_i32x4_make(m[0], m[1], 0, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_cvttsd_si32(__m128d __a) +{ + // TODO: OPTIMIZE! + double elem = __a[0]; + if (elem < 2147483648.0 && elem >= -2147483648.0 && (lrint(elem) != 0 || fabs(elem) < 2.0)) + // Use the trapping instruction here since we have explicit bounds checks + // above. + return __builtin_wasm_trunc_s_i32_f64(elem); + else + return (int)0x80000000; +} + +static __inline__ double __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsd_f64(__m128d __a) +{ + return wasm_f64x2_extract_lane((v128_t)__a, 0); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_load_pd(double const *__dp) +{ + return *(__m128d*)__dp; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_load1_pd(double const *__dp) +{ + return (__m128d)wasm_v64x2_load_splat(__dp); +} + +#define _mm_load_pd1(dp) _mm_load1_pd(dp) + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_loadr_pd(double const *__p) +{ + __m128d __u = *(__m128d*)__p; // aligned load + return (__m128d)wasm_i64x2_shuffle((v128_t)__u, (v128_t)__u, 1, 0); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_pd(double const *__dp) +{ + struct __loadu_pd { + __m128d __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __loadu_pd*)__dp)->__v; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_load_sd(double const *__p) +{ + return (__m128d)wasm_v128_load64_zero((const void*)__p); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_loadh_pd(__m128d __a, double const *__dp) +{ + return (__m128d)wasm_v128_load64_lane((const void*)__dp, (v128_t)__a, 1); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_loadl_pd(__m128d __a, double const *__dp) +{ + return (__m128d)wasm_v128_load64_lane((const void*)__dp, (v128_t)__a, 0); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_set_sd(double __w) +{ + return (__m128d)wasm_f64x2_make(__w, 0); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_set1_pd(double __w) +{ + return (__m128d)wasm_f64x2_splat(__w); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_set_pd(double __c1, double __c0) +{ + return (__m128d)wasm_f64x2_make(__c0, __c1); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_setr_pd(double __c0, double __c1) +{ + return (__m128d)wasm_f64x2_make(__c0, __c1); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_setzero_pd(void) +{ + return (__m128d)wasm_f64x2_const(0.0, 0.0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_sd(double *__dp, __m128d __a) +{ + wasm_v128_store64_lane((void*)__dp, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store1_pd(double *__dp, __m128d __a) +{ + struct __mm_store1_pd_struct { + double __u[2]; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_store1_pd_struct*)__dp)->__u[0] = __a[0]; + ((struct __mm_store1_pd_struct*)__dp)->__u[1] = __a[0]; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_pd(double *__dp, __m128d __a) +{ + *(__m128d *)__dp = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_pd(double *__dp, __m128d __a) +{ + struct __unaligned { + __m128d __v; + } __attribute__((__packed__, __may_alias__)); + + ((struct __unaligned *)__dp)->__v = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storer_pd(double *__p, __m128d __a) +{ + *(__m128d *)__p = (__m128d)wasm_i64x2_shuffle((v128_t)__a, (v128_t)__a, 1, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeh_pd(double *__dp, __m128d __a) +{ + wasm_v128_store64_lane((void*)__dp, (v128_t)__a, 1); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storel_pd(double *__dp, __m128d __a) +{ + wasm_v128_store64_lane((void*)__dp, (v128_t)__a, 0); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_add_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_add_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_add_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_add_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i64x2_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_adds_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_add_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_adds_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_add_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_adds_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u8x16_add_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_adds_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u16x8_add_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_avg_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u8x16_avgr((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_avg_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u16x8_avgr((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_madd_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_dot_i16x8((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_max_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_max((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_max_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u8x16_max((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_min_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_min((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_min_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u8x16_min((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_mulhi_epi16(__m128i __a, __m128i __b) +{ + const v128_t lo = wasm_i32x4_extmul_low_i16x8((v128_t)__a, (v128_t)__b); + const v128_t hi = wasm_i32x4_extmul_high_i16x8((v128_t)__a, (v128_t)__b); + return (__m128i)wasm_i16x8_shuffle(lo, hi, 1, 3, 5, 7, 9, 11, 13, 15); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_mulhi_epu16(__m128i __a, __m128i __b) +{ + const v128_t lo = wasm_u32x4_extmul_low_u16x8((v128_t)__a, (v128_t)__b); + const v128_t hi = wasm_u32x4_extmul_high_u16x8((v128_t)__a, (v128_t)__b); + return (__m128i)wasm_i16x8_shuffle(lo, hi, 1, 3, 5, 7, 9, 11, 13, 15); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_mullo_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_mul((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_mul_epu32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u64x2_extmul_low_u32x4( + wasm_v32x4_shuffle((v128_t)__a, (v128_t)__a, 0, 2, 0, 2), + wasm_v32x4_shuffle((v128_t)__b, (v128_t)__b, 0, 2, 0, 2)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sub_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sub_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sub_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sub_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i64x2_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_subs_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_sub_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_subs_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_sub_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_subs_epu8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u8x16_sub_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_subs_epu16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_u16x8_sub_saturate((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_and_si128(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_v128_and((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_andnot_si128(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_v128_andnot((v128_t)__b, (v128_t)__a); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_or_si128(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_v128_or((v128_t)__b, (v128_t)__a); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_xor_si128(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_v128_xor((v128_t)__b, (v128_t)__a); +} + +#define _mm_slli_si128(__a, __imm) __extension__ ({ \ + (__m128i)wasm_i8x16_shuffle(_mm_setzero_si128(), \ + (__a), \ + ((__imm)&0xF0) ? 0 : 16 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 17 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 18 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 19 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 20 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 21 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 22 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 23 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 24 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 25 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 26 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 27 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 28 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 29 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 30 - ((__imm)&0xF), \ + ((__imm)&0xF0) ? 0 : 31 - ((__imm)&0xF)); }) +#define _mm_bslli_si128(__a, __imm) \ + _mm_slli_si128((__a), (__imm)) + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_slli_epi16(__m128i __a, int __count) +{ + return (__m128i)((__count < 16) ? wasm_i16x8_shl((v128_t)__a, __count) : wasm_i16x8_const(0,0,0,0,0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sll_epi16(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 16) ? wasm_i16x8_shl((v128_t)__a, __c) : wasm_i16x8_const(0,0,0,0,0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_slli_epi32(__m128i __a, int __count) +{ + return (__m128i)((__count < 32) ? wasm_i32x4_shl((v128_t)__a, __count) : wasm_i32x4_const(0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sll_epi32(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 32) ? wasm_i32x4_shl((v128_t)__a, __c) : wasm_i32x4_const(0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_slli_epi64(__m128i __a, int __count) +{ + return (__m128i)((__count < 64) ? wasm_i64x2_shl((v128_t)__a, __count) : wasm_i64x2_const(0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sll_epi64(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 64) ? wasm_i64x2_shl((v128_t)__a, __c) : wasm_i64x2_const(0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srai_epi16(__m128i __a, int __count) +{ + __count = __count < 15 ? __count : 15; + return (__m128i)wasm_i16x8_shr((v128_t)__a, __count); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sra_epi16(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + __c = __c < 15 ? __c : 15; + return (__m128i)wasm_i16x8_shr((v128_t)__a, __c); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srai_epi32(__m128i __a, int __count) +{ + __count = __count < 31 ? __count : 31; + return (__m128i)wasm_i32x4_shr((v128_t)__a, __count); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sra_epi32(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + __c = __c < 31 ? __c : 31; + return (__m128i)wasm_i32x4_shr((v128_t)__a, __c); +} + +#define _mm_srli_si128(__a, __imm) __extension__ ({ \ + (__m128i)wasm_i8x16_shuffle((__a), \ + _mm_setzero_si128(), \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 0, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 1, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 2, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 3, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 4, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 5, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 6, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 7, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 8, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 9, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 10, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 11, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 12, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 13, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 14, \ + ((__imm)&0xF0) ? 16 : ((__imm)&0xF) + 15); }) + +#define _mm_bsrli_si128(__a, __imm) \ + _mm_srli_si128((__a), (__imm)) + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srli_epi16(__m128i __a, int __count) +{ + return (__m128i)(((unsigned int)__count < 16) ? wasm_u16x8_shr((v128_t)__a, __count) : wasm_i16x8_const(0,0,0,0,0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srl_epi16(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 16) ? wasm_u16x8_shr((v128_t)__a, __c) : wasm_i16x8_const(0,0,0,0,0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srli_epi32(__m128i __a, int __count) +{ + return (__m128i)(((unsigned int)__count < 32) ? wasm_u32x4_shr((v128_t)__a, __count) : wasm_i32x4_const(0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srl_epi32(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 32) ? wasm_u32x4_shr((v128_t)__a, __c) : wasm_i32x4_const(0,0,0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srli_epi64(__m128i __a, int __count) +{ + return (__m128i)(((unsigned int)__count < 64) ? wasm_u64x2_shr((v128_t)__a, __count) : wasm_i64x2_const(0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_srl_epi64(__m128i __a, __m128i __count) +{ + unsigned long long __c = (unsigned long long)((__u64x2)__count)[0]; + return (__m128i)((__c < 64) ? wasm_u64x2_shr((v128_t)__a, __c) : wasm_i64x2_const(0,0)); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_eq((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_eq((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_eq((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_gt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_gt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_gt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_lt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_lt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_lt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi64_sd(__m128d __a, long long __b) +{ + // TODO: optimize + union { + double x[2]; + __m128d m; + } m; + m.m = __a; + m.x[0] = (double)__b; + return m.m; +} + +static __inline__ long long __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsd_si64(__m128d __a) +{ + // TODO: optimize + double e = __a[0]; + if (isnan(e) || isinf(e)) return 0x8000000000000000LL; + long long x = llrint(e); + if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabs(e) < 2.f)) + return x; + else + return 0x8000000000000000LL; +} + +static __inline__ long long __attribute__((__always_inline__, __nodebug__)) +_mm_cvttsd_si64(__m128d __a) +{ + // TODO: optimize + double e = __a[0]; + if (isnan(e) || isinf(e) || e > LLONG_MAX || e < LLONG_MIN) return 0x8000000000000000LL; + long long x = llrint(e); + if (x != 0 || fabs(e) < 2.f) + // Use the trapping instruction here since we have explicit bounds checks + // above + return __builtin_wasm_trunc_s_i64_f64(e); + else + return 0x8000000000000000LL; +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cvtepi32_ps(__m128i __a) +{ + return (__m128)wasm_f32x4_convert_i32x4(__a); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvtps_epi32(__m128 __a) +{ + // TODO: optimize + union { + int x[4]; + __m128i m; + } u; + for(int i = 0; i < 4; ++i) + { + double e = __a[i]; + int x = lrint(e); + if (e <= INT_MAX && e >= INT_MIN && (x != 0 || fabs(e) < 2.0)) + u.x[i] = x; + else + u.x[i] = (int)0x80000000; + } + return u.m; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvttps_epi32(__m128 __a) +{ + // TODO: optimize + union { + int x[4]; + __m128i m; + } u; + for(int i = 0; i < 4; ++i) + { + float e = __a[i]; + if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabs(e) < 2.0)) + // Use the trapping instruction here since we have explicit bounds checks + // above. + u.x[i] = __builtin_wasm_trunc_s_i32_f32(e); + else + u.x[i] = (int)0x80000000; + } + return u.m; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi32_si128(int __a) +{ + return (__m128i)wasm_i32x4_make(__a, 0, 0, 0); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi64_si128(long long __a) +{ + return (__m128i)wasm_i64x2_make(__a, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi128_si32(__m128i __a) +{ + return wasm_i32x4_extract_lane(__a, 0); +} + +static __inline__ long long __attribute__((__always_inline__, __nodebug__)) +_mm_cvtsi128_si64(__m128i __a) +{ + return wasm_i64x2_extract_lane(__a, 0); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_load_si128(__m128i const *__p) +{ + return *__p; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_si128(__m128i const *__p) +{ + // UB-free unaligned access copied from wasm_simd128.h + struct __mm_loadu_si128_struct { + __m128i __v; + } __attribute__((__packed__, __may_alias__)); + return ((struct __mm_loadu_si128_struct*)__p)->__v; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_si16(void const *__p) +{ + return (__m128i)wasm_v128_load16_lane(__p, wasm_i64x2_const(0, 0), 0); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_si32(void const *__p) +{ + return (__m128i)wasm_v128_load32_zero(__p); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_si64(void const *__p) +{ + return (__m128i)wasm_v128_load64_zero(__p); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_loadl_epi64(__m128i const *__p) +{ + return _mm_loadu_si64(__p); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set_epi64(long long q1, long long q0) +{ + return (__m128i)wasm_i64x2_make(q0, q1); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set_epi32(int i3, int i2, int i1, int i0) +{ + return (__m128i)wasm_i32x4_make(i0, i1, i2, i3); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set_epi16(short w7, short w6, short w5, short w4, short w3, short w2, short w1, short w0) +{ + return (__m128i)wasm_i16x8_make(w0, w1, w2, w3, w4, w5, w6, w7); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set_epi8(char b15, char b14, char b13, char b12, char b11, char b10, char b9, char b8, char b7, char b6, char b5, char b4, char b3, char b2, char b1, char b0) +{ + return (__m128i)wasm_i8x16_make(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set1_epi64x(long long __q) +{ + return (__m128i)wasm_i64x2_splat(__q); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set1_epi32(int __i) +{ + return (__m128i)wasm_i32x4_splat(__i); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set1_epi16(short __w) +{ + return (__m128i)wasm_i16x8_splat(__w); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_set1_epi8(char __b) +{ + return (__m128i)wasm_i8x16_splat(__b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_setr_epi32(int i0, int i1, int i2, int i3) +{ + return (__m128i)wasm_i32x4_make(i0, i1, i2, i3); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_setr_epi16(short w0, short w1, short w2, short w3, short w4, short w5, short w6, short w7) +{ + return (__m128i)wasm_i16x8_make(w0, w1, w2, w3, w4, w5, w6, w7); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_setr_epi8(char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9, char b10, char b11, char b12, char b13, char b14, char b15) +{ + return (__m128i)wasm_i8x16_make(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_setzero_si128(void) +{ + return wasm_i64x2_const(0, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_si128(__m128i *__p, __m128i __b) +{ + *__p = __b; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_si16(void *__p, __m128i __a) +{ + wasm_v128_store16_lane(__p, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_si32(void *__p, __m128i __a) +{ + wasm_v128_store32_lane(__p, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_si64(void *__p, __m128i __a) +{ + wasm_v128_store64_lane(__p, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_si128(__m128i *__p, __m128i __a) +{ + // UB-free unaligned access copied from wasm_simd128.h + struct __mm_storeu_si128_struct { + __m128i __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __mm_storeu_si128_struct *)__p)->__v = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_maskmoveu_si128(__m128i __d, __m128i __n, char *__p) +{ + // TODO: optimize + union { + unsigned char x[16]; + __m128i m; + } mask, data; + mask.m = __n; + data.m = __d; + for(int i = 0; i < 16; ++i) + if (mask.x[i] & 0x80) + __p[i] = data.x[i]; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storel_epi64(__m128i *__p, __m128i __a) +{ + _mm_storeu_si64(__p, __a); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_stream_pd(double *__p, __m128d __a) +{ + // Emscripten/SIMD.js does not have cache hinting. + _mm_store_pd(__p, __a); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_stream_si128(__m128i *__p, __m128i __a) +{ + // Emscripten/SIMD.js does not have cache hinting. + _mm_store_si128(__p, __a); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_stream_si32(int *__p, int __a) +{ + // No cache hinting available. + *__p = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_stream_si64(long long *__p, long long __a) +{ + // No cache hinting available. + *__p = __a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_clflush(void const *__p) +{ + // Wasm SIMD does not have cache hinting +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_lfence(void) +{ + __sync_synchronize(); // Wasm/SharedArrayBuffer has only a full barrier instruction, which gives a stronger guarantee. +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_mfence(void) +{ + __sync_synchronize(); // Wasm/SharedArrayBuffer has only a full barrier instruction, which gives a stronger guarantee. +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_packs_epi16(__m128i __a, __m128i __b) +{ + return wasm_i8x16_narrow_i16x8(__a, __b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_packs_epi32(__m128i __a, __m128i __b) +{ + return wasm_i16x8_narrow_i32x4(__a, __b); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_packus_epi16(__m128i __a, __m128i __b) +{ + return wasm_u8x16_narrow_i16x8(__a, __b); +} + +#define _mm_extract_epi16(__a, __imm) wasm_u16x8_extract_lane((v128_t)(__a), (__imm) & 7) +#define _mm_insert_epi16(__a, __b, __imm) wasm_i16x8_replace_lane((__a), (__imm) & 7, (__b)) + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_movemask_epi8(__m128i __a) +{ + return (int)wasm_i8x16_bitmask((v128_t)__a); +} + +#define _mm_shuffle_epi32(__a, __imm) __extension__ ({ \ + (__m128i)wasm_i32x4_shuffle((__a), \ + _mm_set1_epi32(0), \ + ((__imm) & 0x3), (((__imm) & 0xc) >> 2), \ + (((__imm) & 0x30) >> 4), (((__imm) & 0xc0) >> 6)); }) + +#define _mm_shufflelo_epi16(__a, __imm) __extension__ ({ \ + (__m128i)wasm_i16x8_shuffle((__a), \ + _mm_set1_epi16(0), \ + ((__imm) & 0x3), (((__imm) & 0xc) >> 2), \ + (((__imm) & 0x30) >> 4), (((__imm) & 0xc0) >> 6), \ + 4, 5, 6, 7); }) + +#define _mm_shufflehi_epi16(__a, __imm) __extension__ ({ \ + (__m128i)wasm_i16x8_shuffle((__a), \ + _mm_set1_epi16(0), \ + 0, 1, 2, 3, \ + (4 + (((__imm) & 0x03) >> 0)), \ + (4 + (((__imm) & 0x0c) >> 2)), \ + (4 + (((__imm) & 0x30) >> 4)), \ + (4 + (((__imm) & 0xc0) >> 6))); }) + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_shuffle(__a, __b, 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_shuffle(__a, __b, 4, 12, 5, 13, 6, 14, 7, 15); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_shuffle(__a, __b, 2, 6, 3, 7); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i64x2_shuffle(__a, __b, 1, 3); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_epi8(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i8x16_shuffle(__a, __b, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_epi16(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i16x8_shuffle(__a, __b, 0, 8, 1, 9, 2, 10, 3, 11); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_epi32(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i32x4_shuffle(__a, __b, 0, 4, 1, 5); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_epi64(__m128i __a, __m128i __b) +{ + return (__m128i)wasm_i64x2_shuffle(__a, __b, 0, 2); +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_move_epi64(__m128i __a) +{ + return wasm_i64x2_shuffle(__a, wasm_i64x2_const(0, 0), 0, 2); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_i64x2_shuffle((v128_t)__a, (v128_t)__b, 1, 3); +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_pd(__m128d __a, __m128d __b) +{ + return (__m128d)wasm_i64x2_shuffle((v128_t)__a, (v128_t)__b, 0, 2); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_movemask_pd(__m128d __a) +{ + return (int)wasm_i64x2_bitmask((v128_t)__a); +} + +#define _mm_shuffle_pd(__a, __b, __i) __extension__ ({ \ + (__m128d) __builtin_shufflevector((__u64x2)(__a), (__u64x2)(__b), \ + (__i) & 1, \ + (((__i) & 2) >> 1) + 2); }) + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_castpd_ps(__m128d __a) +{ + return (__m128)__a; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_castpd_si128(__m128d __a) +{ + return (__m128i)__a; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_castps_pd(__m128 __a) +{ + return (__m128d)__a; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_castps_si128(__m128 __a) +{ + return (__m128i)__a; +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_castsi128_ps(__m128i __a) +{ + return (__m128)__a; +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_castsi128_pd(__m128i __a) +{ + return (__m128d)__a; +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_pause(void) +{ + // No pause/wait instruction in Wasm/SIMD. +} + +static __inline__ __m128d __attribute__((__always_inline__, __nodebug__)) +_mm_undefined_pd() +{ + __m128d val; + return val; +} + +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_undefined_si128() +{ + __m128i val; + return val; +} + +// Must be in the very end as it uses other SSE2 intrinsics +static __inline__ __m128i __attribute__((__always_inline__, __nodebug__)) +_mm_sad_epu8(__m128i __a, __m128i __b) +{ + __m128i __diff = _mm_or_si128(_mm_subs_epu8(__a, __b), + _mm_subs_epu8(__b, __a)); + __diff = _mm_add_epi16(_mm_srli_epi16(__diff, 8), + _mm_and_si128(__diff, _mm_set1_epi16(0x00FF))); + __diff = _mm_add_epi16(__diff, _mm_slli_epi32(__diff, 16)); + __diff = _mm_add_epi16(__diff, _mm_slli_epi64(__diff, 32)); + return _mm_srli_epi64(__diff, 48); +} + +#define _MM_SHUFFLE2(x, y) (((x) << 1) | (y)) + +#endif /* __emscripten_emmintrin_h__ */ diff --git a/fluxer_app/rust/libfluxwebp/simd/xmmintrin.h b/fluxer_app/rust/libfluxwebp/simd/xmmintrin.h new file mode 100644 index 000000000..4998bf5b0 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/simd/xmmintrin.h @@ -0,0 +1,714 @@ +/* + * Copyright 2020 The Emscripten Authors. All rights reserved. + * Emscripten is available under two separate licenses, the MIT license and the + * University of Illinois/NCSA Open Source License. Both these licenses can be + * found in the LICENSE file. + */ +#ifndef __emscripten_xmmintrin_h__ +#define __emscripten_xmmintrin_h__ + +#include + +#include +#include +#include + +#ifndef __SSE__ +#error "SSE instruction set not enabled" +#endif + +#ifdef WASM_SIMD_COMPAT_SLOW +#define DIAGNOSE_SLOW diagnose_if(1, "Instruction emulated via slow path.", "warning") +#else +#define DIAGNOSE_SLOW +#endif + +// Emscripten SIMD support doesn't support MMX/float32x2/__m64. +// However, we support loading and storing 2-vectors, so +// recognize the type at least. +typedef float __m64 __attribute__((__vector_size__(8), __aligned__(8))); +typedef __f32x4 __m128; +typedef v128_t __m128i; + +#define __f32x4_shuffle(__a, __b, __c0, __c1, __c2, __c3) \ + ((v128_t)(__builtin_shufflevector((__f32x4)(__a), (__f32x4)(__b), __c0, \ + __c1, __c2, __c3))) + +// This is defined as a macro because __builtin_shufflevector requires its +// mask argument to be a compile-time constant. +#define _mm_shuffle_ps(__a, __b, __mask) __extension__ ({ \ + ((__m128)__f32x4_shuffle(__a, __b, \ + (((__mask) >> 0) & 0x3) + 0, \ + (((__mask) >> 2) & 0x3) + 0, \ + (((__mask) >> 4) & 0x3) + 4, \ + (((__mask) >> 6) & 0x3) + 4)); }) + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_set_ps(float __z, float __y, float __x, float __w) +{ + return (__m128)wasm_f32x4_make(__w, __x, __y, __z); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_setr_ps(float __z, float __y, float __x, float __w) +{ + return (__m128)wasm_f32x4_make(__z, __y, __x, __w); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_set_ss(float __w) +{ + return (__m128)wasm_f32x4_make(__w, 0, 0, 0); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_set_ps1(float __w) +{ + return (__m128)wasm_f32x4_splat(__w); +} + +#define _mm_set1_ps _mm_set_ps1 + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_setzero_ps(void) +{ + return (__m128)wasm_f32x4_const(0.f, 0.f, 0.f, 0.f); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_load_ps(const float *__p) +{ + return *(__m128*)__p; +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_loadl_pi(__m128 __a, const void /*__m64*/ *__p) +{ + return (__m128)wasm_v128_load64_lane(__p, (v128_t)__a, 0); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_loadh_pi(__m128 __a, const void /*__m64*/ *__p) +{ + return (__m128)wasm_v128_load64_lane(__p, (v128_t)__a, 1); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_loadr_ps(const float *__p) +{ + __m128 __v = _mm_load_ps(__p); + return (__m128)__f32x4_shuffle(__v, __v, 3, 2, 1, 0); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_loadu_ps(const float *__p) +{ + return (__m128)wasm_v128_load(__p); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_load_ps1(const float *__p) +{ + return (__m128)wasm_v32x4_load_splat(__p); +} +#define _mm_load1_ps _mm_load_ps1 + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_load_ss(const float *__p) +{ + return (__m128)wasm_v128_load32_zero(__p); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_storel_pi(__m64 *__p, __m128 __a) +{ + wasm_v128_store64_lane((void*)__p, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_storeh_pi(__m64 *__p, __m128 __a) +{ + wasm_v128_store64_lane((void*)__p, (v128_t)__a, 1); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_ps(float *__p, __m128 __a) +{ + *(__m128 *)__p = __a; +} +// No NTA cache hint available. +#define _mm_stream_ps _mm_store_ps + +#define _MM_HINT_T0 3 +#define _MM_HINT_T1 2 +#define _MM_HINT_T2 1 +#define _MM_HINT_NTA 0 +// No prefetch available, dummy it out. +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_prefetch(const void *__p, int __i) +{ + ((void)__p); + ((void)__i); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_sfence(void) +{ + // Wasm/SharedArrayBuffer memory model is sequentially consistent. + // Perhaps a future version of the spec can provide a related fence. + __sync_synchronize(); +} + +#define _MM_SHUFFLE(w, z, y, x) (((w) << 6) | ((z) << 4) | ((y) << 2) | (x)) + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storer_ps(float *__p, __m128 __a) +{ + _mm_store_ps(__p, _mm_shuffle_ps(__a, __a, _MM_SHUFFLE(0, 1, 2, 3))); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_ps1(float *__p, __m128 __a) +{ + _mm_store_ps(__p, _mm_shuffle_ps(__a, __a, _MM_SHUFFLE(0, 0, 0, 0))); +} +#define _mm_store1_ps _mm_store_ps1 + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_store_ss(float *__p, __m128 __a) +{ + wasm_v128_store32_lane((void*)__p, (v128_t)__a, 0); +} + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_mm_storeu_ps(float *__p, __m128 __a) +{ + struct __unaligned { + __m128 __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __unaligned *)__p)->__v = __a; +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_movemask_ps(__m128 __a) +{ + return (int)wasm_i32x4_bitmask((v128_t)__a); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_move_ss(__m128 __a, __m128 __b) +{ + return (__m128)__f32x4_shuffle(__a, __b, 4, 1, 2, 3); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_add_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_add((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_add_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_add_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_sub_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_sub((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_sub_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_sub_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_mul_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_mul((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_mul_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_mul_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_div_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_div((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_div_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_div_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_min_ps(__m128 __a, __m128 __b) +{ +// return (__m128)wasm_f32x4_pmin((v128_t)__a, (v128_t)__b); // TODO: Migrate to this, once it works in VMs + return (__m128)wasm_v128_bitselect((v128_t)__a, (v128_t)__b, (v128_t)wasm_f32x4_lt((v128_t)__a, (v128_t)__b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_min_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_min_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_max_ps(__m128 __a, __m128 __b) +{ +// return (__m128)wasm_f32x4_pmax((v128_t)__a, (v128_t)__b); // TODO: Migrate to this, once it works in VMs + return (__m128)wasm_v128_bitselect((v128_t)__a, (v128_t)__b, (v128_t)wasm_f32x4_gt((v128_t)__a, (v128_t)__b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_max_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_max_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_rcp_ps(__m128 __a) +{ + return (__m128)wasm_f32x4_div((v128_t)_mm_set1_ps(1.0f), (v128_t)__a); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_rcp_ss(__m128 __a) +{ + return _mm_move_ss(__a, _mm_rcp_ps(__a)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_ps(__m128 __a) +{ + return (__m128)wasm_f32x4_sqrt((v128_t)__a); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_sqrt_ss(__m128 __a) +{ + return _mm_move_ss(__a, _mm_sqrt_ps(__a)); +} + +#define _mm_rsqrt_ps(__a) _mm_rcp_ps(_mm_sqrt_ps((__a))) + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_rsqrt_ss(__m128 __a) +{ + return _mm_move_ss(__a, _mm_rsqrt_ps(__a)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_unpackhi_ps(__m128 __a, __m128 __b) +{ + return (__m128)__f32x4_shuffle(__a, __b, 2, 6, 3, 7); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_unpacklo_ps(__m128 __a, __m128 __b) +{ + return (__m128)__f32x4_shuffle(__a, __b, 0, 4, 1, 5); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_movehl_ps(__m128 __a, __m128 __b) +{ + return (__m128)__f32x4_shuffle(__a, __b, 6, 7, 2, 3); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_movelh_ps(__m128 __a, __m128 __b) +{ + return (__m128)__f32x4_shuffle(__a, __b, 0, 1, 4, 5); +} + +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + __m128 __row0 = (row0); \ + __m128 __row1 = (row1); \ + __m128 __row2 = (row2); \ + __m128 __row3 = (row3); \ + __m128 __tmp0 = _mm_unpacklo_ps(__row0, __row1); \ + __m128 __tmp1 = _mm_unpackhi_ps(__row0, __row1); \ + __m128 __tmp2 = _mm_unpacklo_ps(__row2, __row3); \ + __m128 __tmp3 = _mm_unpackhi_ps(__row2, __row3); \ + (row0) = _mm_movelh_ps(__tmp0, __tmp2); \ + (row1) = _mm_movehl_ps(__tmp2, __tmp0); \ + (row2) = _mm_movelh_ps(__tmp1, __tmp3); \ + (row3) = _mm_movehl_ps(__tmp3, __tmp1); \ + } while (0) + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_lt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmplt_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmplt_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmple_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_le((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmple_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmple_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_eq((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpeq_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpeq_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpge_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_ge((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpge_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpge_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_gt((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpgt_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpgt_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cmpord_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_and(wasm_f32x4_eq((v128_t)__a, (v128_t)__a), + wasm_f32x4_eq((v128_t)__b, (v128_t)__b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cmpord_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpord_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cmpunord_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_or(wasm_f32x4_ne((v128_t)__a, (v128_t)__a), + wasm_f32x4_ne((v128_t)__b, (v128_t)__b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cmpunord_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpunord_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_and_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_and((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_andnot_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_andnot((v128_t)__b, (v128_t)__a); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_or_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_or((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_xor_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_xor((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpneq_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_f32x4_ne((v128_t)__a, (v128_t)__b); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpneq_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpneq_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnge_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_not((v128_t)_mm_cmpge_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnge_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpnge_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpngt_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_not((v128_t)_mm_cmpgt_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpngt_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpngt_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnle_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_not((v128_t)_mm_cmple_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnle_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpnle_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnlt_ps(__m128 __a, __m128 __b) +{ + return (__m128)wasm_v128_not((v128_t)_mm_cmplt_ps(__a, __b)); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_cmpnlt_ss(__m128 __a, __m128 __b) +{ + return _mm_move_ss(__a, _mm_cmpnlt_ps(__a, __b)); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comieq_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) == wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comige_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) >= wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comigt_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) > wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comile_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) <= wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comilt_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) < wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_comineq_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) != wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomieq_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) == wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomige_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) >= wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomigt_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) > wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomile_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) <= wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomilt_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) < wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_ucomineq_ss(__m128 __a, __m128 __b) +{ + return wasm_f32x4_extract_lane((v128_t)__a, 0) != wasm_f32x4_extract_lane((v128_t)__b, 0); +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_cvtsi32_ss(__m128 __a, int __b) +{ + __f32x4 __v = (__f32x4)__a; + __v[0] = (float)__b; + return (__m128)__v; +} +#define _mm_cvt_si2ss _mm_cvtsi32_ss + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cvtss_si32(__m128 __a) +{ + float e = ((__f32x4)__a)[0]; + if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabsf(e) < 2.f)) + return lrint(e); + else + return (int)0x80000000; +} +#define _mm_cvt_ss2si _mm_cvtss_si32 + +static __inline__ int __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) _mm_cvttss_si32(__m128 __a) +{ + float e = ((__f32x4)__a)[0]; + if (e < 2147483648.0f && e >= -2147483648.0f && (lrint(e) != 0 || fabsf(e) < 2.f)) + return (int)e; + else + return (int)0x80000000; +} +#define _mm_cvtt_ss2si _mm_cvttss_si32 + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_cvtsi64_ss(__m128 __a, long long __b) +{ + __f32x4 __v = (__f32x4)__a; + __v[0] = (float)__b; + return (__m128)__v; +} + +static __inline__ long long __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_cvtss_si64(__m128 __a) +{ + float e = ((__f32x4)__a)[0]; + long long x = llrintf(e); + if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabsf(e) < 2.f)) + return x; + else + return 0x8000000000000000LL; +} + +static __inline__ long long __attribute__((__always_inline__, __nodebug__, DIAGNOSE_SLOW)) +_mm_cvttss_si64(__m128 __a) +{ + float e = ((__f32x4)__a)[0]; + long long x = llrintf(e); + if (e <= LLONG_MAX && e >= LLONG_MIN && (x != 0 || fabsf(e) < 2.f)) + return (long long)e; + else + return 0x8000000000000000LL; +} + +static __inline__ float __attribute__((__always_inline__, __nodebug__)) +_mm_cvtss_f32(__m128 __a) +{ + return (float)((__f32x4)__a)[0]; +} + +#define _mm_malloc(__size, __align) memalign((__align), (__size)) +#define _mm_free free + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_undefined() +{ + __m128 val; + return val; +} + +static __inline__ __m128 __attribute__((__always_inline__, __nodebug__)) +_mm_undefined_ps() +{ + __m128 val; + return val; +} + +#define _MM_EXCEPT_MASK 0x003f +#define _MM_EXCEPT_INVALID 0x0001 +#define _MM_EXCEPT_DENORM 0x0002 +#define _MM_EXCEPT_DIV_ZERO 0x0004 +#define _MM_EXCEPT_OVERFLOW 0x0008 +#define _MM_EXCEPT_UNDERFLOW 0x0010 +#define _MM_EXCEPT_INEXACT 0x0020 + +#define _MM_MASK_MASK 0x1f80 +#define _MM_MASK_INVALID 0x0080 +#define _MM_MASK_DENORM 0x0100 +#define _MM_MASK_DIV_ZERO 0x0200 +#define _MM_MASK_OVERFLOW 0x0400 +#define _MM_MASK_UNDERFLOW 0x0800 +#define _MM_MASK_INEXACT 0x1000 + +#define _MM_ROUND_MASK 0x6000 +#define _MM_ROUND_NEAREST 0x0000 +#define _MM_ROUND_DOWN 0x2000 +#define _MM_ROUND_UP 0x4000 +#define _MM_ROUND_TOWARD_ZERO 0x6000 + +#define _MM_FLUSH_ZERO_MASK 0x8000 +#define _MM_FLUSH_ZERO_ON 0x8000 +#define _MM_FLUSH_ZERO_OFF 0x0000 + +static __inline__ int __attribute__((__always_inline__, __nodebug__)) +_mm_getcsr() +{ + return _MM_MASK_INEXACT | _MM_MASK_DENORM | _MM_MASK_DIV_ZERO | _MM_MASK_OVERFLOW | _MM_MASK_UNDERFLOW | _MM_MASK_INVALID + | _MM_ROUND_NEAREST | _MM_FLUSH_ZERO_OFF; +} + +#define _MM_GET_EXCEPTION_STATE() (_mm_getcsr() & _MM_EXCEPT_MASK) +#define _MM_GET_EXCEPTION_MASK() (_mm_getcsr() & _MM_MASK_MASK) +#define _MM_GET_ROUNDING_MODE() (_mm_getcsr() & _MM_ROUND_MASK) +#define _MM_GET_FLUSH_ZERO_MODE() (_mm_getcsr() & _MM_FLUSH_ZERO_MASK) + +// Unavailable functions: +// void _MM_SET_EXCEPTION_STATE(unsigned int __a); +// void _MM_SET_EXCEPTION_MASK(unsigned int __a); +// void _MM_GET_ROUNDING_MODE(unsigned int __a); +// void _MM_GET_FLUSH_ZERO_MODE(unsigned int __a); + +#endif /* __emscripten_xmmintrin_h__ */ diff --git a/fluxer_app/rust/libfluxwebp/src/lib.rs b/fluxer_app/rust/libfluxwebp/src/lib.rs new file mode 100644 index 000000000..e126a4980 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/src/lib.rs @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +mod shim; + +use libwebp_sys as ffi; +use std::ffi::CStr; +use std::ptr; +use wasm_bindgen::prelude::*; + +const DEMUX_ABI: i32 = ffi::WEBP_DEMUX_ABI_VERSION as i32; +const MUX_ABI: i32 = ffi::WEBP_MUX_ABI_VERSION as i32; +const ENCODER_ABI: i32 = ffi::WEBP_ENCODER_ABI_VERSION as i32; +const DECODER_ABI: i32 = ffi::WEBP_DECODER_ABI_VERSION as i32; +const LOSSLESS_FORMAT: i32 = 2; + +fn webp_data(bytes: &[u8]) -> ffi::WebPData { + ffi::WebPData { + bytes: bytes.as_ptr(), + size: bytes.len(), + } +} + +#[wasm_bindgen] +pub fn webp_probe(bytes: &[u8]) -> Result, JsError> { + let data = webp_data(bytes); + let dmux = unsafe { ffi::WebPDemuxInternal(&data, 0, ptr::null_mut(), DEMUX_ABI) }; + if dmux.is_null() { + return Err(JsError::new("webp demux failed")); + } + let get = |feature| unsafe { ffi::WebPDemuxGetI(dmux, feature) }; + let width = get(ffi::WebPFormatFeature::WEBP_FF_CANVAS_WIDTH); + let height = get(ffi::WebPFormatFeature::WEBP_FF_CANVAS_HEIGHT); + let frame_count = get(ffi::WebPFormatFeature::WEBP_FF_FRAME_COUNT); + let loop_count = get(ffi::WebPFormatFeature::WEBP_FF_LOOP_COUNT); + let flags = get(ffi::WebPFormatFeature::WEBP_FF_FORMAT_FLAGS); + let has_alpha = flags & ffi::WebPFeatureFlags::ALPHA_FLAG as u32 != 0; + let all_lossless = unsafe { all_frames_lossless(dmux) }; + unsafe { ffi::WebPDemuxDelete(dmux) }; + Ok(Box::new([ + width, + height, + frame_count, + loop_count, + has_alpha as u32, + all_lossless as u32, + ])) +} + +unsafe fn all_frames_lossless(dmux: *const ffi::WebPDemuxer) -> bool { + unsafe { + let mut iter: ffi::WebPIterator = std::mem::zeroed(); + if ffi::WebPDemuxGetFrame(dmux, 1, &mut iter) == 0 { + return false; + } + let mut lossless = true; + loop { + let mut features: ffi::WebPBitstreamFeatures = std::mem::zeroed(); + let status = ffi::WebPGetFeaturesInternal( + iter.fragment.bytes, + iter.fragment.size, + &mut features, + DECODER_ABI, + ); + if status != ffi::VP8StatusCode::VP8_STATUS_OK || features.format != LOSSLESS_FORMAT { + lossless = false; + break; + } + if ffi::WebPDemuxNextFrame(&mut iter) == 0 { + break; + } + } + ffi::WebPDemuxReleaseIterator(&mut iter); + lossless + } +} + +#[wasm_bindgen] +pub struct AnimDecoder { + dec: *mut ffi::WebPAnimDecoder, + _bytes: Box<[u8]>, + frame: *mut u8, + timestamp: i32, +} + +#[wasm_bindgen] +impl AnimDecoder { + #[wasm_bindgen(constructor)] + pub fn new(bytes: Box<[u8]>) -> Result { + let dec = unsafe { + let mut options: ffi::WebPAnimDecoderOptions = std::mem::zeroed(); + if ffi::WebPAnimDecoderOptionsInitInternal(&mut options, DEMUX_ABI) == 0 { + return Err(JsError::new("webp decoder options init failed")); + } + options.color_mode = ffi::WEBP_CSP_MODE::MODE_RGBA; + options.use_threads = 0; + let data = webp_data(&bytes); + ffi::WebPAnimDecoderNewInternal(&data, &options, DEMUX_ABI) + }; + if dec.is_null() { + return Err(JsError::new("webp decoder init failed")); + } + Ok(AnimDecoder { + dec, + _bytes: bytes, + frame: ptr::null_mut(), + timestamp: 0, + }) + } + + #[wasm_bindgen(js_name = next)] + pub fn next_frame(&mut self) -> Result { + if unsafe { ffi::WebPAnimDecoderHasMoreFrames(self.dec) } == 0 { + return Ok(false); + } + let mut frame = ptr::null_mut(); + let mut timestamp = 0; + if unsafe { ffi::WebPAnimDecoderGetNext(self.dec, &mut frame, &mut timestamp) } == 0 { + return Err(JsError::new("webp frame decode failed")); + } + self.frame = frame; + self.timestamp = timestamp; + Ok(true) + } + + #[wasm_bindgen(getter)] + pub fn frame_ptr(&self) -> u32 { + self.frame as usize as u32 + } + + #[wasm_bindgen(getter)] + pub fn end_timestamp(&self) -> i32 { + self.timestamp + } +} + +impl Drop for AnimDecoder { + fn drop(&mut self) { + unsafe { ffi::WebPAnimDecoderDelete(self.dec) }; + } +} + +#[wasm_bindgen] +pub struct AnimEncoder { + enc: *mut ffi::WebPAnimEncoder, + width: u32, + height: u32, + lossless: bool, +} + +#[wasm_bindgen] +impl AnimEncoder { + #[wasm_bindgen(constructor)] + pub fn new( + width: u32, + height: u32, + loop_count: u32, + lossless: bool, + ) -> Result { + let (kmin, kmax) = if lossless { (9, 17) } else { (4, 5) }; + let enc = unsafe { + let mut options: ffi::WebPAnimEncoderOptions = std::mem::zeroed(); + if ffi::WebPAnimEncoderOptionsInitInternal(&mut options, MUX_ABI) == 0 { + return Err(JsError::new("webp encoder options init failed")); + } + options.anim_params.loop_count = loop_count.min(i32::MAX as u32) as i32; + options.anim_params.bgcolor = 0; + options.minimize_size = 0; + options.allow_mixed = 0; + options.kmin = kmin; + options.kmax = kmax; + ffi::WebPAnimEncoderNewInternal(width as i32, height as i32, &options, MUX_ABI) + }; + if enc.is_null() { + return Err(JsError::new("webp encoder init failed")); + } + Ok(AnimEncoder { + enc, + width, + height, + lossless, + }) + } + + pub fn add( + &mut self, + rgba: &[u8], + start_ms: i32, + quality: f32, + method: i32, + ) -> Result<(), JsError> { + if rgba.len() as u64 != u64::from(self.width) * u64::from(self.height) * 4 { + return Err(JsError::new("webp frame size mismatch")); + } + let added = unsafe { + let mut config: ffi::WebPConfig = std::mem::zeroed(); + if ffi::WebPConfigInitInternal( + &mut config, + ffi::WebPPreset::WEBP_PRESET_DEFAULT, + quality, + ENCODER_ABI, + ) == 0 + { + return Err(JsError::new("webp config init failed")); + } + config.quality = quality; + config.method = method; + config.lossless = self.lossless as i32; + config.thread_level = 0; + config.alpha_quality = 100; + config.exact = 0; + config.use_sharp_yuv = 0; + let mut picture: ffi::WebPPicture = std::mem::zeroed(); + if ffi::WebPPictureInitInternal(&mut picture, ENCODER_ABI) == 0 { + return Err(JsError::new("webp picture init failed")); + } + picture.width = self.width as i32; + picture.height = self.height as i32; + picture.use_argb = 1; + if ffi::WebPPictureImportRGBA(&mut picture, rgba.as_ptr(), self.width as i32 * 4) == 0 { + ffi::WebPPictureFree(&mut picture); + return Err(JsError::new("webp picture import failed")); + } + let added = ffi::WebPAnimEncoderAdd(self.enc, &mut picture, start_ms, &config); + ffi::WebPPictureFree(&mut picture); + added + }; + if added == 0 { + return Err(self.error("webp frame encode failed")); + } + Ok(()) + } + + pub fn finish(&mut self, end_ms: i32) -> Result, JsError> { + if unsafe { ffi::WebPAnimEncoderAdd(self.enc, ptr::null_mut(), end_ms, ptr::null()) } == 0 { + return Err(self.error("webp encoder flush failed")); + } + let mut data = ffi::WebPData::default(); + if unsafe { ffi::WebPAnimEncoderAssemble(self.enc, &mut data) } == 0 { + return Err(self.error("webp assemble failed")); + } + let out = unsafe { std::slice::from_raw_parts(data.bytes, data.size) }.to_vec(); + unsafe { ffi::WebPFree(data.bytes as *mut _) }; + Ok(out) + } + + fn error(&self, what: &str) -> JsError { + let message = unsafe { ffi::WebPAnimEncoderGetError(self.enc) }; + if message.is_null() { + return JsError::new(what); + } + let detail = unsafe { CStr::from_ptr(message) }.to_string_lossy(); + JsError::new(&format!("{what}: {detail}")) + } +} + +impl Drop for AnimEncoder { + fn drop(&mut self) { + unsafe { ffi::WebPAnimEncoderDelete(self.enc) }; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn frame(width: u32, height: u32, seed: u8) -> Vec { + (0..width * height) + .flat_map(|index| { + let value = (index as u8).wrapping_mul(seed); + [ + value, + seed, + value ^ seed, + if index % 3 == 0 { 0 } else { 255 }, + ] + }) + .collect() + } + + fn encode(lossless: bool) -> Vec { + let mut encoder = AnimEncoder::new(16, 8, 3, lossless).expect("encoder"); + let delays = [40, 70, 10]; + let mut start = 0; + for (index, delay) in delays.iter().enumerate() { + encoder + .add(&frame(16, 8, index as u8 + 1), start, 75.0, 4) + .expect("add"); + start += delay; + } + encoder.finish(start).expect("finish") + } + + #[test] + fn probe_reports_canvas_frames_loop_alpha_and_lossless() { + let lossless = encode(true); + assert_eq!( + &*webp_probe(&lossless).expect("probe"), + &[16, 8, 3, 3, 1, 1] + ); + let lossy = encode(false); + let probe = webp_probe(&lossy).expect("probe"); + assert_eq!(&probe[..5], &[16, 8, 3, 3, 1]); + assert_eq!(probe[5], 0); + } + + #[test] + fn lossless_round_trip_keeps_pixels_and_end_timestamps() { + let bytes = encode(true); + let mut decoder = AnimDecoder::new(bytes.into_boxed_slice()).expect("decoder"); + let mut ends = Vec::new(); + let mut index = 0u8; + while decoder.next_frame().expect("next") { + let pixels = unsafe { std::slice::from_raw_parts(decoder.frame, 16 * 8 * 4) }; + let expected = frame(16, 8, index + 1); + for (got, want) in pixels.chunks(4).zip(expected.chunks(4)) { + assert_eq!(got[3], want[3]); + if want[3] != 0 { + assert_eq!(got, want); + } + } + ends.push(decoder.end_timestamp()); + index += 1; + } + assert_eq!(ends, [40, 110, 120]); + } +} diff --git a/fluxer_app/rust/libfluxwebp/src/shim.rs b/fluxer_app/rust/libfluxwebp/src/shim.rs new file mode 100644 index 000000000..f7997a5b5 --- /dev/null +++ b/fluxer_app/rust/libfluxwebp/src/shim.rs @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +use std::alloc::{Layout, alloc, alloc_zeroed, dealloc}; +use std::ffi::{c_int, c_void}; + +const ALIGN: usize = 16; + +unsafe fn shim_alloc(size: usize, zeroed: bool) -> *mut c_void { + let Some(full) = size.checked_add(ALIGN) else { + return std::ptr::null_mut(); + }; + let Ok(layout) = Layout::from_size_align(full, ALIGN) else { + return std::ptr::null_mut(); + }; + unsafe { + let ptr = if zeroed { + alloc_zeroed(layout) + } else { + alloc(layout) + }; + if ptr.is_null() { + return std::ptr::null_mut(); + } + ptr.cast::().write(full); + ptr.add(ALIGN).cast() + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn fluxwebp_shim_malloc(size: usize) -> *mut c_void { + unsafe { shim_alloc(size, false) } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn fluxwebp_shim_calloc(nmemb: usize, size: usize) -> *mut c_void { + match nmemb.checked_mul(size) { + Some(total) => unsafe { shim_alloc(total, true) }, + None => std::ptr::null_mut(), + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn fluxwebp_shim_free(ptr: *mut c_void) { + if ptr.is_null() { + return; + } + unsafe { + let base = ptr.cast::().sub(ALIGN); + let full = base.cast::().read(); + dealloc(base, Layout::from_size_align_unchecked(full, ALIGN)); + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn fluxwebp_shim_qsort( + base: *mut c_void, + n: usize, + size: usize, + compar: unsafe extern "C" fn(*const c_void, *const c_void) -> c_int, +) { + if n < 2 || size == 0 { + return; + } + unsafe { + let bytes = std::slice::from_raw_parts_mut(base.cast::(), n * size); + let copy = bytes.to_vec(); + let mut idx: Vec = (0..n).collect(); + idx.sort_by(|&a, &b| { + let r = compar( + copy.as_ptr().add(a * size).cast(), + copy.as_ptr().add(b * size).cast(), + ); + r.cmp(&0) + }); + for (dst, &src) in idx.iter().enumerate() { + bytes[dst * size..dst * size + size] + .copy_from_slice(©[src * size..src * size + size]); + } + } +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_pow(x: f64, y: f64) -> f64 { + x.powf(y) +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_log(x: f64) -> f64 { + x.ln() +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_log10(x: f64) -> f64 { + x.log10() +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_expf(x: f32) -> f32 { + x.exp() +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_logf(x: f32) -> f32 { + x.ln() +} + +#[unsafe(no_mangle)] +pub extern "C" fn fluxwebp_shim_round(x: f64) -> f64 { + x.round() +} diff --git a/fluxer_app/scripts/build/rspack/static-files.mjs b/fluxer_app/scripts/build/rspack/static-files.mjs index 70da903cc..cd938d69a 100644 --- a/fluxer_app/scripts/build/rspack/static-files.mjs +++ b/fluxer_app/scripts/build/rspack/static-files.mjs @@ -11,6 +11,18 @@ const FONT_LICENSE_FILES = [ {source: 'LICENSE-IBM-PLEX.txt', asset: 'assets/fonts-LICENSE-IBM-PLEX.txt'}, ]; +const WASM_LICENSE_FILES = [ + {source: 'libfluxcore/NOTICE.md', asset: 'assets/libfluxcore-NOTICE.txt'}, + {source: 'libfluxcore/LICENSE-ZSTD.txt', asset: 'assets/libfluxcore-LICENSE-ZSTD.txt'}, + {source: 'libfluxcore/LICENSE-ZSTD-SYS.txt', asset: 'assets/libfluxcore-LICENSE-ZSTD-SYS.txt'}, + {source: 'libfluxcore/LICENSE-ZSTD-RS.txt', asset: 'assets/libfluxcore-LICENSE-ZSTD-RS.txt'}, + {source: 'libfluxwebp/NOTICE.md', asset: 'assets/libfluxwebp-NOTICE.txt'}, + {source: 'libfluxwebp/LICENSE-LIBWEBP.txt', asset: 'assets/libfluxwebp-LICENSE-LIBWEBP.txt'}, + {source: 'libfluxwebp/PATENTS-LIBWEBP.txt', asset: 'assets/libfluxwebp-PATENTS-LIBWEBP.txt'}, + {source: 'libfluxwebp/LICENSE-LIBWEBP-SYS.txt', asset: 'assets/libfluxwebp-LICENSE-LIBWEBP-SYS.txt'}, + {source: 'libfluxwebp/simd/LICENSE', asset: 'assets/libfluxwebp-LICENSE-EMSCRIPTEN.txt'}, +]; + function resolveStaticCdnEndpoint(staticCdnEndpoint) { const value = staticCdnEndpoint?.trim().replace(/\/+$/, ''); return value || STATIC_CDN_ENDPOINT_PLACEHOLDER; @@ -86,17 +98,18 @@ export class StaticFilesPlugin { constructor(options = {}) { this.staticCdnEndpoint = options.staticCdnEndpoint; this.fontsDir = options.fontsDir; + this.wasmCratesDir = options.wasmCratesDir; } - emitFontLicenses(compilation) { - if (!this.fontsDir) { + emitLicenseFiles(compilation, dir, files, subject) { + if (!dir) { return; } - for (const {source, asset} of FONT_LICENSE_FILES) { - const sourcePath = path.join(this.fontsDir, source); + for (const {source, asset} of files) { + const sourcePath = path.join(dir, source); if (!fs.existsSync(sourcePath)) { throw new Error( - `StaticFilesPlugin: ${sourcePath} is missing. The bundled fonts may not be redistributed without it.`, + `StaticFilesPlugin: ${sourcePath} is missing. The bundled ${subject} may not be redistributed without it.`, ); } compilation.emitAsset(asset, new sources.RawSource(fs.readFileSync(sourcePath))); @@ -117,7 +130,8 @@ export class StaticFilesPlugin { new sources.RawSource(generateBrowserConfig(this.staticCdnEndpoint)), ); compilation.emitAsset('robots.txt', new sources.RawSource(generateRobotsTxt())); - this.emitFontLicenses(compilation); + this.emitLicenseFiles(compilation, this.fontsDir, FONT_LICENSE_FILES, 'fonts'); + this.emitLicenseFiles(compilation, this.wasmCratesDir, WASM_LICENSE_FILES, 'WebAssembly modules'); }, ); }); diff --git a/fluxer_app/src/features/channel/components/modals/EditGroupBottomSheet.tsx b/fluxer_app/src/features/channel/components/modals/EditGroupBottomSheet.tsx index 8c92f2384..21d7a7bd2 100644 --- a/fluxer_app/src/features/channel/components/modals/EditGroupBottomSheet.tsx +++ b/fluxer_app/src/features/channel/components/modals/EditGroupBottomSheet.tsx @@ -33,7 +33,7 @@ import {Form} from '@app/features/ui/components/form/Form'; import {Input} from '@app/features/ui/components/form/FormInput'; import {Scroller} from '@app/features/ui/components/Scroller'; import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; -import {canCropFormat} from '@app/features/voice/utils/MediaCapabilities'; +import {canCropFile} from '@app/features/voice/utils/MediaCapabilities'; import {useRemoteFormReset} from '@app/lib/forms/RemoteFormReset'; import {assignTransientUploadFieldMutation} from '@app/lib/forms/TransientUploadFields'; import {msg} from '@lingui/core/macro'; @@ -136,7 +136,7 @@ export const EditGroupBottomSheet: React.FC = observe return; } const svg = isSvgFile(file); - if (!svg && !(await canCropFormat(file.type))) { + if (!svg && !(await canCropFile(file))) { showChannelErrorModal({ title: i18n._(UNSUPPORTED_ICON_FORMAT_DESCRIPTOR), message: getAssetFormatErrorMessage(i18n, 'guild_icon', 'unsupported_mime'), @@ -159,7 +159,6 @@ export const EditGroupBottomSheet: React.FC = observe { const reader = new FileReader(); reader.onload = () => { diff --git a/fluxer_app/src/features/channel/components/modals/EditGroupModal.tsx b/fluxer_app/src/features/channel/components/modals/EditGroupModal.tsx index 7169fbba2..f69603c06 100644 --- a/fluxer_app/src/features/channel/components/modals/EditGroupModal.tsx +++ b/fluxer_app/src/features/channel/components/modals/EditGroupModal.tsx @@ -32,7 +32,7 @@ import * as ToastCommands from '@app/features/ui/commands/ToastCommands'; import {Form} from '@app/features/ui/components/form/Form'; import {Input} from '@app/features/ui/components/form/FormInput'; import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; -import {canCropFormat} from '@app/features/voice/utils/MediaCapabilities'; +import {canCropFile} from '@app/features/voice/utils/MediaCapabilities'; import {useRemoteFormReset} from '@app/lib/forms/RemoteFormReset'; import {assignTransientUploadFieldMutation} from '@app/lib/forms/TransientUploadFields'; import {msg} from '@lingui/core/macro'; @@ -127,7 +127,7 @@ export const EditGroupModal = observer(({channelId}: {channelId: string}) => { return; } const svg = isSvgFile(file); - if (!svg && !(await canCropFormat(file.type))) { + if (!svg && !(await canCropFile(file))) { showChannelErrorModal({ title: i18n._(UNSUPPORTED_ICON_FORMAT_DESCRIPTOR), message: getAssetFormatErrorMessage(i18n, 'guild_icon', 'unsupported_mime'), @@ -150,7 +150,6 @@ export const EditGroupModal = observer(({channelId}: {channelId: string}) => { { const reader = new FileReader(); reader.onload = () => { diff --git a/fluxer_app/src/features/expressions/components/modals/AssetCropModal.tsx b/fluxer_app/src/features/expressions/components/modals/AssetCropModal.tsx index 9131900d1..244983960 100644 --- a/fluxer_app/src/features/expressions/components/modals/AssetCropModal.tsx +++ b/fluxer_app/src/features/expressions/components/modals/AssetCropModal.tsx @@ -218,7 +218,7 @@ export const getAssetAspectRatioRange = (type: AssetType) => { }; export const clampAssetAspectRatio = (type: AssetType, aspectRatio: number | undefined): number | undefined => clampAspectRatio(aspectRatio, getAssetAspectRatioRange(type)); -export const canSkipOriginalAssetImage = (type: AssetType, dimensions: ImageDimensions): boolean => { +const canSkipOriginalAssetImage = (type: AssetType, dimensions: ImageDimensions): boolean => { const config = getAssetConfig(type); return isOriginalImageWithinAssetBounds( dimensions, @@ -298,20 +298,18 @@ const getErrorMessage = (i18n: I18n, assetType: AssetType): string => { interface AssetCropModalProps { imageUrl: string; - sourceMimeType: string; assetType: AssetType; onCropComplete: (croppedImageBlob: Blob) => void; onSkip?: () => void; } export const AssetCropModal: React.FC = observer( - ({imageUrl, sourceMimeType, assetType, onCropComplete, onSkip}) => { + ({imageUrl, assetType, onCropComplete, onSkip}) => { const {i18n} = useLingui(); const config = getAssetConfig(assetType); return ( ( - Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead. - - } + message={i18n._(BROWSER_CAN_T_CROP_ANIMATED_DESCRIPTOR, {avifFormatLabel: AVIF_FORMAT_LABEL})} data-flx="expressions.animated-avif-modal-utils.show-animated-avif-unsupported-modal.confirm-modal" /> )), diff --git a/fluxer_app/src/features/expressions/utils/AnimatedImageUtils.ts b/fluxer_app/src/features/expressions/utils/AnimatedImageUtils.ts index 2912e1a1e..2cd94f9d6 100644 --- a/fluxer_app/src/features/expressions/utils/AnimatedImageUtils.ts +++ b/fluxer_app/src/features/expressions/utils/AnimatedImageUtils.ts @@ -1,90 +1,35 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -const GIF_EXT = '.gif'; -const WEBP_EXT = '.webp'; -const PNG_EXT = '.png'; -const AVIF_EXT = '.avif'; +export type InspectedImageFormat = 'unknown' | 'png' | 'gif' | 'webp' | 'avif' | 'jpeg'; -export type AnimatedImageFormat = 'gif' | 'webp' | 'avif' | 'apng'; +export interface InspectedImage { + format: InspectedImageFormat; + animated: boolean; +} -function getFileExtension(file: File): string { - const name = (file.name || '').toLowerCase(); - const dotIndex = name.lastIndexOf('.'); - return dotIndex === -1 ? '' : name.substring(dotIndex); +const SNIFFED_FORMATS: ReadonlyArray = ['unknown', 'png', 'gif', 'webp', 'avif', 'jpeg']; + +export async function inspectImageBytes(bytes: Uint8Array): Promise { + try { + const {detectAnimatedImage, sniffImageFormat} = await import('@app/features/platform/utils/LibFluxcore'); + const format = SNIFFED_FORMATS[await sniffImageFormat(bytes)] ?? 'unknown'; + if (format === 'unknown' || format === 'jpeg') { + return {format, animated: false}; + } + return {format, animated: await detectAnimatedImage(bytes)}; + } catch { + return {format: 'unknown', animated: false}; + } +} + +export async function inspectImageFile(file: File): Promise { + try { + return await inspectImageBytes(new Uint8Array(await file.arrayBuffer())); + } catch { + return {format: 'unknown', animated: false}; + } } export async function isAnimatedFile(file: File): Promise { - try { - const arrayBuffer = await file.arrayBuffer(); - const {detectAnimatedImage} = await import('@app/features/platform/utils/LibFluxcore'); - return await detectAnimatedImage(new Uint8Array(arrayBuffer)); - } catch { - return false; - } -} - -export function getAnimatedFormatLabel(file: File): string | null { - const mime = (file.type || '').toLowerCase(); - const ext = getFileExtension(file); - if (mime.includes('gif') || ext === GIF_EXT) { - return 'GIF'; - } - if (mime.includes('webp') || ext === WEBP_EXT) { - return 'WebP'; - } - if (mime.includes('png') || ext === PNG_EXT) { - return 'APNG'; - } - if (mime.includes('avif') || ext === AVIF_EXT) { - return 'AVIF'; - } - return null; -} - -export function getAnimatedImageFormat(mime: string, ext?: string): AnimatedImageFormat { - const lowerMime = mime.toLowerCase(); - const lowerExt = ext?.toLowerCase() || ''; - if (lowerMime.includes('gif') || lowerExt === '.gif') { - return 'gif'; - } - if (lowerMime.includes('webp') || lowerExt === '.webp') { - return 'webp'; - } - if (lowerMime.includes('avif') || lowerExt === '.avif') { - return 'avif'; - } - if (lowerMime.includes('png') || lowerExt === '.png') { - return 'apng'; - } - return 'gif'; -} - -export interface HandleAnimatedNonGifOptions { - file: File; - isGif: boolean; - animated: boolean; - onAnimatedAvif: () => void; - onOtherAnimated: () => void; -} - -export function shouldHandleAnimatedNonGifUpload({ - file, - isGif, - animated, - onAnimatedAvif, - onOtherAnimated, -}: HandleAnimatedNonGifOptions): boolean { - if (!animated) { - return false; - } - const format = getAnimatedImageFormat(file.type); - if (isGif || format === 'gif' || format === 'apng') { - return false; - } - if (format === 'avif') { - onAnimatedAvif(); - return true; - } - onOtherAnimated(); - return true; + return (await inspectImageFile(file)).animated; } diff --git a/fluxer_app/src/features/expressions/utils/ImageUploadFileUtils.ts b/fluxer_app/src/features/expressions/utils/ImageUploadFileUtils.ts index f90b0f06c..8b8f69ae9 100644 --- a/fluxer_app/src/features/expressions/utils/ImageUploadFileUtils.ts +++ b/fluxer_app/src/features/expressions/utils/ImageUploadFileUtils.ts @@ -19,13 +19,6 @@ export function isSvgFile(file: ImageUploadFileLike): boolean { return (file.name ?? '').toLowerCase().endsWith('.svg'); } -export function getImageUploadMimeType(file: ImageUploadFileLike): string { - if (isSvgFile(file)) return 'image/svg+xml'; - const type = normalizeImageMimeType(file.type); - if (type.startsWith('image/')) return type; - return 'image/png'; -} - function readBlobAsDataUrl(blob: Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); diff --git a/fluxer_app/src/features/expressions/workers/AnimatedCropPlan.ts b/fluxer_app/src/features/expressions/workers/AnimatedCropPlan.ts new file mode 100644 index 000000000..e0fa9318a --- /dev/null +++ b/fluxer_app/src/features/expressions/workers/AnimatedCropPlan.ts @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { + type AnimatedCropSourceFormat, + type CropParams, + CropPipelineError, +} from '@app/features/expressions/workers/AnimatedImageCropMessages'; + +export const MAX_SOURCE_CANVAS_PIXELS = 16_777_216; +export const MAX_FRAMES = 20_000; +export const MAX_OUTPUT_TOTAL_PIXELS = 1_073_741_824; +export const MAX_SOURCE_TOTAL_PIXELS = 1_073_741_824; +export const MAX_PLAYS = 65_535; +export const LOSSLESS_MAX_WORK_PIXELS = 16_777_216; + +export const QUALITY_RUNGS: ReadonlyArray = [75, 60, 45, 30]; +export const SIZE_RATIO: ReadonlyArray = [1, 0.889, 0.782, 0.595]; + +const LADDER_TARGET_FRACTION = 0.95; +const LADDER_GIVE_UP_FRACTION = 1.15; +const DEFAULT_AVIF_DELAY_MS = 100; + +export interface EncodeRung { + quality: number; + method: number; + lossless: boolean; +} + +export const LOSSLESS_RUNG: EncodeRung = {quality: 75, method: 4, lossless: true}; + +export function chooseMethod(workPixels: number): number { + if (workPixels <= 67_108_864) return 4; + if (workPixels <= 268_435_456) return 2; + return 0; +} + +export function lossyRung(index: number, method: number): EncodeRung { + return {quality: QUALITY_RUNGS[index], method, lossless: false}; +} + +export function nextRung(index: number, sizeBytes: number, capBytes: number): number | 'too_large' { + const last = QUALITY_RUNGS.length - 1; + if (index >= last) return 'too_large'; + const target = LADDER_TARGET_FRACTION * capBytes; + for (let candidate = index + 1; candidate <= last; candidate++) { + if ((sizeBytes * SIZE_RATIO[candidate]) / SIZE_RATIO[index] <= target) return candidate; + } + if ((sizeBytes * SIZE_RATIO[last]) / SIZE_RATIO[index] > LADDER_GIVE_UP_FRACTION * capBytes) return 'too_large'; + return last; +} + +export function usesLosslessFirstRung(sourceLossless: boolean, workPixels: number): boolean { + return sourceLossless && workPixels <= LOSSLESS_MAX_WORK_PIXELS; +} + +export function assertSourceBudget(width: number, height: number, frameCount: number): void { + if (!(width > 0 && height > 0 && frameCount > 0)) { + throw new CropPipelineError( + 'decode_failed', + `Invalid animation header ${width}x${height} with ${frameCount} frames`, + ); + } + if (width * height > MAX_SOURCE_CANVAS_PIXELS) { + throw new CropPipelineError('budget_exceeded', `Canvas ${width}x${height} is larger than the decode budget`); + } + if (frameCount > MAX_FRAMES) { + throw new CropPipelineError('budget_exceeded', `${frameCount} frames is more than ${MAX_FRAMES}`); + } + if (frameCount * width * height > MAX_SOURCE_TOTAL_PIXELS) { + throw new CropPipelineError( + 'budget_exceeded', + `${frameCount} frames at ${width}x${height} is too much decode work`, + ); + } +} + +export function assertOutputBudget(frameCount: number, outputWidth: number, outputHeight: number): void { + if (!(outputWidth > 0 && outputHeight > 0)) { + throw new CropPipelineError('internal', `Invalid output size ${outputWidth}x${outputHeight}`); + } + if (frameCount * outputWidth * outputHeight > MAX_OUTPUT_TOTAL_PIXELS) { + throw new CropPipelineError( + 'budget_exceeded', + `${frameCount} frames at ${outputWidth}x${outputHeight} is too much output`, + ); + } +} + +export function isNoopCrop( + crop: CropParams, + canvasWidth: number, + canvasHeight: number, + format: AnimatedCropSourceFormat, + sourceBytes: number, + capBytes: number, +): boolean { + return ( + (format === 'gif' || format === 'webp') && + crop.x === 0 && + crop.y === 0 && + crop.width === canvasWidth && + crop.height === canvasHeight && + crop.rotation === 0 && + crop.outputWidth === canvasWidth && + crop.outputHeight === canvasHeight && + sourceBytes <= capBytes + ); +} + +export function clampPlays(plays: number): number { + return Math.min(Math.max(Math.trunc(plays), 0), MAX_PLAYS); +} + +export function gifPlaysFromRepeat(repeat: number | null): number { + if (repeat === null) return 1; + if (repeat === 0) return 0; + return clampPlays(repeat + 1); +} + +export function gifRepeatFromPlays(plays: number): number { + if (plays === 1) return -1; + if (plays === 0) return 0; + return clampPlays(plays - 1); +} + +export function avifPlaysFromRepetitionCount(repetitionCount: number | undefined): number { + if (repetitionCount === undefined || !Number.isFinite(repetitionCount)) return 0; + return clampPlays(repetitionCount + 1); +} + +export function apngDelayMs(numerator: number, denominator: number): number { + return (numerator * 1000) / (denominator || 100); +} + +export function avifDelayMs(durationMicros: number | null): number { + return durationMicros == null ? DEFAULT_AVIF_DELAY_MS : durationMicros / 1000; +} diff --git a/fluxer_app/src/features/expressions/workers/AnimatedFrameCodecs.ts b/fluxer_app/src/features/expressions/workers/AnimatedFrameCodecs.ts new file mode 100644 index 000000000..ff5ef9501 --- /dev/null +++ b/fluxer_app/src/features/expressions/workers/AnimatedFrameCodecs.ts @@ -0,0 +1,662 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { + apngDelayMs, + assertSourceBudget, + avifDelayMs, + avifPlaysFromRepetitionCount, + clampPlays, + gifPlaysFromRepeat, + gifRepeatFromPlays, + MAX_SOURCE_CANVAS_PIXELS, +} from '@app/features/expressions/workers/AnimatedCropPlan'; +import {CropPipelineError} from '@app/features/expressions/workers/AnimatedImageCropMessages'; +import { + canDecodeAnimatedAvif, + closeImageDecoder, + drawVideoFrameToCanvas, + type FluxerImageDecoderDecodedFrame, + getImageDecoderConstructor, +} from '@app/features/platform/utils/ImageDecoderInterop'; +import {Unzlib} from 'fflate'; +import {GIFEncoder, type GifPaletteColor} from 'gifenc'; +import {decompressFrame, type ParsedGif, parseGIF} from 'gifuct-js'; +import UPNG from 'upng-js'; + +export interface DecodedFrame { + rgba: Uint8Array; + delayMs: number; +} + +export interface FrameSource { + width: number; + height: number; + frameCount: number; + plays: number; + next(): DecodedFrame | null | Promise; + close(): void; +} + +export interface GifFrameSink { + add(rgba: Uint8Array, delayMs: number): boolean; + finish(): Uint8Array; + close(): void; +} + +interface Rect { + x: number; + y: number; + width: number; + height: number; +} + +type GifBlock = ParsedGif['frames'][number]; +type GifImageBlock = Extract; + +const PNG_SIGNATURE = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); +const GIF_EXTENSION_INTRODUCER = 0x21; +const GIF_APPLICATION_LABEL = 0xff; +const GIF_LOOP_APPLICATIONS = new Set(['NETSCAPE2.0', 'ANIMEXTS1.0']); +const GIF_MAX_DELAY_CS = 0xffff; +const GIF_TRANSPARENT_INDEX = 0; +const GIF_MAX_OPAQUE_COLORS = 255; +const GIF_MAX_LZW_CODE_SIZE = 11; +const GIF_VERSION_87_MINOR = 0x37; +const APNG_DISPOSE_BACKGROUND = 1; +const APNG_DISPOSE_PREVIOUS = 2; +const APNG_BLEND_OVER = 1; +const PNG_CHANNELS: Readonly> = {0: 1, 2: 3, 3: 1, 4: 2, 6: 4}; +const ADAM7_PASSES: ReadonlyArray = [ + [0, 0, 8, 8], + [4, 0, 8, 8], + [0, 4, 4, 8], + [2, 0, 4, 4], + [0, 2, 2, 4], + [1, 0, 2, 2], + [0, 1, 1, 2], +]; +const INFLATE_SLICE_BYTES = 16_384; +const INFLATE_SLACK_BYTES = 65_536; + +function decodeFailed(message: string): CropPipelineError { + return new CropPipelineError('decode_failed', message); +} + +function toArrayBuffer(bytes: Uint8Array): ArrayBuffer { + if (bytes.buffer instanceof ArrayBuffer && bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength) { + return bytes.buffer; + } + return bytes.slice().buffer; +} + +function clipRect(rect: Rect, canvasWidth: number, canvasHeight: number): Rect { + const x = Math.min(rect.x, canvasWidth); + const y = Math.min(rect.y, canvasHeight); + return { + x, + y, + width: Math.max(0, Math.min(rect.x + rect.width, canvasWidth) - x), + height: Math.max(0, Math.min(rect.y + rect.height, canvasHeight) - y), + }; +} + +function clearRect(canvas: Uint8Array, canvasWidth: number, rect: Rect): void { + for (let row = 0; row < rect.height; row++) { + const start = ((rect.y + row) * canvasWidth + rect.x) * 4; + canvas.fill(0, start, start + rect.width * 4); + } +} + +function saveRect(canvas: Uint8Array, canvasWidth: number, rect: Rect): Uint8Array { + const saved = new Uint8Array(rect.width * rect.height * 4); + for (let row = 0; row < rect.height; row++) { + const start = ((rect.y + row) * canvasWidth + rect.x) * 4; + saved.set(canvas.subarray(start, start + rect.width * 4), row * rect.width * 4); + } + return saved; +} + +function restoreRect(canvas: Uint8Array, canvasWidth: number, rect: Rect, saved: Uint8Array): void { + for (let row = 0; row < rect.height; row++) { + const start = ((rect.y + row) * canvasWidth + rect.x) * 4; + canvas.set(saved.subarray(row * rect.width * 4, (row + 1) * rect.width * 4), start); + } +} + +function readGifRepeat(bytes: Uint8Array): number | null { + let pos = 13; + if (bytes[10] & 0x80) pos += 3 * (2 << (bytes[10] & 0x07)); + while (pos + 1 < bytes.length && bytes[pos] === GIF_EXTENSION_INTRODUCER) { + const label = bytes[pos + 1]; + pos += 2; + let isLoopApplication = false; + if (label === GIF_APPLICATION_LABEL && pos < bytes.length) { + const blockSize = bytes[pos]; + isLoopApplication = GIF_LOOP_APPLICATIONS.has( + String.fromCharCode(...bytes.subarray(pos + 1, pos + 1 + blockSize)), + ); + pos += 1 + blockSize; + } + while (pos < bytes.length && bytes[pos] !== 0) { + const size = bytes[pos]; + if (isLoopApplication && size >= 3 && bytes[pos + 1] === 1 && pos + 3 < bytes.length) { + return bytes[pos + 2] | (bytes[pos + 3] << 8); + } + pos += size + 1; + } + pos += 1; + } + return null; +} + +export function openGifFrameSource(bytes: Uint8Array): FrameSource { + if (bytes.length < 13 || bytes[0] !== 0x47 || bytes[1] !== 0x49 || bytes[2] !== 0x46) { + throw decodeFailed('Not a GIF file'); + } + const plays = gifPlaysFromRepeat(readGifRepeat(bytes)); + const parsed = parseGIF(toArrayBuffer(bytes)); + const frames = parsed.frames.filter((block): block is GifImageBlock => 'image' in block && block.image != null); + if (frames.some((frame) => !(frame.image.data.minCodeSize <= GIF_MAX_LZW_CODE_SIZE))) { + throw decodeFailed('GIF frame has an invalid LZW code size'); + } + const screenWidth = bytes[6] | (bytes[7] << 8); + const screenHeight = bytes[8] | (bytes[9] << 8); + const first = frames[0]?.image.descriptor; + const width = Math.max(screenWidth, first ? first.left + first.width : 0); + const height = Math.max(screenHeight, first ? first.top + first.height : 0); + if ( + first && + (screenWidth < first.width || screenHeight < first.height || bytes[4] === GIF_VERSION_87_MINOR) && + (width !== first.width || height !== first.height) + ) { + throw decodeFailed('GIF logical screen does not fit its first frame'); + } + let canvas: Uint8Array | null = null; + let index = 0; + let pendingDisposal: {rect: Rect; saved: Uint8Array | null} | null = null; + + return { + width, + height, + frameCount: frames.length, + plays, + next() { + if (index >= frames.length) return null; + const frame = frames[index++]; + const descriptor = frame.image.descriptor; + if (descriptor.width * descriptor.height > MAX_SOURCE_CANVAS_PIXELS) { + throw new CropPipelineError( + 'budget_exceeded', + `GIF frame ${descriptor.width}x${descriptor.height} is too large`, + ); + } + if (!canvas) { + assertSourceBudget(width, height, frames.length); + canvas = new Uint8Array(width * height * 4); + } + if (pendingDisposal) { + if (pendingDisposal.saved) restoreRect(canvas, width, pendingDisposal.rect, pendingDisposal.saved); + else clearRect(canvas, width, pendingDisposal.rect); + pendingDisposal = null; + } + const decoded = decompressFrame(frame, parsed.gct, false); + const rect = clipRect( + {x: descriptor.left, y: descriptor.top, width: descriptor.width, height: descriptor.height}, + width, + height, + ); + const disposal = frame.gce?.extras.disposal ?? 0; + if (disposal === 3) pendingDisposal = {rect, saved: saveRect(canvas, width, rect)}; + else if (disposal === 2) pendingDisposal = {rect, saved: null}; + const colorTable = decoded.colorTable ?? []; + const transparentIndex = frame.gce?.extras.transparentColorGiven ? frame.gce.transparentColorIndex : -1; + const pixels = decoded.pixels; + for (let row = 0; row < rect.height; row++) { + const sourceRow = (rect.y - descriptor.top + row) * descriptor.width + (rect.x - descriptor.left); + let target = ((rect.y + row) * width + rect.x) * 4; + for (let column = 0; column < rect.width; column++, target += 4) { + const colorIndex = pixels[sourceRow + column]; + if (colorIndex === transparentIndex) continue; + const color = colorTable[colorIndex]; + if (!color) continue; + canvas[target] = color[0]; + canvas[target + 1] = color[1]; + canvas[target + 2] = color[2]; + canvas[target + 3] = 255; + } + } + return {rgba: canvas, delayMs: (frame.gce?.delay ?? 0) * 10}; + }, + close() { + canvas = null; + }, + }; +} + +interface Range { + start: number; + end: number; +} + +interface IsoBox extends Range { + type: string; +} + +interface ApngFrameChunks { + rect: Rect; + delayMs: number; + dispose: number; + blend: number; + data: Array; +} + +function readU32(bytes: Uint8Array, offset: number): number { + return ((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]) >>> 0; +} + +function readU16(bytes: Uint8Array, offset: number): number { + return (bytes[offset] << 8) | bytes[offset + 1]; +} + +function writeChunk(out: Uint8Array, offset: number, type: string, parts: Array): number { + const length = parts.reduce((sum, part) => sum + part.length, 0); + new DataView(out.buffer, out.byteOffset).setUint32(offset, length); + for (let i = 0; i < 4; i++) out[offset + 4 + i] = type.charCodeAt(i); + let cursor = offset + 8; + for (const part of parts) { + out.set(part, cursor); + cursor += part.length; + } + return cursor + 4; +} + +function buildFrameHeaderPng( + ihdr: Uint8Array, + palette: Uint8Array | null, + transparency: Uint8Array | null, + rect: Rect, +): Uint8Array { + const header = ihdr.slice(); + new DataView(header.buffer).setUint32(0, rect.width); + new DataView(header.buffer).setUint32(4, rect.height); + const chunks: Array<[string, Array]> = [['IHDR', [header]]]; + if (palette) chunks.push(['PLTE', [palette]]); + if (transparency) chunks.push(['tRNS', [transparency]]); + chunks.push(['IEND', []]); + const size = chunks.reduce( + (sum, [, parts]) => sum + 12 + parts.reduce((partSum, part) => partSum + part.length, 0), + PNG_SIGNATURE.length, + ); + const out = new Uint8Array(size); + out.set(PNG_SIGNATURE, 0); + let offset = PNG_SIGNATURE.length; + for (const [type, parts] of chunks) offset = writeChunk(out, offset, type, parts); + return out; +} + +function filteredPngByteLength(ihdr: Uint8Array, width: number, height: number): number { + const channels = PNG_CHANNELS[ihdr[9]]; + if (channels === undefined) throw decodeFailed(`PNG color type ${ihdr[9]} is not supported`); + const bitsPerPixel = channels * ihdr[8]; + const rowBytes = (rowWidth: number) => 1 + Math.ceil((rowWidth * bitsPerPixel) / 8); + if (ihdr[12] === 0) return height * rowBytes(width); + let total = 0; + for (const [column, row, columnStep, rowStep] of ADAM7_PASSES) { + const passWidth = Math.ceil((width - column) / columnStep); + const passHeight = Math.ceil((height - row) / rowStep); + if (passWidth > 0 && passHeight > 0) total += passHeight * rowBytes(passWidth); + } + return total; +} + +function inflateFrame(parts: Array, out: Uint8Array, frameIndex: number): Uint8Array { + const filteredLength = out.length; + const limit = filteredLength * 2 + INFLATE_SLACK_BYTES; + let inflated = 0; + const inflater = new Unzlib((chunk) => { + if (inflated < filteredLength) out.set(chunk.subarray(0, filteredLength - inflated), inflated); + inflated += chunk.length; + if (inflated > limit) throw decodeFailed(`APNG frame ${frameIndex} inflates past its dimensions`); + }); + for (const part of parts) { + for (let offset = 0; offset < part.length && inflated < filteredLength; offset += INFLATE_SLICE_BYTES) { + inflater.push(part.subarray(offset, offset + INFLATE_SLICE_BYTES)); + } + } + if (inflated < filteredLength) throw decodeFailed(`APNG frame ${frameIndex} is truncated`); + return out; +} + +function blendOver(canvas: Uint8Array, target: number, rgba: Uint8Array, source: number): void { + const sourceAlpha = rgba[source + 3]; + if (sourceAlpha === 0) return; + const destinationAlpha = canvas[target + 3]; + if (sourceAlpha === 255 || destinationAlpha === 0) { + canvas.set(rgba.subarray(source, source + 4), target); + return; + } + const destinationWeight = destinationAlpha * (255 - sourceAlpha); + const outAlpha = sourceAlpha * 255 + destinationWeight; + for (let channel = 0; channel < 3; channel++) { + canvas[target + channel] = Math.round( + (rgba[source + channel] * sourceAlpha * 255 + canvas[target + channel] * destinationWeight) / outAlpha, + ); + } + canvas[target + 3] = Math.round(outAlpha / 255); +} + +export function openApngFrameSource(bytes: Uint8Array): FrameSource { + for (let i = 0; i < PNG_SIGNATURE.length; i++) { + if (bytes[i] !== PNG_SIGNATURE[i]) throw decodeFailed('Not a PNG file'); + } + let ihdr: Uint8Array | null = null; + let palette: Uint8Array | null = null; + let transparency: Uint8Array | null = null; + let plays = 0; + let animated = false; + const frames: Array = []; + let pos = PNG_SIGNATURE.length; + for (;;) { + if (pos + 8 > bytes.length) throw decodeFailed('PNG ended before IEND'); + const length = readU32(bytes, pos); + const type = String.fromCharCode(bytes[pos + 4], bytes[pos + 5], bytes[pos + 6], bytes[pos + 7]); + const dataStart = pos + 8; + const dataEnd = dataStart + length; + if (dataEnd + 4 > bytes.length) throw decodeFailed(`PNG chunk ${type} overruns the file`); + const data = bytes.subarray(dataStart, dataEnd); + pos = dataEnd + 4; + if (type === 'IEND') break; + if (type === 'IHDR' && length === 13) ihdr = data; + else if (type === 'PLTE') palette = data; + else if (type === 'tRNS') transparency = data; + else if (type === 'acTL' && length >= 8) { + animated = true; + plays = clampPlays(readU32(data, 4)); + } else if (type === 'fcTL' && length >= 26) { + frames.push({ + rect: {x: readU32(data, 12), y: readU32(data, 16), width: readU32(data, 4), height: readU32(data, 8)}, + delayMs: apngDelayMs(readU16(data, 20), readU16(data, 22)), + dispose: data[24], + blend: data[25], + data: [], + }); + } else if (type === 'IDAT' && frames.length === 1) frames[0].data.push(data); + else if (type === 'fdAT' && frames.length > 0 && length > 4) frames[frames.length - 1].data.push(data.subarray(4)); + } + if (!ihdr || !animated) throw decodeFailed('PNG is not animated'); + const header = ihdr; + const width = readU32(header, 0); + const height = readU32(header, 4); + let canvas: Uint8Array | null = null; + let scratch = new Uint8Array(0); + let index = 0; + let pendingDisposal: {rect: Rect; saved: Uint8Array | null} | null = null; + + return { + width, + height, + frameCount: frames.length, + plays, + next() { + if (index >= frames.length) return null; + const frameIndex = index++; + const frame = frames[frameIndex]; + const {rect} = frame; + if ( + rect.width === 0 || + rect.height === 0 || + rect.x + rect.width > width || + rect.y + rect.height > height || + frame.data.length === 0 + ) { + throw decodeFailed(`APNG frame ${frameIndex} is outside the canvas or empty`); + } + if (!canvas) { + assertSourceBudget(width, height, frames.length); + canvas = new Uint8Array(width * height * 4); + } + if (pendingDisposal) { + if (pendingDisposal.saved) restoreRect(canvas, width, pendingDisposal.rect, pendingDisposal.saved); + else clearRect(canvas, width, pendingDisposal.rect); + pendingDisposal = null; + } + const filteredLength = filteredPngByteLength(header, rect.width, rect.height); + if (scratch.length < filteredLength) scratch = new Uint8Array(filteredLength); + const inflated = inflateFrame(frame.data, scratch.subarray(0, filteredLength), frameIndex); + const image = UPNG.decode(toArrayBuffer(buildFrameHeaderPng(header, palette, transparency, rect)), inflated); + const rgba = new Uint8Array(UPNG.toRGBA8(image)[0]); + if (rgba.length !== rect.width * rect.height * 4) throw decodeFailed(`APNG frame ${frameIndex} did not decode`); + const dispose = + frameIndex === 0 && frame.dispose === APNG_DISPOSE_PREVIOUS ? APNG_DISPOSE_BACKGROUND : frame.dispose; + if (dispose === APNG_DISPOSE_PREVIOUS) pendingDisposal = {rect, saved: saveRect(canvas, width, rect)}; + else if (dispose === APNG_DISPOSE_BACKGROUND) pendingDisposal = {rect, saved: null}; + for (let row = 0; row < rect.height; row++) { + const target = ((rect.y + row) * width + rect.x) * 4; + const source = row * rect.width * 4; + if (frame.blend === APNG_BLEND_OVER) { + for (let column = 0; column < rect.width; column++) { + blendOver(canvas, target + column * 4, rgba, source + column * 4); + } + } else { + canvas.set(rgba.subarray(source, source + rect.width * 4), target); + } + } + return {rgba: canvas, delayMs: frame.delayMs}; + }, + close() { + canvas = null; + scratch = new Uint8Array(0); + }, + }; +} + +function readFourCc(bytes: Uint8Array, offset: number): string { + return String.fromCharCode(bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3]); +} + +function isoChildren(bytes: Uint8Array, parent: Range): Array { + const boxes: Array = []; + let pos = parent.start; + while (pos + 8 <= parent.end) { + let size = readU32(bytes, pos); + let headerSize = 8; + if (size === 1) { + if (pos + 16 > parent.end) break; + size = readU32(bytes, pos + 8) * 2 ** 32 + readU32(bytes, pos + 12); + headerSize = 16; + } else if (size === 0) { + size = parent.end - pos; + } + if (size < headerSize || pos + size > parent.end) break; + boxes.push({type: readFourCc(bytes, pos + 4), start: pos + headerSize, end: pos + size}); + pos += size; + } + return boxes; +} + +function isoChild(bytes: Uint8Array, parent: Range | undefined, type: string): IsoBox | undefined { + return parent && isoChildren(bytes, parent).find((box) => box.type === type); +} + +function readTrackDelaysMs(bytes: Uint8Array, trak: IsoBox, frameCount: number): Array | null { + const mdia = isoChild(bytes, trak, 'mdia'); + const mdhd = isoChild(bytes, mdia, 'mdhd'); + const stts = isoChild(bytes, isoChild(bytes, isoChild(bytes, mdia, 'minf'), 'stbl'), 'stts'); + if (!mdhd || !stts || stts.end - stts.start < 8) return null; + const timescaleOffset = mdhd.start + (bytes[mdhd.start] === 1 ? 20 : 12); + if (timescaleOffset + 4 > mdhd.end) return null; + const timescale = readU32(bytes, timescaleOffset); + const entryCount = readU32(bytes, stts.start + 4); + if (timescale === 0 || stts.start + 8 + entryCount * 8 > stts.end) return null; + const delays: Array = []; + for (let entry = 0; entry < entryCount; entry++) { + const sampleCount = readU32(bytes, stts.start + 8 + entry * 8); + const delayMs = (readU32(bytes, stts.start + 12 + entry * 8) * 1000) / timescale; + for (let sample = 0; sample < sampleCount; sample++) { + if (delays.length === frameCount) return null; + delays.push(delayMs); + } + } + return delays.length === frameCount ? delays : null; +} + +function readAvifFrameDelaysMs(bytes: Uint8Array, frameCount: number): Array | null { + const moov = isoChild(bytes, {start: 0, end: bytes.length}, 'moov'); + if (!moov) return null; + for (const trak of isoChildren(bytes, moov)) { + if (trak.type !== 'trak') continue; + const hdlr = isoChild(bytes, isoChild(bytes, trak, 'mdia'), 'hdlr'); + if (!hdlr || hdlr.end - hdlr.start < 12 || readFourCc(bytes, hdlr.start + 8) !== 'pict') continue; + if (isoChild(bytes, isoChild(bytes, trak, 'tref'), 'auxl')) continue; + return readTrackDelaysMs(bytes, trak, frameCount); + } + return null; +} + +export async function openAvifFrameSource(bytes: Uint8Array): Promise { + const ImageDecoderConstructor = getImageDecoderConstructor(); + if (!ImageDecoderConstructor || !(await canDecodeAnimatedAvif())) { + throw new CropPipelineError('animated_avif_unsupported', 'This browser cannot decode animated AVIF frames'); + } + const decoder = new ImageDecoderConstructor({data: bytes, type: 'image/avif'}); + let pending: FluxerImageDecoderDecodedFrame | null = null; + try { + await Promise.all([decoder.tracks.ready, decoder.completed]); + const track = decoder.tracks.selectedTrack; + const frameCount = track?.frameCount ?? 0; + if (frameCount === 0) throw decodeFailed('AVIF has no frames'); + pending = await decoder.decode({frameIndex: 0}); + const width = pending.image.displayWidth; + const height = pending.image.displayHeight; + assertSourceBudget(width, height, frameCount); + const containerDelays = readAvifFrameDelaysMs(bytes, frameCount); + let context: OffscreenCanvasRenderingContext2D | null = null; + let index = 0; + return { + width, + height, + frameCount, + plays: avifPlaysFromRepetitionCount(track?.repetitionCount), + async next() { + if (index >= frameCount) return null; + const frameIndex = index++; + const decoded = pending ?? (await decoder.decode({frameIndex})); + pending = null; + try { + if (!context) { + context = new OffscreenCanvas(width, height).getContext('2d', {willReadFrequently: true}); + if (!context) throw decodeFailed('OffscreenCanvas 2d context is unavailable'); + } + context.clearRect(0, 0, width, height); + drawVideoFrameToCanvas(context, decoded.image); + const imageData = context.getImageData(0, 0, width, height); + return { + rgba: new Uint8Array(imageData.data.buffer, imageData.data.byteOffset, imageData.data.byteLength), + delayMs: containerDelays?.[frameIndex] ?? avifDelayMs(decoded.image.duration), + }; + } finally { + decoded.image.close(); + } + }, + close() { + pending?.image.close(); + pending = null; + closeImageDecoder(decoder); + }, + }; + } catch (error) { + pending?.image.close(); + closeImageDecoder(decoder); + throw error; + } +} + +interface PendingGifFrame { + index: Uint8Array; + palette: Array; + delayMs: number; + dispose: number; +} + +export function openGifFrameSink(width: number, height: number, plays: number, capBytes: number): GifFrameSink { + const encoder = GIFEncoder(); + const pixelCount = width * height; + let previous: Uint8Array | null = null; + let pending: PendingGifFrame | null = null; + let wroteFirst = false; + + function write(frame: PendingGifFrame): void { + encoder.writeFrame(frame.index, width, height, { + palette: frame.palette, + delay: Math.min(frame.delayMs, GIF_MAX_DELAY_CS * 10), + transparent: true, + transparentIndex: GIF_TRANSPARENT_INDEX, + dispose: frame.dispose, + ...(wroteFirst ? {} : {repeat: gifRepeatFromPlays(plays)}), + }); + wroteFirst = true; + } + + function needsFullFrame(rgba: Uint8Array): boolean { + if (!previous) return true; + for (let offset = 3; offset < rgba.length; offset += 4) { + if (previous[offset] === 255 && rgba[offset] === 0) return true; + } + return false; + } + + return { + add(rgba, delayMs) { + if (rgba.length !== pixelCount * 4) return false; + for (let offset = 3; offset < rgba.length; offset += 4) { + const alpha = rgba[offset]; + if (alpha !== 0 && alpha !== 255) return false; + } + const full = needsFullFrame(rgba); + const index = new Uint8Array(pixelCount); + const palette: Array = [[0, 0, 0]]; + const colors = new Map(); + for (let pixel = 0, offset = 0; pixel < pixelCount; pixel++, offset += 4) { + if (rgba[offset + 3] === 0) continue; + if ( + !full && + previous && + previous[offset + 3] === 255 && + previous[offset] === rgba[offset] && + previous[offset + 1] === rgba[offset + 1] && + previous[offset + 2] === rgba[offset + 2] + ) { + continue; + } + const key = (rgba[offset] << 16) | (rgba[offset + 1] << 8) | rgba[offset + 2]; + let colorIndex = colors.get(key); + if (colorIndex === undefined) { + if (palette.length > GIF_MAX_OPAQUE_COLORS) return false; + colorIndex = palette.length; + colors.set(key, colorIndex); + palette.push([rgba[offset], rgba[offset + 1], rgba[offset + 2]]); + } + index[pixel] = colorIndex; + } + if (pending) { + pending.dispose = full ? 2 : 1; + write(pending); + if (encoder.bytesView().length > capBytes) return false; + } + pending = {index, palette, delayMs, dispose: 1}; + if (previous) previous.set(rgba); + else previous = rgba.slice(); + return true; + }, + finish() { + if (pending) write(pending); + pending = null; + encoder.finish(); + return encoder.bytes(); + }, + close() { + pending = null; + previous = null; + }, + }; +} diff --git a/fluxer_app/src/features/expressions/workers/AnimatedImageCropMessages.ts b/fluxer_app/src/features/expressions/workers/AnimatedImageCropMessages.ts index 7fd5f93fd..9e88f89c6 100644 --- a/fluxer_app/src/features/expressions/workers/AnimatedImageCropMessages.ts +++ b/fluxer_app/src/features/expressions/workers/AnimatedImageCropMessages.ts @@ -1,103 +1,60 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -export type AnimatedImageFormat = 'gif' | 'webp' | 'avif' | 'apng'; -export type CropWorkerImageFormat = AnimatedImageFormat | 'png' | 'jpeg'; -export type CropOutputFormat = 'animated_webp' | 'apng' | 'gif' | 'webp' | 'png' | 'jpeg' | 'avif'; +export type AnimatedCropSourceFormat = 'gif' | 'png' | 'webp' | 'avif'; +export type AnimatedCropOutputMime = 'image/gif' | 'image/webp'; +export type CropErrorCode = + | 'aborted' + | 'timeout' + | 'budget_exceeded' + | 'too_large' + | 'decode_failed' + | 'animated_avif_unsupported' + | 'wasm_unavailable' + | 'encode_failed' + | 'internal'; +export type CropProgressPhase = 'init' | 'crop' | 'compress'; export interface CropParams { x: number; y: number; width: number; height: number; - imageRotation?: number; - resizeWidth?: number | null; - resizeHeight?: number | null; - outputFormat?: CropOutputFormat; + rotation: 0 | 90 | 180 | 270; + outputWidth: number; + outputHeight: number; } -export type CropWorkerErrorCode = - | 'unsupported_mime' - | 'lottie_unsupported' - | 'heic_unsupported_in_browser' - | 'decode_failed' - | 'encode_failed' - | 'internal'; -export type FrameBatchOperation = 'transform_rgba' | 'encode_apng_frame' | 'encode_gif_frame'; - -export interface FrameBatch { - startIndex: number; - operation?: FrameBatchOperation; - frames: Array<{ - data: Uint8Array; - delay: number; - disposeOp: number; - width?: number; - height?: number; - delayMs?: number; - first?: boolean; - }>; -} - -export enum CropAnimatedImageMessageType { - CROP_ANIMATED_IMAGE_START = 0, - CROP_ANIMATED_IMAGE_COMPLETE = 1, - CROP_ANIMATED_IMAGE_ERROR = 2, - PROCESS_BATCH = 3, - BATCH_COMPLETE = 4, -} - -export interface DecodedFrameInput { - rgba: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedApngFrameInput { - compressed: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedGifChunkInput { - data: Uint8Array; - width: number; - height: number; -} - -export interface CropAnimatedImageStartMessage extends CropParams { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_START; - imageBytes?: Uint8Array; - format?: CropWorkerImageFormat; - prefetchedFrames?: Array; -} - -export interface CropAnimatedImageCompleteMessage { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_COMPLETE; - result: Uint8Array; -} - -export interface CropAnimatedImageErrorMessage { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR; - error: string; - code?: CropWorkerErrorCode; -} - -export interface ProcessBatchMessage { - type: CropAnimatedImageMessageType.PROCESS_BATCH; +export interface CropWorkerRequest { + type: 'crop'; jobId: number; - batch: FrameBatch; - cropParams: CropParams; + bytes: ArrayBuffer; + format: AnimatedCropSourceFormat; + crop: CropParams; + sizeLimitBytes: number; } -export interface ProcessBatchCompleteMessage { - type: CropAnimatedImageMessageType.BATCH_COMPLETE; - jobId: number; - processedFrames: Array; - processedDecodedFrames?: Array; - encodedApngFrames?: Array; - encodedGifChunks?: Array; +export interface CropStats { + variant: 'simd' | 'scalar' | 'none'; + passes: number; + method: number; + quality: number; + lossless: boolean; + framesDecoded: number; + decodeMs: number; + encodeMs: number; } -export type CropWorkerIncomingMessage = CropAnimatedImageStartMessage | ProcessBatchMessage; +export type CropWorkerResponse = + | {type: 'progress'; jobId: number; phase: CropProgressPhase; done: number; total: number} + | {type: 'done'; jobId: number; bytes: ArrayBuffer; mime: AnimatedCropOutputMime; stats: CropStats} + | {type: 'error'; jobId: number; code: CropErrorCode; message: string}; + +export class CropPipelineError extends Error { + readonly code: CropErrorCode; + + constructor(code: CropErrorCode, message: string) { + super(message); + this.code = code; + this.name = 'CropPipelineError'; + } +} diff --git a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorker.ts b/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorker.ts index 317de4318..b1aa6ab67 100644 --- a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorker.ts +++ b/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorker.ts @@ -1,813 +1,329 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import { - type CropAnimatedImageCompleteMessage, - type CropAnimatedImageErrorMessage, - CropAnimatedImageMessageType, - type CropAnimatedImageStartMessage, - type CropOutputFormat, - type CropParams, - type CropWorkerErrorCode, - type CropWorkerImageFormat, - type CropWorkerIncomingMessage, - type DecodedFrameInput, - type EncodedApngFrameInput, - type EncodedGifChunkInput, - type ProcessBatchCompleteMessage, - type ProcessBatchMessage, -} from '@app/features/expressions/workers/AnimatedImageCropMessages'; + assertOutputBudget, + assertSourceBudget, + chooseMethod, + type EncodeRung, + isNoopCrop, + LOSSLESS_RUNG, + lossyRung, + nextRung, + usesLosslessFirstRung, +} from '@app/features/expressions/workers/AnimatedCropPlan'; import { - assembleApngFrames, - assembleGifFrameChunks, - cropAndRotateImage, - cropRotateRgba, - decodeApngFrames, - decodeGifFrames, - detectAnimatedImage, - encodeApngFramePayload, - encodeApngFrames, - encodeGifFrameChunk, - encodeGifFrames, - ensureLibfluxcoreReady, - releaseLibfluxcoreMemoryIfIdle, -} from '@app/features/platform/workers/LibFluxcoreWorker'; + type FrameSource, + openApngFrameSource, + openAvifFrameSource, + openGifFrameSink, + openGifFrameSource, +} from '@app/features/expressions/workers/AnimatedFrameCodecs'; +import { + type AnimatedCropOutputMime, + type CropErrorCode, + CropPipelineError, + type CropProgressPhase, + type CropStats, + type CropWorkerRequest, + type CropWorkerResponse, +} from '@app/features/expressions/workers/AnimatedImageCropMessages'; +import {cropRotateRgbaInto, ensureLibfluxcoreReady} from '@app/features/platform/workers/LibFluxcoreWorker'; +import { + ensureLibWebpReady, + openWebpFrameSink, + openWebpFrameSource, + probeWebp, +} from '@app/features/platform/workers/LibWebpWorker'; -type StaticImageFormat = Exclude; - -const NESTED_WORKER_IDLE_MS = 30000; - -function getStaticFormatHint(format: StaticImageFormat | CropOutputFormat): string { - switch (format) { - case 'apng': - case 'png': - case 'animated_webp': - return 'png'; - case 'jpeg': - return 'jpeg'; - case 'gif': - return 'gif'; - case 'webp': - return 'webp'; - case 'avif': - return 'avif'; - } -} - -const logger = { - error: (...args: Array) => { - if (typeof console !== 'undefined') { - console.error('[AnimatedImageCrop Worker]', ...args); - } - }, -}; declare const self: DedicatedWorkerGlobalScope; -self.addEventListener('message', async (event: MessageEvent) => { - const msg = event.data; - switch (msg?.type) { - case CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_START: - await handleCropStart(msg); - break; - case CropAnimatedImageMessageType.PROCESS_BATCH: - await handleProcessBatch(msg); - break; - default: - return; - } -}); +const PROGRESS_INTERVAL_MS = 50; -function postError(code: CropWorkerErrorCode, error: unknown): void { - logger.error('Error:', error); - const response: CropAnimatedImageErrorMessage = { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR, - error: error instanceof Error ? error.message : String(error), - code, +interface OpenedSource { + source: FrameSource; + lossless: boolean; +} + +interface FrameSinkLike { + add(rgba: Uint8Array, delayMs: number): unknown; + finish(): Uint8Array; + close(): void; +} + +interface CropResult { + bytes: Uint8Array; + mime: AnimatedCropOutputMime; +} + +class CropJob { + readonly stats: CropStats = { + variant: 'none', + passes: 0, + method: 0, + quality: 0, + lossless: true, + framesDecoded: 0, + decodeMs: 0, + encodeMs: 0, }; - self.postMessage(response); -} + private readonly bytes: Uint8Array; + private lastProgressAt = 0; + private cropStart = 0; + private cropReached = 0; + private reusableSource: OpenedSource | null = null; -function resolveStaticOutput(format: CropWorkerImageFormat, outputFormat: CropOutputFormat | undefined): string { - if (outputFormat) return getStaticFormatHint(outputFormat); - if (format === 'gif') return 'gif'; - return getStaticFormatHint(format); -} - -async function handleCropStart(msg: CropAnimatedImageStartMessage): Promise { - const { - imageBytes, - format, - x, - y, - width, - height, - imageRotation = 0, - resizeWidth = null, - resizeHeight = null, - outputFormat, - } = msg; - if (!imageBytes || !format) { - postError('internal', new Error('worker requires imageBytes; prefetchedFrames must be handled by the manager')); - return; + constructor(private readonly request: CropWorkerRequest) { + this.bytes = new Uint8Array(request.bytes); } - try { - await ensureLibfluxcoreReady(); - let result: Uint8Array; - switch (format) { - case 'gif': - result = await cropGifWithParallelFrames( - imageBytes, - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, + + async run(): Promise { + this.postProgress('init', 0, 1, true); + await this.loadLibfluxcore(); + const {request} = this; + const {crop} = request; + const opened = await this.openSource(); + this.reusableSource = opened; + try { + const {source} = opened; + assertOutputBudget(source.frameCount, crop.outputWidth, crop.outputHeight); + if (isNoopCrop(crop, source.width, source.height, request.format, this.bytes.length, request.sizeLimitBytes)) { + return {bytes: this.bytes, mime: request.format === 'gif' ? 'image/gif' : 'image/webp'}; + } + const cap = request.sizeLimitBytes; + const frameCount = source.frameCount; + const plays = source.plays; + let phase: CropProgressPhase = 'crop'; + if (request.format === 'gif') { + this.setRung({quality: 0, method: 0, lossless: true}); + const gif = await this.runPass( + this.openSink(() => openGifFrameSink(crop.outputWidth, crop.outputHeight, plays, cap)), + 'crop', ); - break; - case 'apng': { - const isActuallyAnimated = await detectAnimatedImage(imageBytes); - if (isActuallyAnimated) { - if (outputFormat && outputFormat !== 'apng' && outputFormat !== 'animated_webp') { - result = cropAndRotateImage( - imageBytes, - getStaticFormatHint(outputFormat), - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - } else { - result = await cropApngWithParallelFrames( - imageBytes, - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - } - } else { - result = cropAndRotateImage( - imageBytes, - resolveStaticOutput(format, outputFormat), - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - } - break; + if (gif && gif.length <= cap) return {bytes: gif, mime: 'image/gif'}; + if (gif) phase = 'compress'; + this.cropStart = this.cropReached; } - case 'webp': - case 'avif': { - const isAnimated = await detectAnimatedImage(imageBytes); - if (isAnimated) { - postError('unsupported_mime', new Error(`animated ${format} must be cropped via the native bridge`)); - return; - } - result = cropAndRotateImage( - imageBytes, - resolveStaticOutput(format, outputFormat), - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, + await this.loadLibWebp(); + const workPixels = frameCount * crop.outputWidth * crop.outputHeight; + const method = chooseMethod(workPixels); + let rungIndex = usesLosslessFirstRung(opened.lossless, workPixels) ? -1 : 0; + for (;;) { + const rung = rungIndex < 0 ? LOSSLESS_RUNG : lossyRung(rungIndex, method); + this.setRung(rung); + const webp = await this.runPass( + this.openSink(() => openWebpFrameSink(crop.outputWidth, crop.outputHeight, plays, rung)), + phase, ); - break; - } - case 'png': - case 'jpeg': { - result = cropAndRotateImage( - imageBytes, - resolveStaticOutput(format, outputFormat), - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - break; - } - default: - postError('unsupported_mime', new Error(`unsupported format: ${format as string}`)); - return; - } - const transferables: Array = []; - if (result?.buffer) { - transferables.push(result.buffer); - } - const response: CropAnimatedImageCompleteMessage = { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_COMPLETE, - result, - }; - self.postMessage(response, transferables); - } catch (err) { - postError('internal', err); - } finally { - releaseLibfluxcoreMemoryIfIdle(); - } -} - -function readU16LE(bytes: Uint8Array, offset: number): number { - return (bytes[offset] ?? 0) | ((bytes[offset + 1] ?? 0) << 8); -} - -function readU32BE(bytes: Uint8Array, offset: number): number { - return ( - ((bytes[offset] ?? 0) * 0x1000000 + - (((bytes[offset + 1] ?? 0) << 16) | ((bytes[offset + 2] ?? 0) << 8) | (bytes[offset + 3] ?? 0))) >>> - 0 - ); -} - -function gifDimensions(bytes: Uint8Array): {width: number; height: number} | null { - if ( - bytes.length < 10 || - bytes[0] !== 0x47 || - bytes[1] !== 0x49 || - bytes[2] !== 0x46 || - bytes[3] !== 0x38 || - (bytes[4] !== 0x37 && bytes[4] !== 0x39) || - bytes[5] !== 0x61 - ) { - return null; - } - return {width: readU16LE(bytes, 6), height: readU16LE(bytes, 8)}; -} - -function pngDimensions(bytes: Uint8Array): {width: number; height: number} | null { - if ( - bytes.length < 24 || - bytes[0] !== 0x89 || - bytes[1] !== 0x50 || - bytes[2] !== 0x4e || - bytes[3] !== 0x47 || - bytes[4] !== 0x0d || - bytes[5] !== 0x0a || - bytes[6] !== 0x1a || - bytes[7] !== 0x0a || - bytes[12] !== 0x49 || - bytes[13] !== 0x48 || - bytes[14] !== 0x44 || - bytes[15] !== 0x52 - ) { - return null; - } - return {width: readU32BE(bytes, 16), height: readU32BE(bytes, 20)}; -} - -function positiveInt(value: number | null | undefined): number | null { - if (value == null || !Number.isFinite(value) || value <= 0) return null; - return Math.floor(value); -} - -function normalizedRotation(degrees: number): number { - const rotation = ((Math.floor(degrees || 0) % 360) + 360) % 360; - return rotation === 90 || rotation === 180 || rotation === 270 ? rotation : 0; -} - -function isNoopTransform( - imageWidth: number, - imageHeight: number, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): boolean { - const cropX = Math.min(Math.max(0, Math.floor(x)), imageWidth); - const cropY = Math.min(Math.max(0, Math.floor(y)), imageHeight); - const cropW = Math.min(Math.max(0, Math.floor(width)), imageWidth - cropX); - const cropH = Math.min(Math.max(0, Math.floor(height)), imageHeight - cropY); - return ( - cropX === 0 && - cropY === 0 && - cropW === imageWidth && - cropH === imageHeight && - normalizedRotation(rotation) === 0 && - (positiveInt(resizeWidth) ?? imageWidth) === imageWidth && - (positiveInt(resizeHeight) ?? imageHeight) === imageHeight - ); -} - -function transformFrame(frame: DecodedFrameInput, cropParams: CropParams): DecodedFrameInput { - const transformed = cropRotateRgba( - frame.rgba, - frame.width, - frame.height, - cropParams.x, - cropParams.y, - cropParams.width, - cropParams.height, - cropParams.imageRotation ?? 0, - cropParams.resizeWidth ?? null, - cropParams.resizeHeight ?? null, - ); - return { - rgba: transformed.rgba, - width: transformed.width, - height: transformed.height, - delayMs: frame.delayMs, - }; -} - -function shouldParallelizeFrames(_frames: Array): boolean { - return false; -} - -function nestedWorkerCount(frameCount: number): number { - const cores = Math.max(1, typeof navigator === 'undefined' ? 1 : navigator.hardwareConcurrency || 1); - return Math.max(1, Math.min(4, frameCount, cores - 1)); -} - -let nestedWorkerPool: Array = []; -let nestedWorkerIdleTimer: NodeJS.Timeout | null = null; -let nestedJobId = 1; - -function nextNestedJobId(): number { - nestedJobId = (nestedJobId % 0x3fffffff) + 1; - return nestedJobId; -} - -function clearNestedWorkerIdleTimer(): void { - if (!nestedWorkerIdleTimer) return; - clearTimeout(nestedWorkerIdleTimer); - nestedWorkerIdleTimer = null; -} - -function terminateNestedWorkerPool(): void { - clearNestedWorkerIdleTimer(); - for (const worker of nestedWorkerPool) worker.terminate(); - nestedWorkerPool = []; -} - -function scheduleNestedWorkerCleanup(): void { - clearNestedWorkerIdleTimer(); - nestedWorkerIdleTimer = setTimeout(terminateNestedWorkerPool, NESTED_WORKER_IDLE_MS); -} - -function retireNestedWorker(worker: Worker): void { - try { - worker.terminate(); - } catch {} - const index = nestedWorkerPool.indexOf(worker); - if (index !== -1) nestedWorkerPool.splice(index, 1); -} - -function getNestedWorkers(_count: number): Array { - throw new Error('nested worker parallelism is disabled'); -} - -function frameBatches( - frames: Array, - workerCount: number, -): Array> { - const batches: Array> = Array.from({length: workerCount}, () => []); - for (let index = 0; index < frames.length; index += 1) { - batches[index % workerCount]?.push({frame: frames[index], index}); - } - return batches.filter((batch) => batch.length > 0); -} - -function processFrameBatchInWorker( - worker: Worker, - jobId: number, - frames: Array<{frame: DecodedFrameInput; index: number}>, - cropParams: CropParams, -): Promise> { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - cleanup(); - retireNestedWorker(worker); - reject(new Error('Nested frame worker timed out')); - }, 30000); - const cleanup = () => { - clearTimeout(timeout); - worker.removeEventListener('message', handleMessage); - worker.removeEventListener('error', handleError); - }; - const handleMessage = (event: MessageEvent) => { - const msg = event.data; - if (msg.type === CropAnimatedImageMessageType.BATCH_COMPLETE && msg.jobId === jobId) { - cleanup(); - const processed = msg.processedDecodedFrames; - if (!processed) { - reject(new Error('Nested frame worker returned no decoded frames')); - return; + phase = 'compress'; + if (!webp) throw new CropPipelineError('encode_failed', 'WebP encoder rejected a frame'); + if (webp.length <= cap) return {bytes: webp, mime: 'image/webp'}; + if (rungIndex < 0) { + rungIndex = 0; + continue; } - resolve(processed.map((frame, offset) => ({frame, index: frames[offset]?.index ?? offset}))); - } else if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR) { - cleanup(); - reject(new Error(msg.error || 'Nested frame worker failed')); + const next = nextRung(rungIndex, webp.length, cap); + if (next === 'too_large') { + throw new CropPipelineError('too_large', `Output is ${webp.length} bytes, over the ${cap} byte limit`); + } + rungIndex = next; } - }; - const handleError = (error: ErrorEvent) => { - cleanup(); - retireNestedWorker(worker); - reject(new Error(error.message || 'Nested frame worker failed')); - }; - worker.addEventListener('message', handleMessage); - worker.addEventListener('error', handleError); - const transferables = frames.map(({frame}) => frame.rgba.buffer); - worker.postMessage( - { - type: CropAnimatedImageMessageType.PROCESS_BATCH, - jobId, - cropParams, - batch: { - startIndex: 0, - operation: 'transform_rgba', - frames: frames.map(({frame}) => ({ - data: frame.rgba, - width: frame.width, - height: frame.height, - delay: frame.delayMs, - delayMs: frame.delayMs, - disposeOp: 0, - })), - }, - } satisfies ProcessBatchMessage, - transferables, - ); - }); -} - -async function transformFramesParallel( - frames: Array, - cropParams: CropParams, -): Promise> { - if (!shouldParallelizeFrames(frames)) { - return frames.map((frame) => transformFrame(frame, cropParams)); - } - const workerCount = nestedWorkerCount(frames.length); - const batches = frameBatches(frames, workerCount); - const workers = getNestedWorkers(batches.length); - try { - const batchResults = await Promise.all( - batches.map((batch, index) => processFrameBatchInWorker(workers[index], nextNestedJobId(), batch, cropParams)), - ); - const ordered: Array = new Array(frames.length); - for (const batch of batchResults) { - for (const item of batch) ordered[item.index] = item.frame; + } finally { + this.reusableSource?.source.close(); + this.reusableSource = null; } - return ordered.map((frame, index) => { - if (!frame) throw new Error(`Missing transformed frame ${index}`); - return frame; + } + + private async loadLibfluxcore(): Promise { + if (typeof WebAssembly === 'undefined') { + throw new CropPipelineError('wasm_unavailable', 'WebAssembly is not available'); + } + try { + await ensureLibfluxcoreReady(); + } catch (error) { + throw new CropPipelineError('wasm_unavailable', errorMessage(error)); + } + } + + private async loadLibWebp(): Promise { + if (this.stats.variant !== 'none') return; + try { + this.stats.variant = await ensureLibWebpReady(); + } catch (error) { + throw new CropPipelineError('wasm_unavailable', errorMessage(error)); + } + } + + private async openSource(): Promise { + const {format} = this.request; + if (format === 'webp') await this.loadLibWebp(); + return this.decodeStage(async () => { + switch (format) { + case 'gif': + return {source: openGifFrameSource(this.bytes), lossless: true}; + case 'png': + return {source: openApngFrameSource(this.bytes), lossless: true}; + case 'avif': + return {source: await openAvifFrameSource(this.bytes), lossless: false}; + case 'webp': { + const probe = probeWebp(this.bytes); + assertSourceBudget(probe.width, probe.height, probe.frameCount); + return {source: openWebpFrameSource(this.bytes), lossless: probe.lossless}; + } + } + }).then((opened) => { + assertSourceBudget(opened.source.width, opened.source.height, opened.source.frameCount); + return opened; }); - } finally { - scheduleNestedWorkerCleanup(); + } + + private async takeSource(): Promise { + const reusable = this.reusableSource; + this.reusableSource = null; + if (reusable) return reusable.source; + return (await this.openSource()).source; + } + + private openSink(open: () => FrameSinkLike): FrameSinkLike { + try { + return open(); + } catch (error) { + throw asStageError('encode_failed', error); + } + } + + private async runPass(sink: FrameSinkLike, phase: CropProgressPhase): Promise { + const {crop} = this.request; + this.stats.passes++; + let source: FrameSource | null = null; + try { + source = await this.takeSource(); + const total = source.frameCount; + const cropped = new Uint8Array(crop.outputWidth * crop.outputHeight * 4); + let done = 0; + this.postProgress(phase, 0, total, true); + for (;;) { + const decodeStart = performance.now(); + const frameSource: FrameSource = source; + const frame = await this.decodeStage(() => frameSource.next()); + if (!frame) break; + try { + cropRotateRgbaInto( + frame.rgba, + frameSource.width, + frameSource.height, + crop.x, + crop.y, + crop.width, + crop.height, + crop.rotation, + cropped, + crop.outputWidth, + crop.outputHeight, + ); + } catch (error) { + throw asStageError('decode_failed', error); + } + this.stats.framesDecoded++; + const encodeStart = performance.now(); + this.stats.decodeMs += encodeStart - decodeStart; + let accepted: unknown; + try { + accepted = sink.add(cropped, frame.delayMs); + } catch (error) { + throw asStageError('encode_failed', error); + } + this.stats.encodeMs += performance.now() - encodeStart; + if (accepted === false) return null; + done++; + if (this.postProgress(phase, done, total, false)) await yieldToEventLoop(); + } + if (done === 0) throw new CropPipelineError('decode_failed', 'Animation has no frames'); + this.postProgress('compress', done, total, true); + const finishStart = performance.now(); + try { + return sink.finish(); + } catch (error) { + throw asStageError('encode_failed', error); + } finally { + this.stats.encodeMs += performance.now() - finishStart; + } + } finally { + sink.close(); + source?.close(); + } + } + + private async decodeStage(read: () => T | Promise): Promise { + try { + return await read(); + } catch (error) { + throw asStageError('decode_failed', error); + } + } + + private setRung(rung: EncodeRung): void { + this.stats.quality = rung.quality; + this.stats.method = rung.method; + this.stats.lossless = rung.lossless; + } + + private postProgress(phase: CropProgressPhase, done: number, total: number, force: boolean): boolean { + const now = performance.now(); + if (!force && done < total && now - this.lastProgressAt < PROGRESS_INTERVAL_MS) return false; + this.lastProgressAt = now; + if (phase === 'crop') { + this.cropReached = this.cropStart + (1 - this.cropStart) * (total > 0 ? done / total : 0); + post({type: 'progress', jobId: this.request.jobId, phase, done: this.cropReached * total, total}); + return true; + } + post({type: 'progress', jobId: this.request.jobId, phase, done, total}); + return true; } } -function processApngEncodeBatchInWorker( - worker: Worker, - jobId: number, - frames: Array<{frame: DecodedFrameInput; index: number}>, -): Promise> { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - cleanup(); - retireNestedWorker(worker); - reject(new Error('Nested APNG encode worker timed out')); - }, 30000); - const cleanup = () => { - clearTimeout(timeout); - worker.removeEventListener('message', handleMessage); - worker.removeEventListener('error', handleError); +function yieldToEventLoop(): Promise { + return new Promise((resolve) => { + const channel = new MessageChannel(); + channel.port1.onmessage = () => { + channel.port1.close(); + resolve(); }; - const handleMessage = (event: MessageEvent) => { - const msg = event.data; - if (msg.type === CropAnimatedImageMessageType.BATCH_COMPLETE && msg.jobId === jobId) { - cleanup(); - const encoded = msg.encodedApngFrames; - if (!encoded) { - reject(new Error('Nested APNG encode worker returned no frame payloads')); - return; - } - resolve(encoded.map((frame, offset) => ({frame, index: frames[offset]?.index ?? offset}))); - } else if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR) { - cleanup(); - reject(new Error(msg.error || 'Nested APNG encode worker failed')); - } - }; - const handleError = (error: ErrorEvent) => { - cleanup(); - retireNestedWorker(worker); - reject(new Error(error.message || 'Nested APNG encode worker failed')); - }; - worker.addEventListener('message', handleMessage); - worker.addEventListener('error', handleError); - const transferables = frames.map(({frame}) => frame.rgba.buffer); - worker.postMessage( - { - type: CropAnimatedImageMessageType.PROCESS_BATCH, - jobId, - cropParams: {x: 0, y: 0, width: 0, height: 0}, - batch: { - startIndex: 0, - operation: 'encode_apng_frame', - frames: frames.map(({frame}) => ({ - data: frame.rgba, - width: frame.width, - height: frame.height, - delay: frame.delayMs, - delayMs: frame.delayMs, - disposeOp: 0, - })), - }, - } satisfies ProcessBatchMessage, - transferables, - ); + channel.port2.postMessage(null); }); } -function processGifEncodeBatchInWorker( - worker: Worker, - jobId: number, - frames: Array<{frame: DecodedFrameInput; index: number}>, -): Promise> { - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - cleanup(); - retireNestedWorker(worker); - reject(new Error('Nested GIF encode worker timed out')); - }, 30000); - const cleanup = () => { - clearTimeout(timeout); - worker.removeEventListener('message', handleMessage); - worker.removeEventListener('error', handleError); - }; - const handleMessage = (event: MessageEvent) => { - const msg = event.data; - if (msg.type === CropAnimatedImageMessageType.BATCH_COMPLETE && msg.jobId === jobId) { - cleanup(); - const encoded = msg.encodedGifChunks; - if (!encoded) { - reject(new Error('Nested GIF encode worker returned no frame chunks')); - return; - } - resolve(encoded.map((frame, offset) => ({frame, index: frames[offset]?.index ?? offset}))); - } else if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR) { - cleanup(); - reject(new Error(msg.error || 'Nested GIF encode worker failed')); - } - }; - const handleError = (error: ErrorEvent) => { - cleanup(); - retireNestedWorker(worker); - reject(new Error(error.message || 'Nested GIF encode worker failed')); - }; - worker.addEventListener('message', handleMessage); - worker.addEventListener('error', handleError); - const transferables = frames.map(({frame}) => frame.rgba.buffer); - worker.postMessage( - { - type: CropAnimatedImageMessageType.PROCESS_BATCH, - jobId, - cropParams: {x: 0, y: 0, width: 0, height: 0}, - batch: { - startIndex: 0, - operation: 'encode_gif_frame', - frames: frames.map(({frame, index}) => ({ - data: frame.rgba, - width: frame.width, - height: frame.height, - delay: frame.delayMs, - delayMs: frame.delayMs, - disposeOp: 0, - first: index === 0, - })), - }, - } satisfies ProcessBatchMessage, - transferables, - ); - }); +function errorMessage(error: unknown): string { + return error instanceof Error ? error.message : String(error); } -async function encodeApngFramesParallel(frames: Array): Promise { - if (!shouldParallelizeFrames(frames)) return encodeApngFrames(frames); - const workerCount = nestedWorkerCount(frames.length); - const batches = frameBatches(frames, workerCount); - const workers = getNestedWorkers(batches.length); +function asStageError(code: CropErrorCode, error: unknown): CropPipelineError { + return error instanceof CropPipelineError ? error : new CropPipelineError(code, errorMessage(error)); +} + +function post(message: CropWorkerResponse, transfer: Array = []): void { + self.postMessage(message, transfer); +} + +function toTransferableBuffer(bytes: Uint8Array): ArrayBuffer { + if (bytes.buffer instanceof ArrayBuffer && bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength) { + return bytes.buffer; + } + return bytes.slice().buffer; +} + +async function handleCrop(request: CropWorkerRequest): Promise { + const job = new CropJob(request); try { - const batchResults = await Promise.all( - batches.map((batch, index) => processApngEncodeBatchInWorker(workers[index], nextNestedJobId(), batch)), - ); - const ordered: Array = new Array(frames.length); - for (const batch of batchResults) { - for (const item of batch) ordered[item.index] = item.frame; - } - return assembleApngFrames( - ordered.map((frame, index) => { - if (!frame) throw new Error(`Missing encoded APNG frame ${index}`); - return frame; - }), - ); - } finally { - scheduleNestedWorkerCleanup(); + const result = await job.run(); + const buffer = toTransferableBuffer(result.bytes); + post({type: 'done', jobId: request.jobId, bytes: buffer, mime: result.mime, stats: job.stats}, [buffer]); + } catch (error) { + const failure = asStageError('internal', error); + post({type: 'error', jobId: request.jobId, code: failure.code, message: failure.message}); } } -async function encodeGifFramesParallel(frames: Array): Promise { - if (!shouldParallelizeFrames(frames)) return encodeGifFrames(frames); - const workerCount = nestedWorkerCount(frames.length); - const batches = frameBatches(frames, workerCount); - const workers = getNestedWorkers(batches.length); - try { - const batchResults = await Promise.all( - batches.map((batch, index) => processGifEncodeBatchInWorker(workers[index], nextNestedJobId(), batch)), - ); - const ordered: Array = new Array(frames.length); - for (const batch of batchResults) { - for (const item of batch) ordered[item.index] = item.frame; - } - return assembleGifFrameChunks( - ordered.map((frame, index) => { - if (!frame) throw new Error(`Missing encoded GIF frame ${index}`); - return frame; - }), - ); - } finally { - scheduleNestedWorkerCleanup(); - } -} - -async function cropGifWithParallelFrames( - imageBytes: Uint8Array, - x: number, - y: number, - width: number, - height: number, - imageRotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Promise { - const dimensions = gifDimensions(imageBytes); - if ( - dimensions && - isNoopTransform(dimensions.width, dimensions.height, x, y, width, height, imageRotation, resizeWidth, resizeHeight) - ) { - return imageBytes.slice(); - } - const frames = decodeGifFrames(imageBytes); - return encodeGifFramesParallel( - await transformFramesParallel(frames, {x, y, width, height, imageRotation, resizeWidth, resizeHeight}), - ); -} - -async function cropApngWithParallelFrames( - imageBytes: Uint8Array, - x: number, - y: number, - width: number, - height: number, - imageRotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Promise { - const dimensions = pngDimensions(imageBytes); - if ( - dimensions && - isNoopTransform(dimensions.width, dimensions.height, x, y, width, height, imageRotation, resizeWidth, resizeHeight) - ) { - return imageBytes.slice(); - } - const frames = decodeApngFrames(imageBytes); - return encodeApngFramesParallel( - await transformFramesParallel(frames, {x, y, width, height, imageRotation, resizeWidth, resizeHeight}), - ); -} - -async function handleProcessBatch(msg: ProcessBatchMessage): Promise { - const {jobId, batch, cropParams} = msg; - const {x, y, width, height, imageRotation = 0, resizeWidth = null, resizeHeight = null} = cropParams; - try { - await ensureLibfluxcoreReady(); - if (batch.operation === 'encode_apng_frame') { - const encodedApngFrames: Array = []; - for (const frame of batch.frames) { - if (frame.width == null || frame.height == null) throw new Error('APNG encode batch requires frame dimensions'); - encodedApngFrames.push( - encodeApngFramePayload({ - rgba: frame.data, - width: frame.width, - height: frame.height, - delayMs: frame.delayMs ?? frame.delay, - }), - ); - } - const transferables = encodedApngFrames.map((frame) => frame.compressed.buffer); - const response: ProcessBatchCompleteMessage = { - type: CropAnimatedImageMessageType.BATCH_COMPLETE, - jobId, - processedFrames: [], - encodedApngFrames, - }; - self.postMessage(response, transferables); - return; - } - if (batch.operation === 'encode_gif_frame') { - const encodedGifChunks: Array = []; - for (const frame of batch.frames) { - if (frame.width == null || frame.height == null) throw new Error('GIF encode batch requires frame dimensions'); - encodedGifChunks.push( - encodeGifFrameChunk( - { - rgba: frame.data, - width: frame.width, - height: frame.height, - delayMs: frame.delayMs ?? frame.delay, - }, - Boolean(frame.first), - ), - ); - } - const transferables = encodedGifChunks.map((chunk) => chunk.data.buffer); - const response: ProcessBatchCompleteMessage = { - type: CropAnimatedImageMessageType.BATCH_COMPLETE, - jobId, - processedFrames: [], - encodedGifChunks, - }; - self.postMessage(response, transferables); - return; - } - const rawFrames = batch.frames.every((frame) => frame.width != null && frame.height != null); - if (rawFrames) { - const processedDecodedFrames: Array = []; - for (const frame of batch.frames) { - const transformed = cropRotateRgba( - frame.data, - frame.width ?? 0, - frame.height ?? 0, - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - processedDecodedFrames.push({ - rgba: transformed.rgba, - width: transformed.width, - height: transformed.height, - delayMs: frame.delayMs ?? frame.delay, - }); - } - const transferables = processedDecodedFrames.map((frame) => frame.rgba.buffer); - const response: ProcessBatchCompleteMessage = { - type: CropAnimatedImageMessageType.BATCH_COMPLETE, - jobId, - processedFrames: [], - processedDecodedFrames, - }; - self.postMessage(response, transferables); - return; - } - const processedFrames: Array = []; - for (const frame of batch.frames) { - const croppedFrame = cropAndRotateImage( - frame.data, - 'png', - x, - y, - width, - height, - imageRotation, - resizeWidth, - resizeHeight, - ); - processedFrames.push(croppedFrame); - } - const transferables: Array = processedFrames - .filter((frame) => frame.buffer) - .map((frame) => frame.buffer); - const response: ProcessBatchCompleteMessage = { - type: CropAnimatedImageMessageType.BATCH_COMPLETE, - jobId, - processedFrames, - }; - self.postMessage(response, transferables); - } catch (err) { - postError('internal', err); - } finally { - releaseLibfluxcoreMemoryIfIdle(); - } -} +self.addEventListener('message', (event: MessageEvent) => { + if (event.data?.type !== 'crop') return; + void handleCrop(event.data); +}); diff --git a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerManager.ts b/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerManager.ts index 7d211dbfc..847d4c3ad 100644 --- a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerManager.ts +++ b/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerManager.ts @@ -1,675 +1,135 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import { - type AnimatedImageFormat, - CropAnimatedImageMessageType, - type CropAnimatedImageStartMessage, - type CropOutputFormat, + type AnimatedCropOutputMime, + type AnimatedCropSourceFormat, + type CropErrorCode, type CropParams, - type CropWorkerErrorCode, - type CropWorkerImageFormat, - type DecodedFrameInput, - type ProcessBatchCompleteMessage, - type ProcessBatchMessage, + CropPipelineError, + type CropProgressPhase, + type CropStats, + type CropWorkerRequest, + type CropWorkerResponse, } from '@app/features/expressions/workers/AnimatedImageCropMessages'; -import {getNativeBridge, type NativeFrame, pickDecoderRouteFor} from '@app/features/messaging/utils/MediaNativeBridge'; -import { - drawVideoFrameToCanvas, - type FluxerImageDecoderInstance, - getImageDecoderConstructor, -} from '@app/features/platform/utils/ImageDecoderInterop'; -import { - cropRotateRgba, - ensureLibfluxcoreReady, - releaseLibfluxcoreMemoryIfIdle, -} from '@app/features/platform/utils/LibFluxcore'; -interface WorkerRequest { - resolve: (result: Uint8Array) => void; - reject: (error: Error) => void; - timeout: NodeJS.Timeout; +export {CropPipelineError}; + +const STALL_TIMEOUT_MS = 45_000; + +let lastJobId = 0; + +export interface AnimatedCropRequest { + bytes: ArrayBuffer; + format: AnimatedCropSourceFormat; + crop: CropParams; + sizeLimitBytes: number; } -interface WorkerState { - worker: Worker; - busy: boolean; - currentRequest: WorkerRequest | null; +export interface AnimatedCropProgress { + phase: CropProgressPhase; + fraction: number; } -interface BatchRequest { - reject: (error: Error) => void; - cleanup: () => void; +export interface AnimatedCropOptions { + signal: AbortSignal; + onProgress?: (progress: AnimatedCropProgress) => void; } -const PARALLEL_FRAME_THRESHOLD = 8; -const PARALLEL_PIXEL_THRESHOLD = 1_000_000; -const WORKER_IDLE_TIMEOUT_MS = 30_000; - -export class CropPipelineError extends Error { - readonly code: CropWorkerErrorCode; - - constructor(code: CropWorkerErrorCode, message: string) { - super(message); - this.code = code; - this.name = 'CropPipelineError'; - } -} - -export interface CropSource { +export interface AnimatedCropResult { bytes: Uint8Array; - mime: string; - format?: CropWorkerImageFormat; + mime: AnimatedCropOutputMime; + stats: CropStats; } -export interface CropOptionsEx extends CropParams { - outputFormat?: CropOutputFormat; +function abortedError(): CropPipelineError { + return new CropPipelineError('aborted', 'Animated crop was aborted'); } -export class AnimatedImageCropWorkerManager { - private static instance: AnimatedImageCropWorkerManager | null = null; - private workers: Array = []; - private readonly pendingBatchRequests = new Set(); - private readonly maxWorkers: number; - private terminated = false; - private activeJobCount = 0; - private idleTerminationTimeout: NodeJS.Timeout | null = null; - private readonly workerTimeout: number = 30000; +export function cropAnimatedImage( + request: AnimatedCropRequest, + options: AnimatedCropOptions, +): Promise { + const {signal, onProgress} = options; + if (signal.aborted) return Promise.reject(abortedError()); + const jobId = ++lastJobId; - private constructor() { - this.maxWorkers = Math.max(1, Math.min(4, (navigator.hardwareConcurrency || 4) - 1)); - } - - static getInstance(): AnimatedImageCropWorkerManager { - if (!AnimatedImageCropWorkerManager.instance) { - AnimatedImageCropWorkerManager.instance = new AnimatedImageCropWorkerManager(); - } - return AnimatedImageCropWorkerManager.instance; - } - - private ensureWorkersInitialized(): void { - if (this.workers.length < this.maxWorkers && !this.terminated) { - const workersToCreate = this.maxWorkers - this.workers.length; - for (let i = 0; i < workersToCreate; i++) { - const worker = new Worker( - new URL(/* webpackChunkName: "animated-image-crop.worker" */ './AnimatedImageCropWorker.ts', import.meta.url), - { - type: 'module', - }, - ); - const workerState: WorkerState = { - worker, - busy: false, - currentRequest: null, - }; - worker.addEventListener('message', (event: MessageEvent) => { - this.handleWorkerMessage(workerState, event); - }); - worker.addEventListener('error', (error) => { - this.handleWorkerError(workerState, error); - }); - this.workers.push(workerState); - } - } - } - - private handleWorkerMessage(workerState: WorkerState, event: MessageEvent): void { - const msg = event.data; - const request = workerState.currentRequest; - if (!request) { + return new Promise((resolve, reject) => { + let worker: Worker; + try { + worker = new Worker( + new URL(/* webpackChunkName: "animated-image-crop.worker" */ './AnimatedImageCropWorker.ts', import.meta.url), + {type: 'module'}, + ); + } catch (error) { + reject(new CropPipelineError('internal', error instanceof Error ? error.message : String(error))); return; } - if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_COMPLETE) { - clearTimeout(request.timeout); - workerState.busy = false; - workerState.currentRequest = null; - if (msg.result) { - request.resolve(msg.result); - } else { - request.reject(new CropPipelineError('internal', 'Empty result from worker')); - } - } else if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR) { - clearTimeout(request.timeout); - workerState.busy = false; - workerState.currentRequest = null; - const code: CropWorkerErrorCode = msg.code ?? 'internal'; - request.reject(new CropPipelineError(code, msg.error || 'Unknown error from worker')); - } - } + let settled = false; + let stallTimer: ReturnType | null = null; - private handleWorkerError(workerState: WorkerState, error: ErrorEvent): void { - const request = workerState.currentRequest; - if (request) { - clearTimeout(request.timeout); - workerState.currentRequest = null; - request.reject( - new CropPipelineError( - 'internal', - `Worker error: ${error.message || 'unknown error (worker script may have failed to load)'}`, - ), - ); - } - workerState.busy = false; - try { - workerState.worker.terminate(); - } catch {} - const index = this.workers.indexOf(workerState); - if (index !== -1) { - this.workers.splice(index, 1); - } - } + const settle = (finish: () => void): void => { + if (settled) return; + settled = true; + if (stallTimer !== null) clearTimeout(stallTimer); + stallTimer = null; + worker.removeEventListener('message', handleMessage); + worker.removeEventListener('error', handleError); + worker.removeEventListener('messageerror', handleMessageError); + signal.removeEventListener('abort', handleAbort); + worker.terminate(); + finish(); + }; + const fail = (code: CropErrorCode, message: string): void => { + settle(() => reject(new CropPipelineError(code, message))); + }; + const armStallTimer = (): void => { + if (stallTimer !== null) clearTimeout(stallTimer); + stallTimer = setTimeout(() => fail('timeout', 'Animated crop worker stopped responding'), STALL_TIMEOUT_MS); + }; - async cropImage(imageBytes: Uint8Array, format: AnimatedImageFormat, options: CropParams): Promise { - return this.cropImageEx({bytes: imageBytes, mime: mimeForAnimatedFormat(format), format}, options); - } - - async cropImageEx(source: CropSource, options: CropOptionsEx): Promise { - if (this.terminated) { - throw new CropPipelineError('internal', 'Worker manager has been terminated'); - } - const mime = source.mime.toLowerCase(); - if (mime === 'application/json' || mime === 'application/lottie+json') { - throw new CropPipelineError('lottie_unsupported', "Lottie can't be cropped. Upload a square JSON instead."); - } - const route = pickDecoderRouteFor(mime, getNativeBridge() !== null); - const wasmFormat = inferWasmFormat(mime, source.format); - if (route === 'unsupported') { - if (mime === 'image/heic' || mime === 'image/heif') { - throw new CropPipelineError( - 'heic_unsupported_in_browser', - 'HEIC decode requires the desktop app or a Safari browser', - ); - } - throw new CropPipelineError('unsupported_mime', `unsupported MIME type: ${mime}`); - } - if (route === 'libfluxcore' && wasmFormat) { - return this.runLibfluxcoreWorker(source.bytes, wasmFormat, options, options.outputFormat); - } - if (route !== 'native' && route !== 'browser') { - throw new CropPipelineError('unsupported_mime', `unhandled decoder route: ${route}`); - } - const frames = await this.decodeToFrames(source, route); - return this.encodeCroppedFrames(frames, options); - } - - private runLibfluxcoreWorker( - imageBytes: Uint8Array, - format: CropWorkerImageFormat, - options: CropParams, - outputFormat: CropOutputFormat | undefined, - ): Promise { - if (this.terminated) { - throw new CropPipelineError('internal', 'Worker manager has been terminated'); - } - this.beginJob(); - return this.dispatchLibfluxcoreWorker(imageBytes, format, options, outputFormat).finally(() => { - this.endJob(); - }); - } - - private dispatchLibfluxcoreWorker( - imageBytes: Uint8Array, - format: CropWorkerImageFormat, - options: CropParams, - outputFormat: CropOutputFormat | undefined, - ): Promise { - if (this.terminated) { - return Promise.reject(new CropPipelineError('internal', 'Worker manager has been terminated')); - } - this.ensureWorkersInitialized(); - const workerState = this.findAvailableWorker(); - if (!workerState) { - return new Promise((resolve, reject) => { - setTimeout(() => { - this.dispatchLibfluxcoreWorker(imageBytes, format, options, outputFormat).then(resolve, reject); - }, 50); - }); - } - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => { - workerState.busy = false; - workerState.currentRequest = null; - reject(new CropPipelineError('internal', `Crop operation timed out after ${this.workerTimeout}ms`)); - }, this.workerTimeout); - workerState.busy = true; - workerState.currentRequest = {resolve, reject, timeout}; - const message: CropAnimatedImageStartMessage = { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_START, - imageBytes, - format, - ...options, - outputFormat, - }; - const transferables: Array = []; - if (imageBytes.buffer) { - transferables.push(imageBytes.buffer); - } - workerState.worker.postMessage(message, transferables); - }); - } - - private async decodeToFrames(source: CropSource, route: 'native' | 'browser'): Promise> { - if (route === 'native') { - const bridge = getNativeBridge(); - if (!bridge) { - throw new CropPipelineError('decode_failed', 'native bridge unavailable'); - } - try { - if (source.mime === 'image/heic' || source.mime === 'image/heif') { - const f = bridge.decodeHeic(source.bytes); - return [{rgba: f.rgba, width: f.width, height: f.height, delayMs: 0}]; - } - if (source.mime === 'image/jxl') { - const f = bridge.decodeJxl(source.bytes); - return [{rgba: f.rgba, width: f.width, height: f.height, delayMs: 0}]; - } - const decoded = bridge.decodeImage(source.bytes); - return decoded.frames; - } catch (err) { - throw new CropPipelineError( - 'decode_failed', - err instanceof Error ? err.message : `failed to decode ${source.mime}`, - ); - } - } - return decodeViaImageDecoder(source); - } - - private async encodeCroppedFrames(frames: Array, options: CropOptionsEx): Promise { - if (frames.length === 0) { - throw new CropPipelineError('decode_failed', 'no frames decoded'); - } - let cropped: Array; - try { - await ensureLibfluxcoreReady(); - cropped = await this.cropDecodedFrames(frames, options); - } catch (err) { - throw new CropPipelineError('internal', err instanceof Error ? err.message : 'wasm RGBA crop failed'); - } finally { - releaseLibfluxcoreMemoryIfIdle(); - } - const isAnimated = frames.length > 1; - const outputFormat: CropOutputFormat = options.outputFormat ?? (isAnimated ? 'animated_webp' : 'webp'); - const bridge = getNativeBridge(); - if (outputFormat === 'animated_webp' || outputFormat === 'apng') { - if (!bridge) { - throw new CropPipelineError('encode_failed', 'animated output requires the native bridge (desktop app)'); - } - try { - if (outputFormat === 'animated_webp') return bridge.encodeAnimatedWebp(cropped); - return bridge.encodeAnimatedApng(cropped); - } catch (err) { - throw new CropPipelineError('encode_failed', err instanceof Error ? err.message : 'animated encode failed'); - } - } - const first = cropped[0]; - if (first === undefined) { - throw new CropPipelineError('encode_failed', 'no cropped frame available'); - } - if (outputFormat === 'avif') { - if (!bridge) throw new CropPipelineError('encode_failed', 'AVIF encode requires the native bridge'); - try { - return bridge.encodeAvif(first.rgba, first.width, first.height, true); - } catch (err) { - throw new CropPipelineError('encode_failed', err instanceof Error ? err.message : 'AVIF encode failed'); - } - } - return encodeViaCanvas(first, outputFormat); - } - - private async cropDecodedFrames(frames: Array, options: CropOptionsEx): Promise> { - if (this.shouldCropFramesInWorkers(frames)) { - return this.cropFramesInWorkerBatches(frames, options); - } - return frames.map((frame) => cropDecodedFrame(frame, options)); - } - - private shouldCropFramesInWorkers(frames: Array): boolean { - if (frames.length < PARALLEL_FRAME_THRESHOLD || this.maxWorkers <= 1) return false; - let pixels = 0; - for (const frame of frames) pixels += frame.width * frame.height; - return pixels >= PARALLEL_PIXEL_THRESHOLD; - } - - private async cropFramesInWorkerBatches( - frames: Array, - options: CropOptionsEx, - ): Promise> { - this.beginJob(); - try { - this.ensureWorkersInitialized(); - const availableWorkers = this.workers.filter((worker) => !worker.busy); - if (availableWorkers.length <= 1) { - return frames.map((frame) => cropDecodedFrame(frame, options)); - } - const batches = createFrameBatches(frames, availableWorkers.length); - const results = await Promise.all( - batches.map((batch, index) => - this.processFrameBatchWithWorker(availableWorkers[index], index + 1, batch, options), - ), - ); - const ordered: Array = new Array(frames.length); - for (const batch of results) { - for (const item of batch) ordered[item.index] = item.frame; - } - return ordered.map((frame, index) => { - if (!frame) throw new CropPipelineError('internal', `Missing transformed frame ${index}`); - return frame; - }); - } finally { - this.endJob(); - } - } - - private processFrameBatchWithWorker( - workerState: WorkerState, - jobId: number, - batch: Array<{frame: NativeFrame; index: number}>, - options: CropOptionsEx, - ): Promise> { - return new Promise((resolve, reject) => { - let pendingBatchRequest: BatchRequest | null = null; - const timeout = setTimeout(() => { - cleanup(); - workerState.busy = false; - reject(new CropPipelineError('internal', `Frame batch timed out after ${this.workerTimeout}ms`)); - }, this.workerTimeout); - const cleanup = () => { - clearTimeout(timeout); - workerState.worker.removeEventListener('message', handleMessage); - workerState.worker.removeEventListener('error', handleError); - if (pendingBatchRequest) { - this.pendingBatchRequests.delete(pendingBatchRequest); - pendingBatchRequest = null; - } - }; - const handleMessage = (event: MessageEvent) => { - const msg = event.data; - if (msg.type !== CropAnimatedImageMessageType.BATCH_COMPLETE || msg.jobId !== jobId) return; - cleanup(); - workerState.busy = false; - const processed = msg.processedDecodedFrames; - if (!processed) { - reject(new CropPipelineError('internal', 'Frame batch returned no decoded frames')); + function handleMessage(event: MessageEvent): void { + const message = event.data; + if (message?.jobId !== jobId) return; + armStallTimer(); + switch (message.type) { + case 'progress': + onProgress?.({phase: message.phase, fraction: message.total > 0 ? message.done / message.total : 0}); + return; + case 'done': + settle(() => resolve({bytes: new Uint8Array(message.bytes), mime: message.mime, stats: message.stats})); + return; + case 'error': + fail(message.code, message.message); return; - } - resolve(processed.map((frame, offset) => ({frame, index: batch[offset]?.index ?? offset}))); - }; - const handleError = (error: ErrorEvent) => { - cleanup(); - workerState.busy = false; - reject( - new CropPipelineError( - 'internal', - `Worker error: ${error.message || 'unknown error (frame batch worker failed)'}`, - ), - ); - }; - workerState.busy = true; - pendingBatchRequest = {reject, cleanup}; - this.pendingBatchRequests.add(pendingBatchRequest); - workerState.worker.addEventListener('message', handleMessage); - workerState.worker.addEventListener('error', handleError); - const message: ProcessBatchMessage = { - type: CropAnimatedImageMessageType.PROCESS_BATCH, - jobId, - cropParams: options, - batch: { - startIndex: 0, - operation: 'transform_rgba', - frames: batch.map(({frame}) => ({ - data: frame.rgba, - width: frame.width, - height: frame.height, - delay: frame.delayMs, - delayMs: frame.delayMs, - disposeOp: 0, - })), - }, - }; - const transferables = batch.map(({frame}) => frame.rgba.buffer); - workerState.worker.postMessage(message, transferables); - }); - } - - private findAvailableWorker(): WorkerState | null { - for (const workerState of this.workers) { - if (!workerState.busy) { - return workerState; } } - return null; - } - - private beginJob(): void { - this.clearIdleTermination(); - this.activeJobCount += 1; - } - - private endJob(): void { - this.activeJobCount = Math.max(0, this.activeJobCount - 1); - this.scheduleIdleTermination(); - } - - private isPoolIdle(): boolean { - return ( - this.activeJobCount === 0 && - this.pendingBatchRequests.size === 0 && - this.workers.every((workerState) => !workerState.busy && workerState.currentRequest === null) - ); - } - - private clearIdleTermination(): void { - if (this.idleTerminationTimeout === null) { - return; + function handleError(event: ErrorEvent): void { + fail('internal', event.message || 'Animated crop worker failed'); } - clearTimeout(this.idleTerminationTimeout); - this.idleTerminationTimeout = null; - } - - private scheduleIdleTermination(): void { - this.clearIdleTermination(); - if (this.terminated || this.workers.length === 0 || !this.isPoolIdle()) { - return; + function handleMessageError(): void { + fail('internal', 'Animated crop worker sent a message that could not be read'); } - this.idleTerminationTimeout = setTimeout(() => { - this.idleTerminationTimeout = null; - if (this.isPoolIdle()) { - this.terminateIdleWorkers(); - } - }, WORKER_IDLE_TIMEOUT_MS); - } - - private terminateIdleWorkers(): void { - for (const workerState of this.workers) { - try { - workerState.worker.terminate(); - } catch {} + function handleAbort(): void { + settle(() => reject(abortedError())); } - this.workers = []; - } - getActiveWorkerCount(): number { - return this.workers.filter((w) => w.busy).length; - } - - getTotalWorkerCount(): number { - return this.workers.length; - } - - terminate(): void { - if (this.terminated) { - return; + worker.addEventListener('message', handleMessage); + worker.addEventListener('error', handleError); + worker.addEventListener('messageerror', handleMessageError); + signal.addEventListener('abort', handleAbort); + armStallTimer(); + const message: CropWorkerRequest = { + type: 'crop', + jobId, + bytes: request.bytes, + format: request.format, + crop: request.crop, + sizeLimitBytes: request.sizeLimitBytes, + }; + try { + worker.postMessage(message, [request.bytes]); + } catch (error) { + fail('internal', error instanceof Error ? error.message : String(error)); } - this.terminated = true; - this.clearIdleTermination(); - for (const workerState of this.workers) { - if (workerState.currentRequest) { - clearTimeout(workerState.currentRequest.timeout); - workerState.currentRequest.reject(new CropPipelineError('internal', 'Worker manager terminated')); - } - workerState.worker.terminate(); - } - const error = new CropPipelineError('internal', 'Worker manager terminated'); - for (const request of Array.from(this.pendingBatchRequests)) { - request.cleanup(); - request.reject(error); - } - this.pendingBatchRequests.clear(); - this.workers = []; - AnimatedImageCropWorkerManager.instance = null; - } - - restart(): void { - if (!this.terminated) { - return; - } - this.terminated = false; - this.ensureWorkersInitialized(); - this.scheduleIdleTermination(); - } -} - -function inferWasmFormat(mime: string, hint: CropWorkerImageFormat | undefined): CropWorkerImageFormat | null { - if (hint) return hint; - switch (mime) { - case 'image/png': - return 'png'; - case 'image/apng': - return 'apng'; - case 'image/jpeg': - return 'jpeg'; - case 'image/gif': - return 'gif'; - case 'image/webp': - return 'webp'; - case 'image/avif': - return 'avif'; - default: - return null; - } -} - -function mimeForAnimatedFormat(format: AnimatedImageFormat): string { - switch (format) { - case 'apng': - return 'image/apng'; - case 'gif': - return 'image/gif'; - case 'webp': - return 'image/webp'; - case 'avif': - return 'image/avif'; - } -} - -function cropDecodedFrame(frame: NativeFrame, options: CropOptionsEx): NativeFrame { - const transformed = cropRotateRgba( - frame.rgba, - frame.width, - frame.height, - options.x, - options.y, - options.width, - options.height, - options.imageRotation ?? 0, - options.resizeWidth ?? null, - options.resizeHeight ?? null, - ); - return { - rgba: transformed.rgba, - width: transformed.width, - height: transformed.height, - delayMs: frame.delayMs, - }; -} - -function createFrameBatches( - frames: Array, - workerCount: number, -): Array> { - const batches: Array> = Array.from({length: workerCount}, () => []); - for (let index = 0; index < frames.length; index += 1) { - batches[index % workerCount]?.push({frame: frames[index], index}); - } - return batches.filter((batch) => batch.length > 0); -} - -async function encodeViaCanvas(frame: NativeFrame, format: 'webp' | 'png' | 'jpeg' | 'gif'): Promise { - if (typeof OffscreenCanvas === 'undefined') { - throw new CropPipelineError('encode_failed', 'OffscreenCanvas required for static encode fallback'); - } - const canvas = new OffscreenCanvas(frame.width, frame.height); - const ctx = canvas.getContext('2d'); - if (!ctx) throw new CropPipelineError('encode_failed', 'no 2d context'); - const imageData = new ImageData(new Uint8ClampedArray(frame.rgba), frame.width, frame.height); - ctx.putImageData(imageData, 0, 0); - const mime = format === 'jpeg' ? 'image/jpeg' : format === 'gif' ? 'image/gif' : `image/${format}`; - let blob: Blob; - try { - blob = await canvas.convertToBlob({type: mime, quality: 0.92}); - } catch (err) { - throw new CropPipelineError('encode_failed', err instanceof Error ? err.message : 'canvas encode failed'); - } - const buffer = await blob.arrayBuffer(); - return new Uint8Array(buffer); -} - -async function decodeViaImageDecoder(source: CropSource): Promise> { - const Cls = getImageDecoderConstructor(); - if (!Cls) { - throw new CropPipelineError('decode_failed', 'ImageDecoder unavailable in this browser'); - } - let decoder: FluxerImageDecoderInstance | null = null; - try { - decoder = new Cls({data: source.bytes, type: source.mime, preferAnimation: true}); - await decoder.completed; - const track = decoder.tracks.selectedTrack; - const frameCount = Math.max(1, track?.frameCount ?? 1); - const frames: Array = []; - for (let i = 0; i < frameCount; i++) { - const {image} = await decoder.decode({frameIndex: i, completeFramesOnly: true}); - try { - const w = image.displayWidth; - const h = image.displayHeight; - if (typeof OffscreenCanvas === 'undefined') { - throw new CropPipelineError('decode_failed', 'OffscreenCanvas required for ImageDecoder fallback'); - } - const canvas = new OffscreenCanvas(w, h); - const ctx = canvas.getContext('2d'); - if (!ctx) throw new CropPipelineError('decode_failed', 'no 2d context'); - drawVideoFrameToCanvas(ctx, image); - const data = ctx.getImageData(0, 0, w, h); - const delayMs = (image.duration ?? 0) / 1000; - frames.push({rgba: new Uint8Array(data.data.buffer.slice(0)), width: w, height: h, delayMs}); - } finally { - image.close(); - } - } - return frames; - } catch (err) { - throw new CropPipelineError( - 'decode_failed', - err instanceof Error ? err.message : `failed to decode ${source.mime}`, - ); - } finally { - decoder?.close(); - } -} - -export async function cropAnimatedImageWithWorkerPool( - imageBytes: Uint8Array, - format: AnimatedImageFormat, - options: CropParams, -): Promise { - const manager = AnimatedImageCropWorkerManager.getInstance(); - return manager.cropImage(imageBytes, format, options); -} - -export async function cropImageWithSource(source: CropSource, options: CropOptionsEx): Promise { - const manager = AnimatedImageCropWorkerManager.getInstance(); - return manager.cropImageEx(source, options); -} - -export function getWorkerManager(): AnimatedImageCropWorkerManager { - return AnimatedImageCropWorkerManager.getInstance(); + }); } diff --git a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerPool.ts b/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerPool.ts deleted file mode 100644 index c41def3a3..000000000 --- a/fluxer_app/src/features/expressions/workers/AnimatedImageCropWorkerPool.ts +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -import { - type AnimatedImageFormat, - type CropAnimatedImageCompleteMessage, - type CropAnimatedImageErrorMessage, - CropAnimatedImageMessageType, - type CropAnimatedImageStartMessage, - type CropParams, - type FrameBatch, -} from '@app/features/expressions/workers/AnimatedImageCropMessages'; - -interface WorkerJob { - indices: Array; - frames: Array; - resolve: (value: Uint8Array) => void; - reject: (reason?: unknown) => void; - timeout: NodeJS.Timeout; -} - -interface WorkerState { - worker: Worker; - busy: boolean; - currentJob: WorkerJob | null; -} - -const DEFAULT_TIMEOUT = 30000; - -export class AnimatedImageCropWorkerPool { - private workers: Array; - private readonly timeout: number; - private terminated: boolean = false; - - constructor(workerCount?: number, timeout: number = DEFAULT_TIMEOUT) { - const concurrency = workerCount ?? Math.max(1, (navigator.hardwareConcurrency || 4) - 1); - this.timeout = timeout; - this.workers = []; - for (let i = 0; i < concurrency; i++) { - const worker = new Worker( - new URL(/* webpackChunkName: "animated-image-crop.worker" */ './AnimatedImageCropWorker.ts', import.meta.url), - { - type: 'module', - }, - ); - this.workers.push({ - worker, - busy: false, - currentJob: null, - }); - } - } - - async processFramesParallel( - frames: Array, - cropParams: CropParams, - format: AnimatedImageFormat = 'gif', - ): Promise> { - if (this.terminated) { - throw new Error('Worker pool has been terminated'); - } - if (frames.length === 0) { - return []; - } - if (frames.length === 1) { - return [await this.processSingleFrame(frames[0], cropParams, format)]; - } - const batches = this.createBatches(frames); - const workerCount = this.workers.length; - const results: Array<{ - index: number; - data: Uint8Array; - }> = []; - const batchPromises = batches.map((batch, batchIndex) => { - const workerIndex = batchIndex % workerCount; - return this.processBatchWithWorker(workerIndex, batch, cropParams, format); - }); - const batchResults = await Promise.all(batchPromises); - for (const batchResult of batchResults) { - results.push(...batchResult); - } - results.sort((a, b) => a.index - b.index); - return results.map((r) => r.data); - } - - private createBatches(frames: Array): Array { - const workerCount = this.workers.length; - const batches: Array = []; - const framesPerBatch = Math.ceil(frames.length / workerCount); - for (let i = 0; i < workerCount && i * framesPerBatch < frames.length; i++) { - const startIndex = i * framesPerBatch; - const endIndex = Math.min(startIndex + framesPerBatch, frames.length); - const batchFrames = frames.slice(startIndex, endIndex); - batches.push({ - startIndex, - frames: batchFrames.map((data) => ({ - data, - delay: 0, - disposeOp: 0, - })), - }); - } - return batches; - } - - private async processBatchWithWorker( - workerIndex: number, - batch: FrameBatch, - cropParams: CropParams, - format: AnimatedImageFormat, - ): Promise< - Array<{ - index: number; - data: Uint8Array; - }> - > { - const workerState = this.workers[workerIndex]; - if (!workerState) { - throw new Error(`Worker at index ${workerIndex} not found`); - } - const results: Array<{ - index: number; - data: Uint8Array; - }> = []; - for (let i = 0; i < batch.frames.length; i++) { - const frameData = batch.frames[i].data; - const frameIndex = batch.startIndex + i; - try { - const croppedData = await this.processFrameWithWorker(workerIndex, frameData, cropParams, format); - results.push({index: frameIndex, data: croppedData}); - } catch (error) { - console.warn(`Worker ${workerIndex} failed for frame ${frameIndex}, attempting recovery:`, error); - const recoveredWorkerIndex = (workerIndex + 1) % this.workers.length; - try { - const croppedData = await this.processFrameWithWorker(recoveredWorkerIndex, frameData, cropParams, format); - results.push({index: frameIndex, data: croppedData}); - } catch (recoveryError) { - const message = recoveryError instanceof Error ? recoveryError.message : String(recoveryError); - throw new Error(`Failed to process frame ${frameIndex} after recovery attempt: ${message}`); - } - } - } - return results; - } - - private processFrameWithWorker( - workerIndex: number, - frameData: Uint8Array, - cropParams: CropParams, - format: AnimatedImageFormat, - ): Promise { - return new Promise((resolve, reject) => { - const workerState = this.workers[workerIndex]; - if (!workerState) { - reject(new Error(`Worker at index ${workerIndex} not found`)); - return; - } - const timeout = setTimeout(() => { - workerState.busy = false; - workerState.currentJob = null; - reject(new Error(`Worker timeout after ${this.timeout}ms`)); - }, this.timeout); - const message: CropAnimatedImageStartMessage = { - type: CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_START, - imageBytes: frameData, - format, - ...cropParams, - }; - const handleMessage = (event: MessageEvent) => { - const msg = event.data; - if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_COMPLETE) { - clearTimeout(timeout); - workerState.busy = false; - workerState.currentJob = null; - workerState.worker.removeEventListener('message', handleMessage); - workerState.worker.removeEventListener('error', handleError); - const completeMsg = msg as CropAnimatedImageCompleteMessage; - if (completeMsg.result) { - resolve(completeMsg.result); - } else { - reject(new Error('Empty result from worker')); - } - } else if (msg.type === CropAnimatedImageMessageType.CROP_ANIMATED_IMAGE_ERROR) { - clearTimeout(timeout); - workerState.busy = false; - workerState.currentJob = null; - workerState.worker.removeEventListener('message', handleMessage); - workerState.worker.removeEventListener('error', handleError); - const errorMsg = msg as CropAnimatedImageErrorMessage; - reject(new Error(errorMsg.error || 'Unknown error from worker')); - } - }; - const handleError = (error: ErrorEvent) => { - clearTimeout(timeout); - workerState.busy = false; - workerState.currentJob = null; - workerState.worker.removeEventListener('message', handleMessage); - workerState.worker.removeEventListener('error', handleError); - reject(new Error(`Worker error: ${error.message || 'unknown error (worker script may have failed to load)'}`)); - }; - workerState.busy = true; - workerState.currentJob = { - indices: [0], - frames: [frameData], - resolve, - reject, - timeout, - }; - workerState.worker.addEventListener('message', handleMessage); - workerState.worker.addEventListener('error', handleError); - const transferables: Array = []; - if (frameData.buffer) { - transferables.push(frameData.buffer); - } - workerState.worker.postMessage(message, transferables); - }); - } - - private async processSingleFrame( - frame: Uint8Array, - cropParams: CropParams, - format: AnimatedImageFormat, - ): Promise { - const workerIndex = this.workers.findIndex((w) => !w.busy); - const targetWorkerIndex = workerIndex >= 0 ? workerIndex : 0; - return this.processFrameWithWorker(targetWorkerIndex, frame, cropParams, format); - } - - getWorkerCount(): number { - return this.workers.length; - } - - getBusyWorkerCount(): number { - return this.workers.filter((w) => w.busy).length; - } - - isIdle(): boolean { - return this.workers.every((w) => !w.busy); - } - - terminate(): void { - if (this.terminated) { - return; - } - this.terminated = true; - for (const workerState of this.workers) { - if (workerState.currentJob?.timeout) { - clearTimeout(workerState.currentJob.timeout); - } - try { - workerState.worker.terminate(); - } catch (error) { - console.warn('Error terminating worker:', error); - } - } - this.workers = []; - } - - restart(): void { - if (!this.terminated) { - this.terminate(); - } - this.terminated = false; - const concurrency = Math.max(1, (navigator.hardwareConcurrency || 4) - 1); - this.workers = []; - for (let i = 0; i < concurrency; i++) { - const worker = new Worker( - new URL(/* webpackChunkName: "animated-image-crop.worker" */ './AnimatedImageCropWorker.ts', import.meta.url), - { - type: 'module', - }, - ); - this.workers.push({ - worker, - busy: false, - currentJob: null, - }); - } - } -} diff --git a/fluxer_app/src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx b/fluxer_app/src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx index 953f7e295..ac0a88014 100644 --- a/fluxer_app/src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx +++ b/fluxer_app/src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx @@ -116,7 +116,6 @@ export const GuildCreateForm = observer(() => { { const reader = new FileReader(); reader.onload = () => { diff --git a/fluxer_app/src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx b/fluxer_app/src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx index f17320cf3..7b6220496 100644 --- a/fluxer_app/src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx +++ b/fluxer_app/src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx @@ -297,7 +297,6 @@ export const TemplateImportForm = observer(() => { { const reader = new FileReader(); reader.onload = () => { diff --git a/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx b/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx index f5132e1ff..d535e7d8c 100644 --- a/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx +++ b/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx @@ -1,26 +1,15 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import type {Gif} from '@app/features/expressions/commands/GifCommands'; -import { - AssetCropModal, - type AssetType, - canSkipOriginalAssetImage, -} from '@app/features/expressions/components/modals/AssetCropModal'; +import {AssetCropModal, type AssetType} from '@app/features/expressions/components/modals/AssetCropModal'; import {openAssetSourceModal} from '@app/features/expressions/components/modals/AssetSourceModal'; import {showAnimatedAvifUnsupportedModal} from '@app/features/expressions/utils/AnimatedAvifModalUtils'; -import { - getAnimatedFormatLabel, - isAnimatedFile, - shouldHandleAnimatedNonGifUpload, -} from '@app/features/expressions/utils/AnimatedImageUtils'; +import {inspectImageFile} from '@app/features/expressions/utils/AnimatedImageUtils'; import {downloadGifAsImageFile} from '@app/features/expressions/utils/GifFileDownload'; import {isSvgFile, readImageFileAsUploadDataUrl} from '@app/features/expressions/utils/ImageUploadFileUtils'; import {showGuildErrorModal} from '@app/features/guild/components/alerts/GuildErrorModalUtils'; import { blobToDataUrl, - getImageDimensionsFromDataUrl, - getSafeImageMimeType, - isGif, MAX_IMAGE_BYTES, revokeObjectUrl, } from '@app/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset'; @@ -31,9 +20,9 @@ import { } from '@app/features/i18n/utils/CommonMessageDescriptors'; import {openFilePicker} from '@app/features/messaging/utils/FilePickerUtils'; import {formatFileSize} from '@app/features/messaging/utils/FileUtils'; +import {canDecodeAnimatedAvif} from '@app/features/platform/utils/ImageDecoderInterop'; import * as ModalCommands from '@app/features/ui/commands/ModalCommands'; import {modal} from '@app/features/ui/commands/ModalCommands'; -import * as ToastCommands from '@app/features/ui/commands/ToastCommands'; import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; import {msg} from '@lingui/core/macro'; import {useLingui} from '@lingui/react/macro'; @@ -55,26 +44,11 @@ const ANIMATED_IMAGES_ARE_NOT_SUPPORTED_FOR_THIS_ASSET_DESCRIPTOR = msg({ message: 'Animated images are not supported for this asset.', comment: 'Confirmation modal body shown before using a non-croppable animated community image.', }); -const CROPPING_ANIMATED_FILES_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR = msg({ - message: "Cropping animated {formatLabel} files isn't supported yet. The original image will be used.", - comment: - 'Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name.', -}); -const CROPPING_ANIMATED_FILES_WITHOUT_FORMAT_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR = msg({ - message: "Cropping animated files isn't supported yet. The original image will be used.", - comment: 'Confirmation modal body shown before using an animated community image with an unknown format.', -}); const CROPPED_IMAGE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR = msg({ message: 'Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel}).', comment: 'Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size.', }); -const IMAGE_DIMENSIONS_DO_NOT_MATCH_THIS_ASSET_DESCRIPTOR = msg({ - message: - '{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop.', - comment: - 'Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field.', -}); const IMAGE_COULDN_T_BE_USED_DESCRIPTOR = msg({ message: "Image couldn't be used", comment: 'Error modal title shown when a community image upload cannot be accepted or processed.', @@ -197,22 +171,6 @@ export function useGuildImageAssetField({ }, [applyAspectRatio, aspectRatio, setFieldValue, setHasCleared, setPreviewUrl], ); - const canApplyOriginalDataUrl = useCallback( - async (dataUrl: string) => { - try { - const dimensions = await getImageDimensionsFromDataUrl(dataUrl); - if (canSkipOriginalAssetImage(assetType, dimensions)) { - return true; - } - showErrorModal(i18n._(IMAGE_DIMENSIONS_DO_NOT_MATCH_THIS_ASSET_DESCRIPTOR, {label})); - return false; - } catch { - showErrorModal(i18n._(INVALID_IMAGE_TRY_ANOTHER_DESCRIPTOR)); - return false; - } - }, - [assetType, i18n, label, showErrorModal], - ); const handleFile = useCallback( async (file: File | null) => { if (!file) return; @@ -224,7 +182,7 @@ export function useGuildImageAssetField({ return; } const svg = isSvgFile(file); - const animated = svg ? false : await isAnimatedFile(file); + const {format, animated} = svg ? {format: 'unknown', animated: false} : await inspectImageFile(file); if (animated) { const policy = gif?.mode ?? 'disallow'; if (policy === 'disallow') { @@ -246,6 +204,11 @@ export function useGuildImageAssetField({ } } } + const isAnimatedAvif = animated && format === 'avif'; + if (isAnimatedAvif && !(await canDecodeAnimatedAvif())) { + showAnimatedAvifUnsupportedModal({i18n}); + return; + } setIsProcessing(true); let sourceBase64: string; try { @@ -259,42 +222,12 @@ export function useGuildImageAssetField({ setIsProcessing(false); return; } - const animatedHandled = shouldHandleAnimatedNonGifUpload({ - file, - isGif: isGif(file), - animated, - onAnimatedAvif: () => { - setIsProcessing(false); - showAnimatedAvifUnsupportedModal({i18n}); - }, - onOtherAnimated: async () => { - if (!(await canApplyOriginalDataUrl(sourceBase64))) { - setIsProcessing(false); - return; - } - const formatLabel = getAnimatedFormatLabel(file); - ToastCommands.createToast({ - type: 'info', - children: - formatLabel == null - ? i18n._(CROPPING_ANIMATED_FILES_WITHOUT_FORMAT_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR) - : i18n._(CROPPING_ANIMATED_FILES_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR, {formatLabel}), - }); - await applyDataUrl(sourceBase64, file, requestId); - setIsProcessing(false); - }, - }); - if (animatedHandled) { - return; - } setIsProcessing(false); - const sourceMimeType = getSafeImageMimeType(file); ModalCommands.push( modal(() => ( { if (requestId !== requestIdRef.current) return; setIsProcessing(true); @@ -314,10 +247,14 @@ export function useGuildImageAssetField({ } } }} - onSkip={async () => { - if (requestId !== requestIdRef.current) return; - await applyDataUrl(sourceBase64, file, requestId); - }} + onSkip={ + isAnimatedAvif + ? undefined + : async () => { + if (requestId !== requestIdRef.current) return; + await applyDataUrl(sourceBase64, file, requestId); + } + } data-flx="guild.guild-tabs.guild-overview-tab.use-guild-image-asset-field.handle-file.asset-crop-modal" /> )), @@ -327,7 +264,6 @@ export function useGuildImageAssetField({ applyAspectRatio, applyDataUrl, assetType, - canApplyOriginalDataUrl, canManage, gif, label, diff --git a/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset.ts b/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset.ts index 84a9a1255..201a68746 100644 --- a/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset.ts +++ b/fluxer_app/src/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset.ts @@ -1,17 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later -import type {ImageDimensions} from '@app/features/expressions/utils/AssetImageGeometry'; -import {getImageUploadMimeType} from '@app/features/expressions/utils/ImageUploadFileUtils'; - export const MAX_IMAGE_BYTES = 10 * 1024 * 1024; -export function isGif(file: File): boolean { - const type = (file.type || '').toLowerCase(); - if (type === 'image/gif') return true; - const name = (file.name || '').toLowerCase(); - return name.endsWith('.gif'); -} - export function revokeObjectUrl(url: string | null | undefined): void { if (!url) return; if (!url.startsWith('blob:')) return; @@ -28,31 +18,3 @@ export function blobToDataUrl(blob: Blob): Promise { reader.readAsDataURL(blob); }); } - -export function getSafeImageMimeType(file: File): string { - return getImageUploadMimeType(file); -} - -export function getImageDimensionsFromDataUrl(dataUrl: string): Promise { - if (typeof Image === 'undefined') { - return Promise.reject(new Error('Image API is unavailable')); - } - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => { - if (img.naturalWidth > 0 && img.naturalHeight > 0) { - resolve({width: img.naturalWidth, height: img.naturalHeight}); - } else { - reject(new Error('Invalid image dimensions')); - } - img.onload = null; - img.onerror = null; - }; - img.onerror = () => { - reject(new Error('Failed to load image')); - img.onload = null; - img.onerror = null; - }; - img.src = dataUrl; - }); -} diff --git a/fluxer_app/src/features/i18n/locales/ar/messages.po b/fluxer_app/src/features/i18n/locales/ar/messages.po index 1995bce3e..abcf56e93 100644 --- a/fluxer_app/src/features/i18n/locales/ar/messages.po +++ b/fluxer_app/src/features/i18n/locales/ar/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}ی Ù‚Ű±ÙŠŰšÙ‹Ű§" msgid "{kilobits} kbps" msgstr "{kilobits} ÙƒÙŠÙ„ÙˆŰšŰȘ في Ű§Ù„Ű«Ű§Ù†ÙŠŰ©" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "ŰŁŰšŰčۧۯ {label} Ù„Ű§ ŰȘŰ·Ű§ŰšÙ‚ Ù‡Ű°Ű§ Ű§Ù„ŰčÙ†Ű”Ű±. ۧ۟ŰȘ۱ Ű”ÙˆŰ±Ű© Ù…ŰźŰȘÙ„ÙŰ© ŰŁÙˆ Ű­Ù…Ù‘Ù„ Ű”ÙˆŰ±Ű© ۫ۧۚŰȘŰ© يمكنك Ù‚Ű”Ù‡Ű§." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "ملف {label} ÙƒŰšÙŠŰ± ŰŹŰŻÙ‹Ű§. ۧ۟ŰȘ۱ Ù…Ù„ÙÙ‹Ű§ ŰŁŰ”Űș۱ من {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Ù„Ű§ يمكن ŰŁÙ† ŰȘكون Ű”ÙˆŰ± {label} مŰȘŰ­Ű±ÙƒŰ©. ۧ۳ŰȘŰźŰŻÙ… Ű”ÙˆŰ±Ű© ۫ۧۚŰȘŰ©." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„Ù†ŰŽŰ§Ű·" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Ű­ŰŻ Ű§Ù„Ù†ŰŽŰ§Ű·" @@ -3566,11 +3561,11 @@ msgstr "Ű§Ù„ŰłÙ…Ű§Ű­ ŰšÙ€ {everyoneMention} و{hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Ű§ŰłÙ…Ű­ لـ {PRODUCT_NAME} ŰšŰ§Ù„ÙˆŰ”ÙˆÙ„ Ű„Ù„Ù‰ Ű§Ù„ÙƒŰ§Ù…ÙŠŰ±Ű§ في {MACOS_SYSTEM_SETTINGS_NAME} ← {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} ← {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Ű§ŰłÙ…Ű­ لـ {PRODUCT_NAME} ŰšŰ§Ù„ÙˆŰ”ÙˆÙ„ Ű„Ù„Ù‰ Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† Ű§Ù„ŰźŰ§Ű” ŰšÙƒ في {MACOS_SYSTEM_SETTINGS_NAME} ← {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} ← {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Ű§ŰłÙ…Ű­ لـ {PRODUCT_NAME} ŰšŰ§Ù„ÙˆŰ”ÙˆÙ„ Ű„Ù„Ù‰ Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ† Ű§Ù„ŰźŰ§Ű” ŰšÙƒ. ŰȘŰ­Ù‚Ù‚ من ŰŽŰ±ÙŠŰ· ŰčÙ†ÙˆŰ§Ù† Ű§Ù„Ù…ŰȘŰ”ÙŰ­ ŰŁÙˆ Ű§Ù„Ű„ŰčۯۧۯۧŰȘ." @@ -3673,7 +3668,7 @@ msgstr "Ű§Ù„ŰłÙ…Ű§Ű­ Ù„Ù„ŰŁŰč۶ۧۥ Ű§Ù„Ű°ÙŠÙ† Ù„Ű§ يملكون Ű„Ű°Ù† {readMes msgid "Allow mentions for this role" msgstr "Ű§Ù„ŰłÙ…Ű§Ű­ ŰšŰ§Ù„Ű„ŰŽŰ§Ű±Ű© Ű„Ù„Ù‰ Ù‡Ű°Ű§ Ű§Ù„ŰŻÙˆŰ±" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Ű§Ù„ŰłÙ…Ű§Ű­ ŰšŰ§Ù„ÙˆŰ”ÙˆÙ„ Ű„Ù„Ù‰ Ű§Ù„Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ†" @@ -3942,25 +3937,21 @@ msgstr "و{remainingCount} ŰŁŰźŰ±Ù‰" msgid "Animate on interaction" msgstr "ŰȘŰ­Ű±ÙŠÙƒ ŰčÙ†ŰŻ Ű§Ù„ŰȘÙŰ§Űčل" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Ù…Ù„ÙŰ§ŰȘ {AVIF_FORMAT_LABEL} Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčÙˆÙ…Ű©. Ű­Ù…Ù‘Ù„ ملف {AVIF_FORMAT_LABEL} ۫ۧۚŰȘÙ‹Ű§ ŰšŰŻÙ„Ű§Ù‹ من Ű°Ù„Ùƒ." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Ű”ÙŠŰșŰ© {avifFormatLabel} Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčÙˆÙ…Ű©" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ŰȘŰȘÙˆÙŰ± Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ({ANIMATED_AVATAR_FORMATS}) Ű­Ű”Ű±ÙŠÙ‹Ű§ Ù„Ù…ŰŽŰȘŰ±ÙƒÙŠ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ({ANIMATED_AVATAR_FORMATS}) ŰșÙŠŰ± مŰȘۭۧ۩ في Ù‡Ű°Ű§ Ű§Ù„Ù…Ű«ÙŠÙ„. Ű­Ù…Ù‘Ù„ Ű”ÙˆŰ±Ű© ۫ۧۚŰȘŰ© ŰšŰŻÙ„Ű§Ù‹ من Ű°Ù„Ùƒ." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ŰȘŰȘŰ·Ù„Űš Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ({animatedAvatarFormats}) {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Ű”ÙˆŰ± Ű±Ù…ŰČÙŠŰ© ÙˆÙ„Ű§ÙŰȘۧŰȘ ملف ŰŽŰźŰ”ÙŠ مŰȘŰ­Ű±ÙƒŰ©" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± مŰȘۭۧ۩" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ŰȘŰȘŰ·Ù„Űš Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "مŰčŰ§ÙŠÙ†Ű© Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ©" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčÙˆÙ…Ű© Ù„Ù‡Ű°Ű§ Ű§Ù„ŰčÙ†Ű”Ű±." @@ -4947,7 +4938,7 @@ msgstr "Ű§ÙƒŰȘŰŽŰ§Ù Ű§Ù„Ù„ŰșŰ© ŰȘÙ„Ù‚Ű§ŰŠÙŠÙ‹Ű§" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "ŰȘŰčيين Ű­ŰŻ Ű§Ù„Ù†ŰŽŰ§Ű· ŰȘÙ„Ù‚Ű§ŰŠÙŠÙ‹Ű§" @@ -5127,15 +5118,15 @@ msgstr "مŰȘÙˆÙŰ± في ŰȘŰ·ŰšÙŠÙ‚ ۳۷ۭ Ű§Ù„Ù…ÙƒŰȘŰš." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ملف Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ© ÙƒŰšÙŠŰ± ŰŹŰŻÙ‹Ű§. ۧ۟ŰȘ۱ Ù…Ù„ÙÙ‹Ű§ ŰŁŰ”Űș۱ من {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ© ÙƒŰšÙŠŰ±Ű© ŰŹŰŻÙ‹Ű§. ۧ۟ŰȘ۱ Ű”ÙˆŰ±Ű© ŰŁŰ”Űș۱ من {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "ۧ۟ŰȘÙŠŰ§Ű± ÙˆŰ¶Űč Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" @@ -5187,11 +5178,11 @@ msgstr "ŰșÙŠŰ± مŰȘÙˆŰ§ŰŹŰŻ Ű­Ű§Ù„ÙŠÙ‹Ű§" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Ű§Ù„Ù…ŰłŰȘŰźŰŻÙ…ÙˆÙ† Ű§Ù„Ù…Ű­ŰžÙˆŰ±ÙˆÙ†" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Ù„Ű§ÙŰȘŰ©" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ملف Ű§Ù„Ù„Ű§ÙŰȘŰ© ÙƒŰšÙŠŰ± ŰŹŰŻÙ‹Ű§. ۧ۟ŰȘ۱ Ù…Ù„ÙÙ‹Ű§ ŰŁŰ”Űș۱ من {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "ۧ۟ŰȘÙŠŰ§Ű± ÙˆŰ¶Űč Ű§Ù„Ù„Ű§ÙŰȘŰ©" @@ -6107,8 +6098,8 @@ msgstr "ۧێŰȘŰ±Ù Ù‡ŰŻÙŠŰ© {premiumProductName} من ŰčÙ„Ű§Ù…Ű© ŰȘŰšÙˆÙŠŰš {pre msgid "Buy gift" msgstr "ێ۱ۧۥ Ù‡ŰŻÙŠŰ©" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ŰšŰ„Ù†ŰŽŰ§ŰŠÙƒ Ù…ŰŹŰȘمŰčÙ‹Ű§ŰŒ ÙŰ„Ù†Ùƒ ŰȘÙˆŰ§ÙÙ‚ Űčلى ۧŰȘۚۧŰč <0>ۄ۱ێۧۯۧŰȘ Ù…ŰŹŰȘمŰč {PRODUCT_NAME} ÙˆŰ§Ù„Ű§Ù„ŰȘŰČŰ§Ù… ŰšÙ‡Ű§." @@ -6361,7 +6352,7 @@ msgstr "Ù„Ű§ يمكن ŰȘŰ­Ù…ÙŠÙ„ Ű§Ù„Ù…Ù„ÙŰ§ŰȘ Ù‡Ù†Ű§" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "في Ű§Ù„Ù…Ù†ŰȘŰ”Ù" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ŰȘŰșÙŠÙŠŰ± Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" @@ -6627,9 +6618,9 @@ msgstr "ŰȘŰșÙŠÙŠŰ± Ű§Ù„ŰźÙ„ÙÙŠŰ©" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "ŰȘŰșÙŠÙŠŰ± Ű§Ù„Ù„Ű§ÙŰȘŰ©" @@ -6668,13 +6659,13 @@ msgstr "ŰȘŰșÙŠÙŠŰ± Ű§Ù„Ű§ŰłÙ… Ű§Ù„Ù…ŰłŰȘŰčۧ۱ في Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "ŰȘŰșÙŠÙŠŰ± Ű§Ù„ŰŁÙŠÙ‚ÙˆÙ†Ű©" @@ -7669,8 +7660,8 @@ msgstr "ۧ۳ŰȘÙ„Ű§Ù… Ű§Ù„Ù‡ŰŻÙŠŰ©" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Ű§Ù„Ù…Ű·Ű§Ù„ŰšŰ© ŰšŰ­ŰłŰ§ŰšÙƒ" @@ -8518,8 +8509,8 @@ msgstr "Ù…ŰŹŰȘمŰč ÙŠŰłÙ‡Ù‘Ù„ Ű§Ù„Ù‡ŰŹÙ…Ű§ŰȘ Ű§Ù„ŰŹÙ…Ű§ŰčÙŠŰ© ŰŁÙˆ Ű§Ù„Ű„ŰłŰ§ŰĄ msgid "Community filter" msgstr "ŰȘŰ”ÙÙŠŰ© Ű§Ù„Ù…ŰŹŰȘمŰčۧŰȘ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ŰŁÙŠÙ‚ÙˆÙ†Ű© Ű§Ù„Ù…ŰŹŰȘمŰč" @@ -8763,6 +8754,11 @@ msgstr "ŰŁŰČ۱ۧ۱ Ù…Ű±ŰšŰč Ű§Ù„Ű±ŰłŰ§Ù„Ű©" msgid "Composer focus" msgstr "Ű§Ù„ŰȘŰ±ÙƒÙŠŰČ Űčلى Ù…Ű±ŰšŰč Ű§Ù„Ű±ŰłŰ§Ù„Ű©" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "ŰŹŰ§Ű±ÙŠ Ű§Ù„Ű¶ŰșŰ·" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ÙˆŰ”Ù‘Ù„ ÙƒŰ§Ù…ÙŠŰ±Ű§ ŰŁÙˆ ŰŹÙ‡Ű§ŰČ Ű§Ù„ŰȘÙ‚Ű§Ű· Ű§ÙŰȘŰ±Ű§Ű¶ÙŠŰŒ Ű«Ù… msgid "Connect a display, then try again." msgstr "ÙˆŰ”Ù‘Ù„ ŰŽŰ§ŰŽŰ©ŰŒ Ű«Ù… Ű­Ű§ÙˆÙ„ Ù…Ű±Ű© ŰŁŰźŰ±Ù‰." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ÙˆŰ”Ù‘Ù„ Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ†Ù‹Ű§ ÙˆŰ­Ű§ÙˆÙ„ Ù…Ű±Ű© ŰŁŰźŰ±Ù‰." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ŰȘŰčŰ°Ù‘Ű± Ű„Ù†ŰŽŰ§ŰĄ Ù‡Ű°Ű§ Ű§Ù„Ù…Ù„Ű”Ù‚" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ŰȘŰč۰۱ Ù‚Ű” Ű§Ù„Ű”ÙˆŰ±Ű©" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ŰȘŰč۰۱ ŰȘŰ­ŰŻÙŠŰ« Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„Ù†ŰŽŰ§Ű· Ű§Ù„Ű”ÙˆŰȘي Ű§Ù„ŰąÙ†" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ŰȘŰč۰۱ ŰȘŰ­Ù…ÙŠÙ„ Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ŰȘŰčŰ°Ù‘Ű± ŰȘŰ­Ù…ÙŠÙ„ Ű§Ù„Ù„Ű§ÙŰȘŰ©" @@ -10230,7 +10226,7 @@ msgstr "Ű„Ù†ŰŽŰ§ŰĄ ÙˆÙ…ŰŽŰ§Ű±ÙƒŰ©" msgid "Create a community" msgstr "Ű„Ù†ŰŽŰ§ŰĄ Ù…ŰŹŰȘمŰč" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ŰŁÙ†ŰŽŰŠ Ù…ŰŹŰȘمŰčÙ‹Ű§ لك ÙˆÙ„ŰŁŰ”ŰŻÙ‚Ű§ŰŠÙƒ Ù„Ù„ŰŻŰ±ŰŻŰŽŰ©." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Ù‚Ű” ŰźÙ„ÙÙŠŰ© Ű§Ù„ŰŻŰčÙˆŰ©" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "مŰčŰ§ÙŠÙ†Ű© Ű§Ù„Ù‚Ű”" @@ -10500,30 +10496,15 @@ msgstr "Ù‚Ű” Ù„Ű§ÙŰȘŰ© Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Ű§Ù„Ű”ÙˆŰ±Ű© ŰšŰčŰŻ Ű§Ù„Ù‚Ű” ÙƒŰšÙŠŰ±Ű© ŰŹŰŻÙ‹Ű§. ۧ۟ŰȘ۱ Ù…Ù†Ű·Ù‚Ű© ŰŁŰ”Űș۱ ŰŁÙˆ Ù…Ù„ÙÙ‹Ű§ ŰŁŰ”Űș۱ (Ű§Ù„Ű­ŰŻ Ű§Ù„ŰŁÙ‚Ű”Ù‰ {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Ù‚Ű” Ù…Ù„ÙŰ§ŰȘ {formatLabel} Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčوم ŰšŰčŰŻ. ŰłÙŠŰȘم ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„ŰŁŰ”Ù„ÙŠŰ©." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Ù‚Ű” Ù…Ù„ÙŰ§ŰȘ {formatLabel} Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčوم ŰšŰčŰŻ. ŰłÙŠŰȘم ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŁŰ”Ù„ÙŠ Ű§Ù„Ű°ÙŠ ŰȘم ŰȘŰ­Ù…ÙŠÙ„Ù‡." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Ù‚Ű” Ű§Ù„Ù…Ù„ÙŰ§ŰȘ Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčوم ŰšŰčŰŻ. ŰłÙŠŰȘم ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„ŰŁŰ”Ù„ÙŠŰ©." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Ù‚Ű” Ű§Ù„Ù…Ù„ÙŰ§ŰȘ Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© ŰșÙŠŰ± Ù…ŰŻŰčوم ŰšŰčŰŻ. ŰłÙŠŰȘم ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŁŰ”Ù„ÙŠ Ű§Ù„Ű°ÙŠ ŰȘم ŰȘŰ­Ù…ÙŠÙ„Ù‡." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "ŰŹŰ§Ű±ÙŠ Ù‚Ű” {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Ù„ÙŠŰł Ù„ŰŻÙŠÙƒ ۭ۳ۧ۹۟" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ŰčŰŻÙ… Ű§Ù„Ű„ŰžÙ‡Ű§Ű±" @@ -16560,8 +16541,8 @@ msgstr "Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ù„Ù„Ù…Ű­Ű§ŰŻŰ«Ű§ŰȘ Ű§Ù„ŰŹÙ…Ű§ŰčÙŠŰ© ۚۧ۳ŰȘŰź msgid "Group DMs" msgstr "Ű§Ù„Ù…Ű­Ű§ŰŻŰ«Ű§ŰȘ Ű§Ù„ŰŹÙ…Ű§ŰčÙŠŰ©" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ŰŁÙŠÙ‚ÙˆÙ†Ű© Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©" @@ -16624,8 +16605,8 @@ msgstr "Ű„ŰčۯۧۯۧŰȘ Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©" msgid "Group typing states" msgstr "Ű­Ű§Ù„Ű§ŰȘ Ű§Ù„ÙƒŰȘۧۚ۩ في Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "ŰȘم ŰȘŰ­ŰŻÙŠŰ« Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ©" @@ -16803,7 +16784,7 @@ msgstr "Ù‚Ù„Űš" msgid "Hebrew" msgstr "Ű§Ù„ŰčŰšŰ±ÙŠŰ©" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Ű§Ù„Ű§Ű±ŰȘÙŰ§Űč" @@ -17510,7 +17491,7 @@ msgstr "ŰȘم Ù†ŰłŰź Ű§Ù„Ű”ÙˆŰ±Ű© Ű„Ù„Ù‰ Ű§Ù„Ű­Ű§ÙŰžŰ©" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ŰȘŰč۰۱ ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ű”ÙˆŰ±Ű©" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Ű§Ù„Ù…ŰžÙ‡Ű± ÙˆŰ§Ù„ŰŽÙƒÙ„" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ÙŠŰšŰŻÙˆ ŰŁÙ†Ùƒ ŰȘŰłŰȘŰźŰŻÙ… {0}. Ù‚ŰŻ ŰȘŰ€ŰŻÙŠ Ű„Ű¶Ű§ÙŰ© مŰčŰ§Ù„ŰŹŰ© {PRODUCT_NAME} فوقه Ű„Ù„Ù‰ ŰȘ۰ۚ۰ۚ Ù…ŰłŰȘوى Ű§Ù„Ű”ÙˆŰȘ ŰŁÙˆ ŰȘŰŽÙˆÙŠÙ‡Ù‡. ÙŠÙ…Ű±Ù‘Ű± Ű§Ù„Ű„ŰŻŰźŰ§Ù„ Ű§Ù„Ù…ŰšŰ§ŰŽŰ± Ű§Ù„Ű”ÙˆŰȘ ÙƒÙ…Ű§ هو ŰŻÙˆÙ† ŰŁÙŠ ŰȘŰčŰŻÙŠÙ„." @@ -22577,7 +22558,7 @@ msgstr "لم يŰȘم Ű§Ù„ŰčŰ«ÙˆŰ± Űčلى نŰȘۧۊۏ Ù…Ű·Ű§ŰšÙ‚Ű©" msgid "No mentions yet" msgstr "Ù„Ű§ ŰȘÙˆŰŹŰŻ ۄێۧ۱ۧŰȘ ŰšŰčŰŻ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "لم يŰȘم Ű§Ù„ŰčŰ«ÙˆŰ± Űčلى Ù…ÙŠÙƒŰ±ÙˆÙÙˆÙ†" @@ -23806,7 +23787,7 @@ msgstr "فŰȘŰ­ Ű±ŰłŰ§Ù„Ű© Ù…ŰšŰ§ŰŽŰ±Ű© من Ű§Ù„Ù†ŰžŰ§Ù…" msgid "Open system picker" msgstr "فŰȘŰ­ منŰȘقي Ű§Ù„Ù†ŰžŰ§Ù…" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "فŰȘŰ­ Ù‚Ű§Ù„Űš JSON" @@ -23820,7 +23801,7 @@ msgstr "Ű§ÙŰȘŰ­ Ù…Ű±ŰšŰč Ű­ÙˆŰ§Ű± Ű§Ù„Ű­ŰžŰ± Ù„Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč." msgid "Open the context menu" msgstr "فŰȘŰ­ Ù‚Ű§ŰŠÙ…Ű© Ű§Ù„ŰłÙŠŰ§Ù‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Ű§ÙŰȘŰ­ Ű§Ù„Ű±Ű§ŰšŰ· ŰŁŰŻÙ†Ű§Ù‡ في مŰȘŰ”ÙŰ­ÙƒŰŒ Ű«Ù… Ű§Ù†ŰłŰź ۧ۳ŰȘۏۧۚ۩ JSON ŰšŰ§Ù„ÙƒŰ§Ù…Ù„ ÙˆŰ§Ù„Ű”Ù‚Ù‡Ű§ في Ű§Ù„Ù…Ű±ŰšŰč." @@ -24331,7 +24312,7 @@ msgstr "۹۟۱ 7 ŰŁÙŠŰ§Ù…" msgid "Paste" msgstr "Ù„Ű”Ù‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Ű§Ù„Ű”Ù‚ ۱ۧۚ۷ Ù‚Ű§Ù„Űš {theOtherPlatform} Ù„Ű§ŰłŰȘÙŠŰ±Ű§ŰŻ هيكله Ű„Ù„Ù‰ Ù…ŰŹŰȘمŰč ŰŹŰŻÙŠŰŻ." @@ -25191,6 +25172,11 @@ msgstr "نوŰč Premium" msgid "Premium until date" msgstr "ŰȘŰ§Ű±ÙŠŰź Ű§Ù†ŰȘÙ‡Ű§ŰĄ Premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ŰŹŰ§Ű±ÙŠ Ű§Ù„ŰȘŰ­Ű¶ÙŠŰ±" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ" msgid "Profile badge" msgstr "ێۧ۱۩ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Ù„Ű§ÙŰȘۧŰȘ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ ميŰČŰ© من {PREMIUM_PRODUCT_NAME}. Ű§Ű­Ű”Ù„ Űčلى {PREMIUM_PRODUCT_NAME} Ù„Ű„Ű¶Ű§ÙŰ© Ù„Ű§ÙŰȘŰ© Ű„Ù„Ù‰ ملفك Ű§Ù„ŰŽŰźŰ”ÙŠ." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Ù„Ű§ÙŰȘۧŰȘ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ ŰșÙŠŰ± مفŰčÙ‘Ù„Ű© Űčلى Ù‡Ű°Ű§ Ű§Ù„Ù…Ű«ÙŠÙ„." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "ŰȘŰȘŰ·Ù„Űš Ù„Ű§ÙŰȘۧŰȘ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "ŰȘŰȘŰ·Ù„Űš Ù„Ű§ÙŰȘۧŰȘ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Ű§Ù„Ű¶ŰșŰ· للŰȘŰ­ŰŻŰ«" msgid "Push-to-talk (limited)" msgstr "Ű§Ù„Ű¶ŰșŰ· للŰȘŰ­ŰŻŰ« (Ù…Ű­ŰŻÙˆŰŻ)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "يŰȘم ŰȘŰŹŰ§Ù‡Ù„ Ű§Ù„Ű¶ŰșŰ· للŰȘŰ­ŰŻŰ« في ÙˆŰ¶Űč Ű§Ù„Ű„ŰŻŰźŰ§Ù„ Ű§Ù„Ù…ŰšŰ§ŰŽŰ±. ŰšŰŻÙ‘Ù„ Ű„Ù„Ù‰ Ű§Ù„Ű”ÙˆŰȘ Ű§Ù„Ù…Ű±ÙƒÙ‘ŰČ ŰŁÙˆ Ű§Ù„Ù…ŰźŰ”Ű” Ù„Ű§ŰłŰȘŰźŰŻŰ§Ù…Ù‡." @@ -26551,8 +26537,8 @@ msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„Ù…Ű±ÙÙ‚" msgid "Remove authenticator app" msgstr "Ű„ŰČŰ§Ù„Ű© ŰȘŰ·ŰšÙŠÙ‚ Ű§Ù„Ù…Ű”Ű§ŰŻÙ‚Ű©" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" @@ -26561,8 +26547,8 @@ msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ©" msgid "Remove background" msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„ŰźÙ„ÙÙŠŰ©" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„Ù„Ű§ÙŰȘŰ©" @@ -26625,10 +26611,10 @@ msgstr "Ű„Ù„Űșۧۥ Ű„ŰšÙ‚Ű§ŰĄ Ű§Ù„Ù†Ű§ÙŰ°Ű© في Ű§Ù„Ù…Ù‚ŰŻÙ…Ű©" msgid "Remove from URL-only GIF favorites" msgstr "Ű„ŰČŰ§Ù„Ű© من Ű”ÙˆŰ± GIF Ű§Ù„Ù…ÙŰ¶Ù„Ű© (ŰšŰ§Ù„Ű±Ű§ŰšŰ· ÙÙ‚Ű·)" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Ű„ŰČŰ§Ù„Ű© Ű§Ù„ŰŁÙŠÙ‚ÙˆÙ†Ű©" @@ -27331,7 +27317,7 @@ msgstr "ŰŁÙŰčÙŠŰŻ Ű§Ù„Ű„Ű±ŰłŰ§Ù„" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Ű„Űčۧۯ۩ ŰȘŰčيين" @@ -28074,7 +28060,7 @@ msgstr "Ű§Ù„Ű±ÙˆÙ…Ű§Ù†ÙŠŰ©" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ŰȘŰŻÙˆÙŠŰ± ۚۧŰȘŰŹŰ§Ù‡ ŰčÙ‚Ű§Ű±Űš Ű§Ù„ŰłŰ§ŰčŰ©" @@ -28153,8 +28139,8 @@ msgstr "Ű§Ù„ŰȘŰŽŰšŰč" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ŰčÙ†Ű§Ű”Ű± Ű§Ù„ŰȘŰ­ÙƒÙ… في Ù…ÙŰ±Ù…ÙÙ‘ŰČ Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„ŰŽŰ§ŰŽŰ©" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Ű§Ù†ŰȘهŰȘ Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„ŰŽŰ§ŰŽŰ©" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Ű„ŰžÙ‡Ű§Ű± ێۧ۱۩ Ű­Ù…Ű±Ű§ŰĄ Űčلى ŰŁÙŠÙ‚ÙˆÙ†Ű© Ű§Ù„ŰȘŰ·ŰšÙŠÙ‚ ŰčÙ†ŰŻ ÙˆŰŹÙˆŰŻ Ű±ŰłŰ§ŰŠÙ„ ŰșÙŠŰ± Ù…Ù‚Ű±ÙˆŰĄŰ©" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Ű„ŰžÙ‡Ű§Ű± لون Ű§Ù„ŰȘمييŰČ ÙÙ‚Ű·ŰŒ مŰč ŰȘŰŹŰ§Ù‡Ù„ ملفك Ű§Ù„ŰŽŰźŰ”ÙŠ Ű§Ù„ŰčŰ§Ù…" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Ű„ŰžÙ‡Ű§Ű± Ű§Ù„Ű±Ù…ÙˆŰČ Ű§Ù„ŰȘŰčŰšÙŠŰ±ÙŠŰ© Ű§Ù„Ù…ŰźŰ”Ű”Ű© في Ű§Ù„Ű„ÙƒÙ…Ű§Ù„ Ű§Ù„ŰȘÙ„Ù‚Ű§ŰŠÙŠ للŰȘŰčŰšÙŠŰ±Ű§ŰȘ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Ű„ŰžÙ‡Ű§Ű± Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ© Ű§Ù„Ű§ÙŰȘŰ±Ű§Ű¶ÙŠŰ©ŰŒ مŰč ŰȘŰŹŰ§Ù‡Ù„ ملفك Ű§Ù„ŰŽŰźŰ”ÙŠ Ű§Ù„ŰčŰ§Ù…" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Ű„ŰžÙ‡Ű§Ű± Ù…Ű€ŰŽŰ± Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ ŰșÙŠŰ± Ű§Ù„Ù…Ù‚Ű±ÙˆŰĄŰ© في Ű§Ù„Ù‚Ù†ÙˆŰ§ŰȘ Ű§Ù„Ù…ÙƒŰȘÙˆÙ…Ű©" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Ű„ŰžÙ‡Ű§Ű± Ű§Ù„Ű”ÙˆŰ±Ű© Ű§Ù„Ű±Ù…ŰČÙŠŰ© لملفك Ű§Ù„ŰŽŰźŰ”ÙŠ Ű§Ù„ŰčŰ§Ù… في Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Ű„ŰžÙ‡Ű§Ű± Ù„Ű§ÙŰȘŰ© ملفك Ű§Ù„ŰŽŰźŰ”ÙŠ Ű§Ù„ŰčŰ§Ù… في Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč" @@ -30720,7 +30706,7 @@ msgstr "ŰȘŰźŰ·ÙŠ" msgid "Skip \"Mark all as read\" confirmation" msgstr "ŰȘŰźŰ·ÙŠ ŰȘŰŁÙƒÙŠŰŻ Â«ÙˆŰ¶Űč ŰčÙ„Ű§Ù…Ű© Űčلى Ű§Ù„ÙƒÙ„ ÙƒÙ…Ù‚Ű±ÙˆŰĄÂ»" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "ŰȘŰźŰ·ÙŠ Ű§Ù„Ű§Ù‚ŰȘ۔ۧ۔" @@ -32346,7 +32332,7 @@ msgstr "Ű§Ù„ŰȘŰšŰŻÙŠÙ„ Ű„Ù„Ù‰ Ű§Ù„ŰȘŰźŰ·ÙŠŰ· Ű§Ù„Ù…Ű±ÙŠŰ­" msgid "Switch to dense layout" msgstr "Ű§Ù„ŰȘŰšŰŻÙŠÙ„ Ű„Ù„Ù‰ Ű§Ù„ŰȘŰźŰ·ÙŠŰ· Ű§Ù„Ù…Ű¶ŰșÙˆŰ·" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Ű§Ù„ŰȘŰšŰŻÙŠÙ„ Ű„Ù„Ù‰ Ű§Ù„Ű„ŰŻŰźŰ§Ù„ Ű§Ù„Ù…ŰšŰ§ŰŽŰ±" @@ -32734,7 +32720,7 @@ msgstr "Ű§Ù„Ù…Ù‡Ű§Ù…" msgid "Teleporting you to another voice region..." msgstr "ŰŹŰ§Ű±Ù نقلك Ű„Ù„Ù‰ Ù…Ù†Ű·Ù‚Ű© Ű”ÙˆŰȘÙŠŰ© ŰŁŰźŰ±Ù‰..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Ù‚Ű§Ù„Űš" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Ù…Ù†Ű­ Ű§Ù„ŰŻÙˆŰ± {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "ŰȘوقف Ù…Ű”ŰŻŰ± Ù…ŰŽŰ§Ű±ÙƒŰ© Ű§Ù„ŰŽŰ§ŰŽŰ© Űčن Ű„Ű±ŰłŰ§Ù„ Ű§Ù„ÙÙŠŰŻÙŠÙˆŰŒ Ù„Ű°Ù„Ùƒ ŰŁÙÙˆÙ‚ÙŰȘ Ù…ŰŽŰ§Ű±ÙƒŰ© ێۧێŰȘك." @@ -33453,6 +33439,11 @@ msgstr "Ù„Ű§ يمكن ۭ۞۱ Ù‡Ű°Ű§ Ű§Ù„Ű­ŰłŰ§Űš." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Ù„Ű§ يمكن Ű§Ù„ŰȘ۱ۧۏŰč Űčن Ù‡Ű°Ű§ Ű§Ù„Ű„ŰŹŰ±Ű§ŰĄ. ŰłÙŠŰȘم Ű­Ű°Ù ŰŹÙ…ÙŠŰč Ű§Ù„ŰšÙŠŰ§Ù†Ű§ŰȘ Ű§Ù„Ù…Ű±ŰȘŰšŰ·Ű©ŰŒ ŰšÙ…Ű§ في Ű°Ù„Ùƒ Ù…ŰłŰȘŰźŰŻÙ… Ű§Ù„ŰšÙˆŰȘی Ù†Ù‡Ű§ŰŠÙŠÙ‹Ű§." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ù‡Ű°Ù‡ Ű§Ù„Ű±ŰłÙˆÙ… Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ© Ű·ÙˆÙŠÙ„Ű© ŰŹŰŻÙ‹Ű§ ŰŁÙˆ ÙƒŰšÙŠŰ±Ű© ŰŹŰŻÙ‹Ű§ ŰšŰ­ÙŠŰ« Ù„Ű§ يمكن Ù‚Ű”Ù‡Ű§. ۏ۱ۚ Ù…Ù„ÙÙ‹Ű§ ŰŁÙ‚Ű”Ű± ŰŁÙˆ ŰŁŰ”Űș۱." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ù‡Ű°Ű§ Ű§Ù„ŰšÙˆŰȘ Ù„ÙŠŰł ŰčŰ§Ù…Ù‹Ű§ ÙˆÙ„Ű§ يمكن Ù„Ù„Ù…ŰłŰȘŰźŰŻÙ…ÙŠÙ† msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "ÙŠŰ·Ù„Űš Ù‡Ű°Ű§ Ű§Ù„ŰšÙˆŰȘ Ű„Ű°Ù† Ű§Ù„Ù…ŰłŰ€ÙˆÙ„. Ù„Ű§ ŰȘÙ…Ù†Ű­Ù‡ Ù‡Ű°Ű§ Ű§Ù„Ű„Ű°Ù† Ű„Ù„Ű§ ۄ۰ۧ كنŰȘ ŰȘŰ«Ù‚ ŰšŰ§Ù„Ù…Ű·ÙˆŰ± ŰȘÙ…Ű§Ù…Ù‹Ű§. Ű§Ű·Ù„Űš من Ű§Ù„Ù…Ű·ÙˆŰ± Ű·Ù„Űš ŰŁŰ°ÙˆÙ†Ű§ŰȘ ŰŁÙ‚Ù„ ŰšŰŻÙ„Ù‹Ű§ من Ű°Ù„Ùƒ. ŰŁŰșلق Ù‡Ű°Ù‡ Ű§Ù„Ű”ÙŰ­Ű© ۄ۰ۧ لم ŰȘكن مŰȘŰŁÙƒŰŻÙ‹Ű§." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ù„Ű§ يمكن Ù„Ù‡Ű°Ű§ Ű§Ù„Ù…ŰȘŰ”ÙŰ­ Ù‚Ű” Ù…Ù„ÙŰ§ŰȘ {avifFormatLabel} Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ©. قم ŰšŰȘŰ­Ù…ÙŠÙ„ ملف GIF ŰŁÙˆ WebP ŰšŰŻÙ„Ű§Ù‹ من Ű°Ù„Ùƒ." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "ÙˆŰ­ŰŻŰ© ŰȘŰ­ÙƒÙ… Ű§Ù„Ù…ŰȘŰ”ÙŰ­ Ù‡Ű°Ù‡ ۣۯۧ۩ Ù„Ù„Ù…Ű·ÙˆŰ±ÙŠÙ†." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "مŰȘŰ”ÙŰ­Ùƒ Ù‡Ű°Ű§ يŰčŰ·Ù„ WebAssemblyی Ù„Ű°Ű§ Ù„Ű§ يمكن Ù‚Ű” Ű§Ù„Ű”ÙˆŰ± Ű§Ù„Ù…ŰȘŰ­Ű±ÙƒŰ©." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ù‡Ű°Ù‡ Ű§Ù„Ù…ŰŹÙ…ÙˆŰčŰ© ممŰȘÙ„ŰŠŰ©. ŰŁŰČل ŰŽŰźŰ”Ù‹Ű§ Ù‚ŰšÙ„ Ű„Ű¶Ű§Ù msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ű§Ù†ŰȘهŰȘ Ű”Ù„Ű§Ű­ÙŠŰ© Ű±Ù…ŰČ Ű§Ù„ŰȘŰłÙ„ÙŠÙ… Ù‡Ű°Ű§. ŰŁÙ†ŰŽŰŠ Ű±Ù…ŰČÙ‹Ű§ ŰŹŰŻÙŠŰŻÙ‹Ű§ للمŰȘۧۚŰčŰ©." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "لم يمكن Ù‚Ű±Ű§ŰĄŰ© Ù‡Ű°Ù‡ Ű§Ù„Ű”ÙˆŰ±Ű©. Ù‚ŰŻ ŰȘكون ŰȘŰ§Ù„ÙŰ©." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "ŰȘŰ­Ù…ÙŠÙ„" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "ŰȘŰ­Ù…ÙŠÙ„ Ű”ÙˆŰ±Ű© Ű±Ù…ŰČÙŠŰ© Ù…ŰźŰ”Ű”Ű© Ù„Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "ŰȘŰ­Ù…ÙŠÙ„ Ù„Ű§ÙŰȘŰ© Ù…ŰźŰ”Ű”Ű© Ù„Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč" @@ -36155,10 +36163,10 @@ msgstr "ŰȘŰ­Ù…ÙŠÙ„ Ű§Ù„Ù…Ù„ÙŰ§ŰȘ ÙˆŰ§Ù„ÙˆŰłŰ§ŰŠŰ· في Ű§Ù„Ű±ŰłŰ§ŰŠÙ„." msgid "Upload files and media in this channel." msgstr "ŰȘŰ­Ù…ÙŠÙ„ Ű§Ù„Ù…Ù„ÙŰ§ŰȘ ÙˆŰ§Ù„ÙˆŰłŰ§ŰŠŰ· في Ù‡Ű°Ù‡ Ű§Ù„Ù‚Ù†Ű§Ű©." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "ŰȘŰ­Ù…ÙŠÙ„ ŰŁÙŠÙ‚ÙˆÙ†Ű©" @@ -36401,8 +36409,8 @@ msgstr "ۧ۳ŰȘŰźŰŻŰ§Ù… ŰłÙ…Ű© Ű§Ù„ÙŰ­Ù… (ۣ۳۷ۭ ŰłÙˆŰŻŰ§ŰĄ Ű­Ű§Ù„ÙƒŰ©)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "ۧ۳ŰȘŰźŰŻŰ§Ù… Ű”ÙˆŰ±Ű© Ù…ŰźŰ”Ű”Ű©" @@ -36462,8 +36470,8 @@ msgstr "ۧ۳ŰȘŰźŰŻÙ… Ű§Ù„ÙÙ„Ű§ŰȘ۱ ŰŁÙˆ ŰŁŰŻŰźÙ„ ÙƒÙ„Ù…Ű§ŰȘ مفŰȘŰ§Ű­ÙŠŰ© لل #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "ۧ۳ŰȘŰźŰŻŰ§Ù… Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠ Ű§Ù„ŰčŰ§Ù…" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Ű§Ù„Ù…ŰŽŰ§Ű±ÙƒÙˆÙ† في Ű§Ù„Ù…ÙƒŰ§Ù„Ù…Ű© Ű§Ù„Ű”ÙˆŰȘÙŠŰ©" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "مŰčŰ§Ù„ŰŹŰ© Ű§Ù„Ű”ÙˆŰȘ" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ÙˆÙŠŰłÙƒÙˆÙ†ŰłÙ†" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "مŰč {PREMIUM_PRODUCT_NAME}ی يمكنك ۧ۳ŰȘŰźŰŻŰ§Ù… Ű”ÙˆŰ± Ű±Ù…ŰČÙŠŰ© مŰȘŰ­Ű±ÙƒŰ© ({ANIMATED_AVATAR_FORMATS}) ÙˆÙ„Ű§ÙŰȘۧŰȘ Ű§Ù„Ù…Ù„Ù Ű§Ù„ŰŽŰźŰ”ÙŠŰŒ وŰȘŰźŰ”ÙŠŰ” ŰčÙ„Ű§Ù…ŰȘÙƒŰŒ وفŰȘŰ­ Ű§Ù„ÙƒŰ«ÙŠŰ± من مŰČŰ§ÙŠŰ§ {PREMIUM_PRODUCT_NAME} Ű§Ù„ŰŁŰźŰ±Ù‰." @@ -39334,8 +39342,8 @@ msgstr "ŰŁÙ†ŰȘ ۭۚۧۏ۩ Ű„Ù„Ù‰ Ű„Ű°Ù† \"{permissionLabel}\" Ù„Ű§ŰłŰȘŰźŰŻŰ§Ù… msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "ŰŁÙ†ŰȘ ۭۚۧۏ۩ Ű„Ù„Ù‰ Ű„Ű°Ù† \"{permissionLabel}\" Ù„Ű§ŰłŰȘŰźŰŻŰ§Ù… Ű§Ù„Ù…Ù„Ű”Ù‚Ű§ŰȘ من Ű§Ù„Ù…ŰŹŰȘمŰčۧŰȘ Ű§Ù„ŰŁŰźŰ±Ù‰ Ù‡Ù†Ű§." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ÙŠŰŹŰš Űčليك Ű§Ù„Ù…Ű·Ű§Ù„ŰšŰ© ŰšŰ­ŰłŰ§ŰšÙƒ Ù‚ŰšÙ„ ŰŁÙ† ŰȘŰȘمكن من Ű„Ù†ŰŽŰ§ŰĄ Ù…ŰŹŰȘمŰč." @@ -39356,8 +39364,8 @@ msgstr "ÙŠŰŹŰš Ű§Ù„Ù…Ű·Ű§Ù„ŰšŰ© ŰšŰ­ŰłŰ§ŰšÙƒ Ù„Ű„Ű±ŰłŰ§Ù„ Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ في ه msgid "You need to verify a phone number to send messages in this community." msgstr "ÙŠŰŹŰš Űčليك Ű§Ù„ŰȘŰ­Ù‚Ù‚ من Ű±Ù‚Ù… Ű§Ù„Ù‡Ű§ŰȘف Ù„Ű„Ű±ŰłŰ§Ù„ Ű§Ù„Ű±ŰłŰ§ŰŠÙ„ في Ù‡Ű°Ű§ Ű§Ù„Ù…ŰŹŰȘمŰč." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ÙŠŰŹŰš Űčليك Ű§Ù„ŰȘŰ­Ù‚Ù‚ من ŰčÙ†ÙˆŰ§Ù† ŰšŰ±ÙŠŰŻÙƒ Ű§Ù„Ű„Ù„ÙƒŰȘŰ±ÙˆÙ†ÙŠ Ù‚ŰšÙ„ ŰŁÙ† ŰȘŰȘمكن من Ű„Ù†ŰŽŰ§ŰĄ Ù…ŰŹŰȘمŰč." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "ŰȘŰ­ŰȘۧۏ ŰŹÙˆŰŻŰ© Ű§Ù„ŰŽŰ§ŰŽŰ© Ű§Ù„Ù…Ű­ÙÙˆŰžŰ© Ù„ŰŻÙŠÙƒ ŰšŰŻÙ‚Ű© {savedResolution} ŰšÙ…ŰčŰŻÙ„ ۄ۷ۧ۱ۧŰȘ {savedFrameRate} Ű„Ű·Ű§Ű±Ù‹Ű§ في Ű§Ù„Ű«Ű§Ù†ÙŠŰ© Ű„Ù„Ù‰ {premiumProductName}ی Ù„Ű°Ű§ ŰȘŰłŰȘŰźŰŻÙ… Ű§Ù„Ù…ŰŽŰ§Ű±ÙƒŰ§ŰȘ ŰŻÙ‚Ű© {resolution} ŰšÙ…ŰčŰŻÙ„ ۄ۷ۧ۱ۧŰȘ {frameRate} Ű„Ű·Ű§Ű±Ù‹Ű§ في Ű§Ù„Ű«Ű§Ù†ÙŠŰ©." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ŰȘŰčŰ°Ù‘Ű± Ù†ŰŽŰ± Ù…ŰŽŰ§Ű±ÙƒŰ© ێۧێŰȘك ۚۧ۳ŰȘŰźŰŻŰ§Ù… ŰšŰ±Ù†Ű§Ù…ŰŹ ŰȘŰ±Ù…ÙŠŰČ ÙÙŠŰŻÙŠÙˆ مŰȘÙˆŰ§ÙÙ‚ŰŒ Ù„Ű°Ű§ ŰȘم Ű„ÙŠÙ‚Ű§ÙÙ‡Ű§. Ű­Ű§ÙˆÙ„ Ű§Ù„Ù…ŰŽŰ§Ű±ÙƒŰ© Ù…Ű±Ű© ŰŁŰźŰ±Ù‰." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "ŰȘم ŰȘŰčيين ŰčÙ†ÙˆŰ§Ù† URL Ű§Ù„Ù…ŰźŰ”Ű” Ű„Ù„Ù‰ {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "ŰȘوقف Ù…ÙŰ±Ù…Ù‘ŰČ Ű§Ù„ÙÙŠŰŻÙŠÙˆ Ű§Ù„ŰźŰ§Ű” ŰšÙƒ Űčن ŰȘŰ±Ù…ÙŠŰČ Ű§Ù„Ű„Ű·Ű§Ű±Ű§ŰȘی Ù„Ű°Ű§ ŰȘم Ű„ÙŠÙ‚Ű§Ù Ù…ŰŽŰ§Ű±ÙƒŰ© ێۧێŰȘك. Ű­Ű§ÙˆÙ„ Ű§Ù„Ù…ŰŽŰ§Ű±ÙƒŰ© Ù…Ű±Ű© ŰŁŰźŰ±Ù‰." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "مفŰȘۭۧ YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "ŰȘÙƒŰšÙŠŰ±/ŰȘŰ”ŰșÙŠŰ±" diff --git a/fluxer_app/src/features/i18n/locales/auto-i18n-reviewed-unchanged.json b/fluxer_app/src/features/i18n/locales/auto-i18n-reviewed-unchanged.json index 715a625df..931ea20c9 100644 --- a/fluxer_app/src/features/i18n/locales/auto-i18n-reviewed-unchanged.json +++ b/fluxer_app/src/features/i18n/locales/auto-i18n-reviewed-unchanged.json @@ -1761,6 +1761,12 @@ { "msgid": "Community overrides" }, + { + "msgid": "Compressing" + }, + { + "msgid": "Compressing {percent}%" + }, { "msgid": "Connect a camera and try again." }, @@ -1803,6 +1809,9 @@ { "msgid": "Create the administrator account" }, + { + "msgid": "Cropping {percent}%" + }, { "msgid": "Custom emoji {emojiName} from a community" }, @@ -2277,6 +2286,9 @@ { "msgid": "Premium model" }, + { + "msgid": "Preparing" + }, { "msgid": "Prevent <0>{targetUserTag} from sending messages, reacting, and connecting to voice channels for the specified duration." }, @@ -2982,12 +2994,27 @@ { "msgid": "These options change how people use the instance. Some can only be chosen during setup." }, + { + "msgid": "This animation is too long or too large to crop. Try a shorter or smaller file." + }, + { + "msgid": "This browser can't crop animated {AVIF_FORMAT_LABEL} files. Upload a GIF or WebP instead." + }, + { + "msgid": "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." + }, + { + "msgid": "This browser has WebAssembly turned off, so animated images can't be cropped." + }, { "msgid": "This device could not keep up with {targetResolution} at {targetFrameRate} FPS last time, so your stream started at {resolution} at {frameRate} FPS." }, { "msgid": "This emoji is from" }, + { + "msgid": "This image couldn't be read. It may be damaged." + }, { "msgid": "This instance currently allows screen share up to 720p at 30 FPS." }, diff --git a/fluxer_app/src/features/i18n/locales/bg/messages.po b/fluxer_app/src/features/i18n/locales/bg/messages.po index b1a1324a2..f602b9704 100644 --- a/fluxer_app/src/features/i18n/locales/bg/messages.po +++ b/fluxer_app/src/features/i18n/locales/bg/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, ĐŸŃ‡Đ°ĐșĐČаĐčтД сĐșĐŸŃ€ĐŸ" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Đ Đ°Đ·ĐŒĐ”Ń€ĐžŃ‚Đ” ĐœĐ° ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”Ń‚ĐŸ за {label} ĐœĐ” ŃŃŠĐŸŃ‚ĐČДтстĐČат ĐœĐ° Ń‚ĐŸĐ·Đž Đ”Đ»Đ”ĐŒĐ”ĐœŃ‚. Đ˜Đ·Đ±Đ”Ń€Đž ĐŽŃ€ŃƒĐłĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” ОлО Đșачо ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”, ĐșĐŸĐ”Ń‚ĐŸ ĐŒĐŸĐ¶Đ”Ńˆ Ўа ĐžĐ·Ń€Đ”Đ¶Đ”Ńˆ." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "ЀаĐčлът за {label} Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒ. Đ˜Đ·Đ±Đ”Ń€Đž фаĐčĐ», ĐżĐŸ-ĐŒĐ°Đ»ŃŠĐș ĐŸŃ‚ {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”Ń‚ĐŸ за {label} ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐŸ. Đ˜Đ·ĐżĐŸĐ»Đ·ĐČаĐč ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "ĐĄĐżĐŸĐŽĐ”Đ»ŃĐœĐ” ĐœĐ° аĐșтоĐČĐœĐŸŃŃ‚" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Праг ĐœĐ° аĐșтоĐČĐœĐŸŃŃ‚" @@ -3566,11 +3561,11 @@ msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐ°ĐČĐ°ĐœĐ” ĐœĐ° {everyoneMention} Đž {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐž ĐœĐ° {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃŠĐż ĐŽĐŸ ĐșĐ°ĐŒĐ”Ń€Đ°Ń‚Đ° то ĐČ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐž ĐœĐ° {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃŠĐż ĐŽĐŸ ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœĐ° то ĐČ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐž ĐœĐ° {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃŠĐż ĐŽĐŸ ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœĐ° то. ĐŸŃ€ĐŸĐČДрО Đ°ĐŽŃ€Đ”ŃĐœĐ°Ń‚Đ° Đ»Đ”ĐœŃ‚Đ° ОлО ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșОтД ĐœĐ° Đ±Ń€Đ°ŃƒĐ·ŃŠŃ€Đ° сО." @@ -3673,7 +3668,7 @@ msgstr "ĐŸĐŸĐ·ĐČĐŸĐ»ŃĐČа ĐœĐ° Ń‡Đ»Đ”ĐœĐŸĐČДтД бДз Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐ”Ń‚ msgid "Allow mentions for this role" msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐ°ĐČĐ°ĐœĐ” ĐœĐ° ŃĐżĐŸĐŒĐ”ĐœĐ°ĐČĐ°ĐœĐžŃ за тазО Ń€ĐŸĐ»Ń" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐž ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœĐ°" @@ -3942,25 +3937,21 @@ msgstr "Đž ĐŸŃ‰Đ” {remainingCount}" msgid "Animate on interaction" msgstr "ĐĐœĐžĐŒĐžŃ€Đ°Đč про ĐČĐ·Đ°ĐžĐŒĐŸĐŽĐ”ĐčстĐČОД" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” фаĐčĐ»ĐŸĐČĐ” {AVIF_FORMAT_LABEL} ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°Ń‚. Качо ŃŃ‚Đ°Ń‚ĐžŃ‡Đ”Đœ фаĐčĐ» {AVIF_FORMAT_LABEL}." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃŃ‚ Ń„ĐŸŃ€ĐŒĐ°Ń‚ {avifFormatLabel} ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” аĐČатаро ({ANIMATED_AVATAR_FORMATS}) са ĐŽĐŸŃŃ‚ŃŠĐżĐœĐž ŃĐ°ĐŒĐŸ за Đ°Đ±ĐŸĐœĐ°Ń‚Đž ĐœĐ° {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” аĐČатаро ({ANIMATED_AVATAR_FORMATS}) ĐœĐ” са ĐœĐ°Đ»ĐžŃ‡ĐœĐž ĐČ Ń‚Đ°Đ·Đž ĐžĐœŃŃ‚Đ°ĐœŃ†ĐžŃ. Качо ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” аĐČатаро ({animatedAvatarFormats}) ОзОсĐșĐČат {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐž аĐČатаро Đž Đ±Đ°ĐœĐ”Ń€Đž ĐœĐ° ĐżŃ€ĐŸŃ„ĐžĐ»Đž" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” аĐČатаро ĐœĐ” са ĐœĐ°Đ»ĐžŃ‡ĐœĐž" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” аĐČатаро ОзОсĐșĐČат {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ĐœĐ° Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ĐĐœĐžĐŒĐžŃ€Đ°ĐœĐžŃ‚Đ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°Ń‚ за Ń‚ĐŸĐ·Đž Đ”Đ»Đ”ĐŒĐ”ĐœŃ‚." @@ -4947,7 +4938,7 @@ msgstr "АĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡ĐœĐŸ Ń€Đ°Đ·ĐżĐŸĐ·ĐœĐ°ĐČĐ°ĐœĐ” ĐœĐ° ДзОĐș" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "АĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡ĐœĐŸ заЎаĐČĐ°ĐœĐ” ĐœĐ° праг за аĐșтоĐČĐœĐŸŃŃ‚" @@ -5127,15 +5118,15 @@ msgstr "ĐĐ°Đ»ĐžŃ‡ĐœĐŸ ĐČ ĐœĐ°ŃŃ‚ĐŸĐ»ĐœĐŸŃ‚ĐŸ ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ”." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "АĐČатар" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčлът ĐœĐ° аĐČатара Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒ. Đ˜Đ·Đ±Đ”Ń€Đž фаĐčĐ», ĐżĐŸ-ĐŒĐ°Đ»ŃŠĐș ĐŸŃ‚ {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "АĐČатарът Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒ. Đ˜Đ·Đ±Đ”Ń€Đž таĐșъĐČ ĐżĐŸĐŽ {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Đ˜Đ·Đ±ĐŸŃ€ ĐœĐ° Ń€Đ”Đ¶ĐžĐŒ за аĐČатар" @@ -5187,11 +5178,11 @@ msgstr "В ĐŒĐŸĐŒĐ”ĐœŃ‚Đ° ĐŒĐ” ĐœŃĐŒĐ°" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Đ—Đ°Đ±Ń€Đ°ĐœĐ”ĐœĐž ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»Đž" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Đ‘Đ°ĐœĐ”Ń€" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčлът ĐœĐ° Đ±Đ°ĐœĐ”Ń€Đ° Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒ. Đ˜Đ·Đ±Đ”Ń€Đž фаĐčĐ», ĐżĐŸ-ĐŒĐ°Đ»ŃŠĐș ĐŸŃ‚ {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Đ˜Đ·Đ±ĐŸŃ€ ĐœĐ° Ń€Đ”Đ¶ĐžĐŒ ĐœĐ° Đ±Đ°ĐœĐ”Ń€" @@ -6107,8 +6098,8 @@ msgstr "Купо ĐżĐŸĐŽĐ°Ń€ŃŠĐș {premiumProductName} ĐŸŃ‚ разЎДла {premiu msgid "Buy gift" msgstr "Купо ĐżĐŸĐŽĐ°Ń€ŃŠĐș" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Със съзЎаĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ĐŸĐ±Ń‰ĐœĐŸŃŃ‚ сД ŃŃŠĐłĐ»Đ°ŃŃĐČаш Ўа спазĐČаш Đž ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°Ńˆ <0>ĐœĐ°ŃĐŸĐșОтД ĐœĐ° ĐŸĐ±Ń‰ĐœĐŸŃŃ‚Ń‚Đ° ĐœĐ° {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "йуĐș ĐœĐ” ĐŒĐŸĐ¶Đ”Ńˆ Ўа ĐșачĐČаш фаĐčĐ»ĐŸĐČĐ”" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ĐŠĐ”ĐœŃ‚Ń€ĐžŃ€Đ°ĐœĐŸ" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ĐĄĐŒŃĐœĐ° ĐœĐ° аĐČатара" @@ -6627,9 +6618,9 @@ msgstr "ĐĄĐŒŃĐœĐ° ĐœĐ° Ń„ĐŸĐœĐ°" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "ĐĄĐŒŃĐœĐ° ĐœĐ° Đ±Đ°ĐœĐ”Ń€Đ°" @@ -6668,13 +6659,13 @@ msgstr "ĐŸŃ€ĐŸĐŒŃĐœĐ° ĐœĐ° пряĐșĐŸŃ€ ĐČ ĐłŃ€ŃƒĐżĐ°Ń‚Đ°" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "ĐĄĐŒŃĐœĐ° ĐœĐ° ĐžĐșĐŸĐœĐ°" @@ -7669,8 +7660,8 @@ msgstr "Đ’Đ·Đ”ĐŒĐž ĐżĐŸĐŽĐ°Ń€ŃŠĐș" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "ЗаяĐČĐž аĐșĐ°ŃƒĐœŃ‚Đ° сО" @@ -8518,8 +8509,8 @@ msgstr "ĐžĐ±Ń‰ĐœĐŸŃŃ‚Ń‚Đ° ŃƒĐ»Đ”ŃĐœŃĐČа ĐłŃ€ŃƒĐżĐŸĐČОтД атаĐșĐž ОлО msgid "Community filter" msgstr "ЀОлтър за ĐŸĐ±Ń‰ĐœĐŸŃŃ‚Đž" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ИĐșĐŸĐœĐ° ĐœĐ° ĐŸĐ±Ń‰ĐœĐŸŃŃ‚Ń‚Đ°" @@ -8763,6 +8754,11 @@ msgstr "Đ‘ŃƒŃ‚ĐŸĐœĐž ĐČ ĐżĐŸĐ»Đ”Ń‚ĐŸ за ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžĐ”" msgid "Composer focus" msgstr "Đ€ĐŸĐșус ĐœĐ° тДĐșŃŃ‚ĐŸĐČĐŸŃ‚ĐŸ ĐżĐŸĐ»Đ”" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "ĐšĐŸĐŒĐżŃ€Đ”ŃĐžŃ€Đ°ĐœĐ”" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ĐĄĐČържО ĐșĐ°ĐŒĐ”Ń€Đ° ОлО ĐČĐžŃ€Ń‚ŃƒĐ°Đ»ĐœĐŸ ŃƒŃŃ‚Ń€ĐŸĐčстĐČĐŸ msgid "Connect a display, then try again." msgstr "ĐĄĐČържО ЎОсплДĐč Đž ĐŸĐżĐžŃ‚Đ°Đč ĐŸŃ‚ĐœĐŸĐČĐŸ." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ĐĄĐČържО ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ Đž ĐŸĐżĐžŃ‚Đ°Đč ĐŸŃ‚ĐœĐŸĐČĐŸ." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "СтоĐșДрът ĐœĐ” ĐŒĐŸĐ¶Đ° Ўа бъЎД ŃŃŠĐ·ĐŽĐ°ĐŽĐ”Đœ" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”Ń‚ĐŸ ĐœĐ” ĐŒĐŸĐ¶Đ° Ўа бъЎД ĐžĐ·Ń€ŃĐ·Đ°ĐœĐŸ" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ĐĄĐżĐŸĐŽĐ”Đ»ŃĐœĐ”Ń‚ĐŸ ĐœĐ° ĐłĐ»Đ°ŃĐŸĐČа аĐșтоĐČĐœĐŸŃŃ‚ ĐœĐ” ĐŒĐŸĐ¶Đ° Ўа бъЎД аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·ĐžŃ€Đ°ĐœĐŸ ĐČ ĐŒĐŸĐŒĐ”ĐœŃ‚Đ°" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ĐĐ”ŃƒŃĐżĐ”ŃˆĐœĐŸ ĐșачĐČĐ°ĐœĐ” ĐœĐ° аĐČатара" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ĐĐ”ŃƒŃĐżĐ”ŃˆĐœĐŸ ĐșачĐČĐ°ĐœĐ” ĐœĐ° Đ±Đ°ĐœĐ”Ń€" @@ -10230,7 +10226,7 @@ msgstr "ХъзЎаĐČĐ°ĐœĐ” Đž ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐ”" msgid "Create a community" msgstr "ХъзЎаĐČĐ°ĐœĐ” ĐœĐ° ĐŸĐ±Ń‰ĐœĐŸŃŃ‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ХъзЎаĐč ĐŸĐ±Ń‰ĐœĐŸŃŃ‚, ĐČ ĐșĐŸŃŃ‚ĐŸ то Đž ĐżŃ€ĐžŃŃ‚Đ”Đ»ĐžŃ‚Đ” то Ўа сО чатОтД." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ” ĐœĐ° Ń„ĐŸĐœĐ° ĐœĐ° ĐżĐŸĐșĐ°ĐœĐ°Ń‚Đ°" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ĐŸŃ€Đ”ĐłĐ»Đ”ĐŽ ĐœĐ° ĐžĐ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ" @@ -10500,30 +10496,15 @@ msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ” ĐœĐ° Đ±Đ°ĐœĐ”Ń€ ĐœĐ° ĐżŃ€ĐŸŃ„ĐžĐ»" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Đ˜Đ·Ń€ŃĐ·Đ°ĐœĐŸŃ‚ĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” Đ” тĐČърЎД ĐłĐŸĐ»ŃĐŒĐŸ. Đ˜Đ·Đ±Đ”Ń€Đž ĐżĐŸ-ĐŒĐ°Đ»Đșа ĐŸĐ±Đ»Đ°ŃŃ‚ ОлО ĐżĐŸ-ĐŒĐ°Đ»ŃŠĐș фаĐčĐ» (ĐŒĐ°Đșс. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž {formatLabel} фаĐčĐ»ĐŸĐČĐ” ĐČсД ĐŸŃ‰Đ” ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°. ЩД бъЎД ĐžĐ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐŸ ĐŸŃ€ĐžĐłĐžĐœĐ°Đ»ĐœĐŸŃ‚ĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž {formatLabel} фаĐčĐ»ĐŸĐČĐ” ĐČсД ĐŸŃ‰Đ” ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°. ЩД бъЎД ĐžĐ·ĐżĐŸĐ»Đ·ĐČĐ°Đœ ĐŸŃ€ĐžĐłĐžĐœĐ°Đ»ĐœĐžŃŃ‚ фаĐčĐ»." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž фаĐčĐ»ĐŸĐČĐ” ĐČсД ĐŸŃ‰Đ” ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°. ЩД бъЎД ĐžĐ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐŸ ĐŸŃ€ĐžĐłĐžĐœĐ°Đ»ĐœĐŸŃ‚ĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Đ˜Đ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž фаĐčĐ»ĐŸĐČĐ” ĐČсД ĐŸŃ‰Đ” ĐœĐ” сД ĐżĐŸĐŽĐŽŃŠŃ€Đ¶Đ°. ЩД бъЎД ĐžĐ·ĐżĐŸĐ»Đ·ĐČĐ°Đœ ĐŸŃ€ĐžĐłĐžĐœĐ°Đ»ĐœĐžŃŃ‚ фаĐčĐ»." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "ĐžĐ±Ń€Đ°Đ±ĐŸŃ‚ĐČĐ°ĐœĐ” ĐœĐ° {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ĐŃĐŒĐ°Ńˆ аĐșĐ°ŃƒĐœŃ‚?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ĐĐ” ĐżĐŸĐșазĐČаĐč" @@ -16560,8 +16541,8 @@ msgstr "АĐČатарОтД ĐœĐ° ĐłŃ€ŃƒĐżĐŸĐČОтД DM ĐžĐ·ĐżĐŸĐ»Đ·ĐČат същ msgid "Group DMs" msgstr "Đ“Ń€ŃƒĐżĐŸĐČĐž DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ИĐșĐŸĐœĐ° ĐœĐ° групата" @@ -16624,8 +16605,8 @@ msgstr "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž ĐœĐ° групата" msgid "Group typing states" msgstr "ĐĄŃŠŃŃ‚ĐŸŃĐœĐžŃ ĐœĐ° ĐżĐžŃĐ°ĐœĐ” ĐČ ĐłŃ€ŃƒĐżĐ°" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Групата Đ” аĐșŃ‚ŃƒĐ°Đ»ĐžĐ·ĐžŃ€Đ°ĐœĐ°" @@ -16803,7 +16784,7 @@ msgstr "ХърцД" msgid "Hebrew" msgstr "ИĐČрот" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Đ’ĐžŃĐŸŃ‡ĐžĐœĐ°" @@ -17510,7 +17491,7 @@ msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”Ń‚ĐŸ Đ” ĐșĐŸĐżĐžŃ€Đ°ĐœĐŸ ĐČ ĐșĐ»ĐžĐżĐ±ĐŸŃ€ĐŽĐ°" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”Ń‚ĐŸ ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД ĐžĐ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐŸ" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Đ’ŃŠĐœŃˆĐ”Đœ ĐČОЎ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ИзглДжЎа, чД ĐžĐ·ĐżĐŸĐ»Đ·ĐČаш {0}. ĐĐ°ŃĐ»Đ°ĐłĐČĐ°ĐœĐ”Ń‚ĐŸ ĐœĐ° ĐŸĐ±Ń€Đ°Đ±ĐŸŃ‚Đșата ĐœĐ° {PRODUCT_NAME} ĐŸŃ‚ĐłĐŸŃ€Đ” ĐŒĐŸĐ¶Đ” Ўа ĐżŃ€ĐžŃ‡ĐžĐœĐž ĐżŃƒĐ»ŃĐžŃ€Đ°ĐœĐ” ОлО ОзĐșроĐČяĐČĐ°ĐœĐ” ĐœĐ° Đ·ĐČуĐșа. ДОрДĐșŃ‚ĐœĐžŃŃ‚ ĐČŃ…ĐŸĐŽ прДЎаĐČа Đ·ĐČуĐșа то ĐœĐ”ĐżŃ€ĐŸĐŒĐ”ĐœĐ”Đœ." @@ -22577,7 +22558,7 @@ msgstr "ĐŃĐŒĐ° ĐœĐ°ĐŒĐ”Ń€Đ”ĐœĐž съĐČĐżĐ°ĐŽĐ”ĐœĐžŃ" msgid "No mentions yet" msgstr "ВсД ĐŸŃ‰Đ” ĐœŃĐŒĐ° ŃĐżĐŸĐŒĐ”ĐœĐ°ĐČĐ°ĐœĐžŃ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "ĐĐ” Đ” ĐœĐ°ĐŒĐ”Ń€Đ”Đœ ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ" @@ -23806,7 +23787,7 @@ msgstr "ОтĐČĐ°Ń€ŃĐœĐ” ĐœĐ° ŃĐžŃŃ‚Đ”ĐŒĐœĐŸ DM" msgid "Open system picker" msgstr "ОтĐČĐ°Ń€ŃĐœĐ” ĐœĐ° ŃĐžŃŃ‚Đ”ĐŒĐœĐžŃ ĐžĐœŃŃ‚Ń€ŃƒĐŒĐ”ĐœŃ‚ за ĐžĐ·Đ±ĐŸŃ€" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "ОтĐČĐ°Ń€ŃĐœĐ” ĐœĐ° JSON ĐœĐ° ŃˆĐ°Đ±Đ»ĐŸĐœĐ°" @@ -23820,7 +23801,7 @@ msgstr "ОтĐČĐ°Ń€ŃĐœĐ” ĐœĐ° ĐŽĐžĐ°Đ»ĐŸĐłĐŸĐČоя ĐżŃ€ĐŸĐ·ĐŸŃ€Đ”Ń† за заб msgid "Open the context menu" msgstr "ОтĐČĐ°Ń€ŃĐœĐ” ĐœĐ° ĐșĐŸĐœŃ‚Đ”ĐșŃŃ‚ĐœĐŸŃ‚ĐŸ ĐŒĐ”ĐœŃŽ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "ОтĐČĐŸŃ€Đž Đ»ĐžĐœĐșа ĐżĐŸ-ĐŽĐŸĐ»Ńƒ ĐČ Đ±Ń€Đ°ŃƒĐ·ŃŠŃ€Đ° сО, слДЎ ĐșĐŸĐ”Ń‚ĐŸ ĐșĐŸĐżĐžŃ€Đ°Đč Ń†Đ”Đ»ĐžŃ JSON ĐŸŃ‚ĐłĐŸĐČĐŸŃ€ Đž ĐłĐŸ ĐżĐŸŃŃ‚Đ°ĐČĐž ĐČ ĐżĐŸĐ»Đ”Ń‚ĐŸ." @@ -24331,7 +24312,7 @@ msgstr "ĐŸĐŸŃĐ»Đ”ĐŽĐœĐžŃ‚Đ” 7 ĐŽĐœĐž" msgid "Paste" msgstr "ĐŸĐŸŃŃ‚Đ°ĐČĐž" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "ĐŸĐŸŃŃ‚Đ°ĐČĐž URL аЎрДс ĐœĐ° ŃˆĐ°Đ±Đ»ĐŸĐœ ĐŸŃ‚ {theOtherPlatform}, за Ўа ĐžĐŒĐżĐŸŃ€Ń‚ĐžŃ€Đ°Ńˆ струĐșтурата ĐŒŃƒ ĐČ ĐœĐŸĐČа ĐŸĐ±Ń‰ĐœĐŸŃŃ‚." @@ -25191,6 +25172,11 @@ msgstr "ĐŸŃ€Đ”ĐŒĐžŃƒĐŒ топ" msgid "Premium until date" msgstr "ĐŸŃ€Đ”ĐŒĐžŃƒĐŒ ĐŽĐŸ Юата" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ĐŸĐŸĐŽĐłĐŸŃ‚ĐČŃĐœĐ”" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»" msgid "Profile badge" msgstr "Đ—ĐœĐ°Ń‡Đșа ĐœĐ° ĐżŃ€ĐŸŃ„ĐžĐ»" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»ĐœĐžŃ‚Đ” Đ±Đ°ĐœĐ”Ń€Đž са Ń„ŃƒĐœĐșцоя ĐœĐ° {PREMIUM_PRODUCT_NAME}. Đ’Đ·Đ”ĐŒĐž {PREMIUM_PRODUCT_NAME}, за Ўа ĐŽĐŸĐ±Đ°ĐČОш Đ±Đ°ĐœĐ”Ń€ ĐșŃŠĐŒ ĐżŃ€ĐŸŃ„ĐžĐ»Đ° сО." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»ĐœĐžŃ‚Đ” Đ±Đ°ĐœĐ”Ń€Đž ĐœĐ” са аĐșтоĐČĐžŃ€Đ°ĐœĐž ĐČ Ń‚Đ°Đ·Đž ĐžĐœŃŃ‚Đ°ĐœŃ†ĐžŃ." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»ĐœĐžŃ‚Đ” Đ±Đ°ĐœĐ”Ń€Đž ОзОсĐșĐČат {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»ĐœĐžŃ‚Đ” Đ±Đ°ĐœĐ”Ń€Đž ОзОсĐșĐČат {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "ĐĐ°Ń‚ĐžŃĐœĐž Đž ĐłĐŸĐČĐŸŃ€Đž" msgid "Push-to-talk (limited)" msgstr "ĐĐ°Ń‚ĐžŃĐœĐž Đž ĐłĐŸĐČĐŸŃ€Đž (ĐŸĐłŃ€Đ°ĐœĐžŃ‡Đ”ĐœĐŸ)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "â€žĐĐ°Ń‚ĐžŃĐœĐž Đž ĐłĐŸĐČĐŸŃ€Đžâ€œ сД ĐžĐłĐœĐŸŃ€ĐžŃ€Đ° про ЎОрДĐșŃ‚Đ”Đœ ĐČŃ…ĐŸĐŽ. ĐŸŃ€Đ”ĐČĐșлючО ĐœĐ° â€žĐ€ĐŸĐșŃƒŃĐžŃ€Đ°Đœ ĐłĐ»Đ°Ńâ€œ ОлО â€žĐŸĐŸ ĐžĐ·Đ±ĐŸŃ€â€œ, за Ўа ĐłĐŸ ĐžĐ·ĐżĐŸĐ»Đ·ĐČаш." @@ -26551,8 +26537,8 @@ msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° проĐșĐ°Ń‡Đ”Đœ фаĐčĐ»" msgid "Remove authenticator app" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ”Ń‚ĐŸ за ŃƒĐŽĐŸŃŃ‚ĐŸĐČĐ”Ń€ŃĐČĐ°ĐœĐ”" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° аĐČатара" @@ -26561,8 +26547,8 @@ msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° аĐČатара" msgid "Remove background" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° Ń„ĐŸĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° Đ±Đ°ĐœĐ”Ń€" @@ -26625,10 +26611,10 @@ msgstr "БДз Đ·Đ°ĐŽŃŠŃ€Đ¶Đ°ĐœĐ” ĐŸŃ‚ĐłĐŸŃ€Đ”" msgid "Remove from URL-only GIF favorites" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐŸŃ‚ Đ»ŃŽĐ±ĐžĐŒĐžŃ‚Đ” GIF фаĐčĐ»ĐŸĐČĐ”, Đ·Đ°ĐżĐ°Đ·Đ”ĐœĐž ĐżĐŸ URL аЎрДс" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ĐŸŃ€Đ”ĐŒĐ°Ń…ĐČĐ°ĐœĐ” ĐœĐ° ĐžĐșĐŸĐœĐ°" @@ -27331,7 +27317,7 @@ msgstr "Đ˜Đ·ĐżŃ€Đ°Ń‚Đ”ĐœĐŸ ĐŸŃ‚ĐœĐŸĐČĐŸ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ĐŃƒĐ»ĐžŃ€Đ°ĐœĐ”" @@ -28074,7 +28060,7 @@ msgstr "Đ ŃƒĐŒŃŠĐœŃĐșĐž" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ЗаĐČŃŠŃ€Ń‚Đ°ĐœĐ” ĐżĐŸ Ń‡Đ°ŃĐŸĐČĐœĐžĐșĐŸĐČата стрДлĐșа" @@ -28153,8 +28139,8 @@ msgstr "ĐĐ°ŃĐžŃ‚Đ”ĐœĐŸŃŃ‚" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ĐšĐŸĐœŃ‚Ń€ĐŸĐ»Đž за ĐșĐŸĐŽĐžŃ€Đ°ĐœĐ” ĐœĐ° ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐ” ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ°" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "ĐĄĐżĐŸĐŽĐ”Đ»ŃĐœĐ”Ń‚ĐŸ ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ° проĐșлючО" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "ĐŸĐŸĐșазĐČĐ°ĐœĐ” ĐœĐ° чДрĐČĐ”ĐœĐ° Đ·ĐœĐ°Ń‡Đșа ĐČърху ĐžĐșĐŸĐœĐ°Ń‚Đ° ĐœĐ° ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ”Ń‚ĐŸ про ĐœĐ°Đ»ĐžŃ‡ĐžĐ” ĐœĐ° ĐœĐ”ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”ĐœĐž ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "ĐŸĐŸĐșазĐČа ŃĐ°ĐŒĐŸ аĐșŃ†Đ”ĐœŃ‚ĐœĐžŃ цĐČят, ĐœĐ”Đ·Đ°ĐČĐžŃĐžĐŒĐŸ ĐŸŃ‚ ĐłĐ»ĐŸĐ±Đ°Đ»ĐœĐžŃ то ĐżŃ€ĐŸŃ„ĐžĐ»" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "ĐŸĐŸĐșазĐČĐ°ĐœĐ” ĐœĐ° ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°ĐœĐž Đ”ĐŒĐŸĐŽĐ¶ĐžŃ‚Đ° ĐČ Đ°ĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡ĐœĐŸŃ‚ĐŸ ĐŽĐŸĐČършĐČĐ°ĐœĐ” ĐœĐ° ОзразО" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "ĐŸĐŸĐșазĐČа аĐČатара ĐżĐŸ ĐżĐŸĐŽŃ€Đ°Đ·Đ±ĐžŃ€Đ°ĐœĐ”, ĐœĐ”Đ·Đ°ĐČĐžŃĐžĐŒĐŸ ĐŸŃ‚ ĐłĐ»ĐŸĐ±Đ°Đ»ĐœĐžŃ то ĐżŃ€ĐŸŃ„ĐžĐ»" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "ĐŸĐŸĐșазĐČĐ°ĐœĐ” ĐœĐ° ĐžĐœĐŽĐžĐșĐ°Ń‚ĐŸŃ€ за ĐœĐ”ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”ĐœĐž ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ ĐČ Đ·Đ°ĐłĐ»ŃƒŃˆĐ”ĐœĐž ĐșĐ°ĐœĐ°Đ»Đž" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ĐŸĐŸĐșазĐČа аĐČатара ĐœĐ° ĐłĐ»ĐŸĐ±Đ°Đ»ĐœĐžŃ то ĐżŃ€ĐŸŃ„ĐžĐ» ĐČ Ń‚Đ°Đ·Đž ĐŸĐ±Ń‰ĐœĐŸŃŃ‚" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ĐŸĐŸĐșазĐČа Đ±Đ°ĐœĐ”Ń€Đ° ĐœĐ° ĐłĐ»ĐŸĐ±Đ°Đ»ĐœĐžŃ то ĐżŃ€ĐŸŃ„ĐžĐ» ĐČ Ń‚Đ°Đ·Đž ĐŸĐ±Ń‰ĐœĐŸŃŃ‚" @@ -30720,7 +30706,7 @@ msgstr "ĐŸŃ€ĐŸĐżŃƒŃĐœĐž" msgid "Skip \"Mark all as read\" confirmation" msgstr "ĐŸŃ€ĐŸĐżŃƒŃĐșĐ°ĐœĐ” ĐœĐ° ĐżĐŸŃ‚ĐČŃŠŃ€Đ¶ĐŽĐ”ĐœĐžĐ”Ń‚ĐŸ за „МарĐșораĐč ĐČсочĐșĐž ĐșĐ°Ń‚ĐŸ ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”ĐœĐžâ€œ" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "ĐŸŃ€ĐŸĐżŃƒŃĐœĐž ĐžĐ·Ń€ŃĐ·ĐČĐ°ĐœĐ”Ń‚ĐŸ" @@ -32346,7 +32332,7 @@ msgstr "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ” ĐșŃŠĐŒ ŃƒĐŽĐŸĐ±Đ”Đœ ОзглДЎ" msgid "Switch to dense layout" msgstr "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ” ĐșŃŠĐŒ сбОт ОзглДЎ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ĐŸŃ€Đ”ĐČĐșлючĐČĐ°ĐœĐ” ĐșŃŠĐŒ ЎОрДĐșŃ‚Đ”Đœ ĐČŃ…ĐŸĐŽ" @@ -32734,7 +32720,7 @@ msgstr "ЗаЮачо" msgid "Teleporting you to another voice region..." msgstr "ĐŸŃ€Đ”Ń…ĐČŃŠŃ€Đ»ŃĐœĐ” ĐșŃŠĐŒ Юруг ĐłĐ»Đ°ŃĐŸĐČ Ń€Đ”ĐłĐžĐŸĐœ..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ĐšĐ°Đ±Đ»ĐŸĐœ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Đ ĐŸĐ»ŃŃ‚Đ° ĐżŃ€Đ”ĐŽĐŸŃŃ‚Đ°ĐČĐž {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Đ˜Đ·Ń‚ĐŸŃ‡ĐœĐžĐșът ĐœĐ° ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐ” ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ° спря Ўа Озпраща ĐČĐžĐŽĐ”ĐŸ, ĐżĐŸŃ€Đ°ĐŽĐž ĐșĐŸĐ”Ń‚ĐŸ ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐ”Ń‚ĐŸ ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ° бДшД прДĐșŃ€Đ°Ń‚Đ”ĐœĐŸ." @@ -33453,6 +33439,11 @@ msgstr "ĐąĐŸĐ·Đž аĐșĐ°ŃƒĐœŃ‚ ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД Đ±Đ»ĐŸĐșĐžŃ€Đ°Đœ." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "ĐąĐŸĐČа ĐŽĐ”ĐčстĐČОД ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД ĐŸŃ‚ĐŒĐ”ĐœĐ”ĐœĐŸ. ВсочĐșĐž сĐČŃŠŃ€Đ·Đ°ĐœĐž ĐŽĐ°ĐœĐœĐž, ĐČĐșĐ»ŃŽŃ‡ĐžŃ‚Đ”Đ»ĐœĐŸ ĐżĐŸŃ‚Ń€Đ”Đ±ĐžŃ‚Đ”Đ»ŃŃ‚ ĐœĐ° Đ±ĐŸŃ‚Đ°, щД бъЎат ОзтрОтО заĐČĐžĐœĐ°ĐłĐž." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "ĐĐœĐžĐŒĐ°Ń†ĐžŃŃ‚Đ° Đ” тĐČърЎД Ўълга ОлО тĐČърЎД ĐłĐŸĐ»ŃĐŒĐ°, за Ўа бъЎД ĐžĐ·Ń€ŃĐ·Đ°ĐœĐ°. ОпотаĐčтД с ĐżĐŸ-ĐșратъĐș ОлО ĐżĐŸ-ĐŒĐ°Đ»ŃŠĐș фаĐčĐ»." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "ĐąĐŸĐ·Đž Đ±ĐŸŃ‚ ĐœĐ” Đ” ĐżŃƒĐ±Đ»ĐžŃ‡Đ”Đœ Đž ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "ĐąĐŸĐ·Đž Đ±ĐŸŃ‚ ОсĐșа Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐ”Ń‚ĐŸ â€žĐĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€â€œ. ДаĐč ĐłĐŸ ŃĐ°ĐŒĐŸ аĐșĐŸ ĐžĐŒĐ°Ńˆ ĐżŃŠĐ»ĐœĐŸ ĐŽĐŸĐČДрОД ĐœĐ° Ń€Đ°Đ·Ń€Đ°Đ±ĐŸŃ‚Ń‡ĐžĐșа. Đ’ĐŒĐ”ŃŃ‚ĐŸ Ń‚ĐŸĐČа ĐłĐŸ ĐżĐŸĐŒĐŸĐ»Đž Ўа ĐżĐŸĐžŃĐșа ĐżĐŸ-ĐŒĐ°Đ»ĐșĐŸ Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžŃ. ЗатĐČĐŸŃ€Đž тазО ŃŃ‚Ń€Đ°ĐœĐžŃ†Đ°, аĐșĐŸ ĐžĐŒĐ°Ńˆ ŃŃŠĐŒĐœĐ”ĐœĐžŃ." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "ĐąĐŸĐ·Đž Đ±Ń€Đ°ŃƒĐ·ŃŠŃ€ ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа ĐŸĐ±Ń€Đ°Đ±ĐŸŃ‚ĐČа Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž {avifFormatLabel} фаĐčĐ»ĐŸĐČĐ”. Đ’ĐŒĐ”ŃŃ‚ĐŸ Ń‚ĐŸĐČа ĐșачДтД GIF ОлО WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "йазО ĐșĐŸĐœĐ·ĐŸĐ»Đ° ĐœĐ° Đ±Ń€Đ°ŃƒĐ·ŃŠŃ€Đ° Đ” ĐžĐœŃŃ‚Ń€ŃƒĐŒĐ”ĐœŃ‚ за Ń€Đ°Đ·Ń€Đ°Đ±ĐŸŃ‚Ń‡ĐžŃ†Đž." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "В Ń‚ĐŸĐ·Đž Đ±Ń€Đ°ŃƒĐ·ŃŠŃ€ WebAssembly Đ” ОзĐșĐ»ŃŽŃ‡Đ”Đœ, таĐșа чД Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐœĐ” ĐŒĐŸĐłĐ°Ń‚ Ўа бъЎат ĐžĐ·Ń€ŃĐ·ĐČĐ°ĐœĐž." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "йазО група Đ” ĐżŃŠĐ»ĐœĐ°. ĐŸŃ€Đ”ĐŒĐ°Ń…ĐœĐž ĐœŃĐșĐŸĐłĐŸ, прД msgid "This handoff code has expired. Generate a new one to continue." msgstr "ĐąĐŸĐ·Đž ĐșĐŸĐŽ за прДхĐČŃŠŃ€Đ»ŃĐœĐ” Đ” ОзтДĐșŃŠĐ». Đ“Đ”ĐœĐ”Ń€ĐžŃ€Đ°Đč ĐœĐŸĐČ, за Ўа ĐżŃ€ĐŸĐŽŃŠĐ»Đ¶ĐžŃˆ." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "ĐąĐŸĐ·Đž ĐŸĐ±Ń€Đ°Đ· ĐœĐ” ĐŒĐŸĐ¶Đ” Ўа бъЎД ĐżŃ€ĐŸŃ‡Đ”Ń‚Đ”Đœ. ĐœĐŸĐ¶Đ” Ўа Đ” ĐżĐŸĐČŃ€Đ”ĐŽĐ”Đœ." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "КачĐČĐ°ĐœĐ”" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Качо ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°Đœ аĐČатар за тазО ĐŸĐ±Ń‰ĐœĐŸŃŃ‚" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Качо ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°Đœ Đ±Đ°ĐœĐ”Ń€ за тазО ĐŸĐ±Ń‰ĐœĐŸŃŃ‚" @@ -36155,10 +36163,10 @@ msgstr "КачĐČĐ°ĐœĐ” ĐœĐ° фаĐčĐ»ĐŸĐČĐ” Đž ĐŒĐ”ĐŽĐžĐž ĐČ ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ." msgid "Upload files and media in this channel." msgstr "КачĐČĐ°ĐœĐ” ĐœĐ° фаĐčĐ»ĐŸĐČĐ” Đž ĐŒĐ”ĐŽĐžĐž ĐČ Ń‚ĐŸĐ·Đž ĐșĐ°ĐœĐ°Đ»." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "КачĐČĐ°ĐœĐ” ĐœĐ° ĐžĐșĐŸĐœĐ°" @@ -36401,8 +36409,8 @@ msgstr "Đ˜Đ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐ” ĐœĐ° ĐČŃŠĐłĐ»Đ”ĐœĐŸĐČа Ń‚Đ”ĐŒĐ° (ĐœĐ°ŃĐžŃ‚Đ”ĐœĐŸ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Đ˜Đ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐ” ĐœĐ° ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°ĐœĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”" @@ -36462,8 +36470,8 @@ msgstr "Đ˜Đ·ĐżĐŸĐ»Đ·ĐČаĐč фОлтрО ОлО ĐČъĐČДЎО ĐșĐ»ŃŽŃ‡ĐŸĐČĐž Ўу #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Đ˜Đ·ĐżĐŸĐ»Đ·ĐČĐ°ĐœĐ” ĐœĐ° ĐłĐ»ĐŸĐ±Đ°Đ»Đ”Đœ ĐżŃ€ĐŸŃ„ĐžĐ»" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ĐŁŃ‡Đ°ŃŃ‚ĐœĐžŃ†Đž ĐČ ĐłĐ»Đ°ŃĐŸĐČ Ń‡Đ°Ń‚" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ĐžĐ±Ń€Đ°Đ±ĐŸŃ‚Đșа ĐœĐ° глас" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "УОсĐșĐŸĐœŃĐžĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "ĐĄ {PREMIUM_PRODUCT_NAME} ĐŒĐŸĐ¶Đ”Ńˆ Ўа ĐžĐ·ĐżĐŸĐ»Đ·ĐČаш Đ°ĐœĐžĐŒĐžŃ€Đ°ĐœĐž аĐČатаро ({ANIMATED_AVATAR_FORMATS}) Đž Đ±Đ°ĐœĐ”Ń€Đž за ĐżŃ€ĐŸŃ„ĐžĐ», Ўа ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°Ńˆ тага сО Đž Ўа ĐŸŃ‚ĐșĐ»ŃŽŃ‡ĐžŃˆ ĐŒĐœĐŸĐłĐŸ Юруго ĐżŃ€Đ”ĐŽĐžĐŒŃŃ‚ĐČа ĐœĐ° {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "ĐŃƒĐ¶ĐœĐŸ Đ” Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐ”Ń‚ĐŸ „{permissionLabel}“, за ĐŽ msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "ĐŃƒĐ¶ĐœĐŸ Đ” Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐ”Ń‚ĐŸ „{permissionLabel}“, за Ўа ĐžĐ·ĐżĐŸĐ»Đ·ĐČаш стоĐșДрО ĐŸŃ‚ Юруго ĐŸĐ±Ń‰ĐœĐŸŃŃ‚Đž туĐș." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ĐąŃ€ŃĐ±ĐČа Ўа Đ·Đ°ŃĐČОш аĐșĐ°ŃƒĐœŃ‚Đ° сО, прДЎО Ўа ĐŒĐŸĐ¶Đ”Ńˆ Ўа ŃŃŠĐ·ĐŽĐ°ĐŽĐ”Ńˆ ĐŸĐ±Ń‰ĐœĐŸŃŃ‚." @@ -39356,8 +39364,8 @@ msgstr "ĐąŃ€ŃĐ±ĐČа Ўа Đ·Đ°ŃĐČОш аĐșĐ°ŃƒĐœŃ‚Đ° сО, за Ўа Озпра msgid "You need to verify a phone number to send messages in this community." msgstr "ĐąŃ€ŃĐ±ĐČа Ўа ĐżĐŸŃ‚ĐČърЮош Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ”Đœ ĐœĐŸĐŒĐ”Ń€, за Ўа ĐžĐ·ĐżŃ€Đ°Ń‰Đ°Ńˆ ŃŃŠĐŸĐ±Ń‰Đ”ĐœĐžŃ ĐČ Ń‚Đ°Đ·Đž ĐŸĐ±Ń‰ĐœĐŸŃŃ‚." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ĐąŃ€ŃĐ±ĐČа Ўа ĐżĐŸŃ‚ĐČърЮош ĐžĐŒĐ”ĐčĐ» аЎрДса сО, прДЎО Ўа ĐŒĐŸĐ¶Đ”Ńˆ Ўа ŃŃŠĐ·ĐŽĐ°ĐŽĐ”Ńˆ ĐŸĐ±Ń‰ĐœĐŸŃŃ‚." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Вашата Đ·Đ°ĐżĐ°Đ·Đ”ĐœĐ° ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșа {savedResolution} про {savedFrameRate} FPS ОзОсĐșĐČа {premiumProductName}, таĐșа чД ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐžŃŃ‚Đ° ĐžĐ·ĐżĐŸĐ»Đ·ĐČат {resolution} про {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ĐĄĐżĐŸĐŽĐ”Đ»ŃĐœĐ”Ń‚ĐŸ ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ° то ĐœĐ” ĐŒĐŸĐ¶Đ° Ўа бъЎД публОĐșуĐČĐ°ĐœĐŸ със съĐČĐŒĐ”ŃŃ‚ĐžĐŒ ĐČĐžĐŽĐ”ĐŸ ĐșĐŸĐŽĐ”Đș, Đ·Đ°Ń‚ĐŸĐČа бДшД ŃĐżŃ€ŃĐœĐŸ. ОпотаĐč Ўа ŃĐżĐŸĐŽĐ”Đ»ĐžŃˆ ĐŸŃ‚ĐœĐŸĐČĐŸ." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "ĐŸĐ”Ń€ŃĐŸĐœĐ°Đ»ĐžĐ·ĐžŃ€Đ°ĐœĐžŃŃ‚ то URL аЎрДс Đ” Đ·Đ°ĐŽĐ°ĐŽĐ”Đœ ĐœĐ° {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Đ’ĐžĐŽĐ”ĐŸĐ”ĐœĐșĐŸĐŽĐ”Ń€ŃŠŃ‚ то спря Ўа ĐșĐŸĐŽĐžŃ€Đ° ĐșаЮро, Đ·Đ°Ń‚ĐŸĐČа ŃĐżĐŸĐŽĐ”Đ»ŃĐœĐ”Ń‚ĐŸ ĐœĐ° Đ”ĐșŃ€Đ°ĐœĐ° бДшД ŃĐżŃ€ŃĐœĐŸ. ОпотаĐč Ўа ŃĐżĐŸĐŽĐ”Đ»ĐžŃˆ ĐŸŃ‚ĐœĐŸĐČĐŸ." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "ĐœĐ°Ń‰Đ°Đ±ĐžŃ€Đ°ĐœĐ”" diff --git a/fluxer_app/src/features/i18n/locales/cs/messages.po b/fluxer_app/src/features/i18n/locales/cs/messages.po index 5f3f5815e..540394c83 100644 --- a/fluxer_app/src/features/i18n/locales/cs/messages.po +++ b/fluxer_app/src/features/i18n/locales/cs/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, jiĆŸ brzy" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Rozměry {label} neodpovĂ­dajĂ­ tomuto prostƙedku. Vyberte jinĂœ obrĂĄzek nebo nahrajte statickĂœ obrĂĄzek, kterĂœ mĆŻĆŸete oƙíznout." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Soubor {label} je pƙíliĆĄ velkĂœ. Vyberte soubor menĆĄĂ­ neĆŸ {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "ObrĂĄzky {label} nemohou bĂœt animovanĂ©. PouĆŸijte statickĂœ obrĂĄzek." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "SdĂ­lenĂ­ aktivit" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "PrĂĄh aktivity" @@ -3566,11 +3561,11 @@ msgstr "Povolit zmĂ­nky {everyoneMention} a {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Povolte aplikaci {PRODUCT_NAME} pƙístup k vaĆĄĂ­ kameƙe v {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Povolte aplikaci {PRODUCT_NAME} pƙístup k mikrofonu v: {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Povolte aplikaci {PRODUCT_NAME} pƙístup k mikrofonu. Zkontrolujte adresnĂ­ ƙádek nebo nastavenĂ­ prohlĂ­ĆŸeče." @@ -3673,7 +3668,7 @@ msgstr "Povolit členĆŻm bez oprĂĄvněnĂ­ {readMessageHistoryPermissionLabel} zo msgid "Allow mentions for this role" msgstr "Povolit zmĂ­nky pro tuto roli" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Povolit mikrofon" @@ -3942,25 +3937,21 @@ msgstr "a {remainingCount, plural, one {# dalĆĄĂ­} few {# dalĆĄĂ­} many {# dalĆĄ msgid "Animate on interaction" msgstr "Animovat pƙi interakci" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "AnimovanĂ© soubory {AVIF_FORMAT_LABEL} nejsou podporovĂĄny. Nahrajte mĂ­sto toho statickĂœ soubor {AVIF_FORMAT_LABEL}." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "AnimovanĂœ formĂĄt {avifFormatLabel} nenĂ­ podporovĂĄn" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "AnimovanĂ© avatary ({ANIMATED_AVATAR_FORMATS}) jsou dostupnĂ© pouze pƙedplatitelĆŻm {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "AnimovanĂ© avatary ({ANIMATED_AVATAR_FORMATS}) nejsou na tĂ©to instanci dostupnĂ©. Nahrajte mĂ­sto toho statickĂœ obrĂĄzek." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "AnimovanĂ© avatary ({animatedAvatarFormats}) vyĆŸadujĂ­ {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "AnimovanĂ© avatary a bannery profilu" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "AnimovanĂ© avatary nejsou k dispozici" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "AnimovanĂ© avatary vyĆŸadujĂ­ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "NĂĄhled animovanĂ©ho obrĂĄzku" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "AnimovanĂ© obrĂĄzky nejsou pro toto mĂ©dium podporovĂĄny." @@ -4947,7 +4938,7 @@ msgstr "Automaticky rozpoznat jazyk" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Automaticky nastavit prĂĄh aktivity" @@ -5127,15 +5118,15 @@ msgstr "K dispozici v desktopovĂ© aplikaci." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Soubor avatara je pƙíliĆĄ velkĂœ. Vyberte soubor menĆĄĂ­ neĆŸ {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar je pƙíliĆĄ velkĂœ – vyberte obrĂĄzek do {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "VĂœběr reĆŸimu avatara" @@ -5187,11 +5178,11 @@ msgstr "MomentĂĄlně pryč" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "ZabanovanĂ­ uĆŸivatelĂ©" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Soubor banneru je pƙíliĆĄ velkĂœ. Vyberte soubor menĆĄĂ­ neĆŸ {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "VĂœběr reĆŸimu banneru" @@ -6107,8 +6098,8 @@ msgstr "Kupte dĂĄrkovĂ© pƙedplatnĂ© {premiumProductName} na kartě {premiumProd msgid "Buy gift" msgstr "Koupit dĂĄrek" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "VytvoƙenĂ­m komunity souhlasĂ­te s dodrĆŸovĂĄnĂ­m a prosazovĂĄnĂ­m <0>pravidel komunity {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Sem nelze nahrĂĄvat soubory" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Na stƙed" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Změnit avatar" @@ -6627,9 +6618,9 @@ msgstr "Změnit pozadĂ­" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Změnit banner" @@ -6668,13 +6659,13 @@ msgstr "Změnit pƙezdĂ­vku skupiny" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Změnit ikonu" @@ -7669,8 +7660,8 @@ msgstr "PƙevzĂ­t dĂĄrek" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Dokončit registraci Ășčtu" @@ -8518,8 +8509,8 @@ msgstr "Komunita umoĆŸĆˆuje hromadnĂ© Ăștoky nebo cĂ­lenĂ© obtÄ›ĆŸovĂĄnĂ­." msgid "Community filter" msgstr "Filtr komunit" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ikona komunity" @@ -8763,6 +8754,11 @@ msgstr "Tlačítka pro psanĂ­ zprĂĄv" msgid "Composer focus" msgstr "Fokus v poli pro psanĂ­ zprĂĄv" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimuji" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Pƙipojte kameru nebo virtuĂĄlnĂ­ zĂĄznamovĂ© zaƙízenĂ­ a zkuste to zn msgid "Connect a display, then try again." msgstr "Pƙipojte displej a zkuste to znovu." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Pƙipojte mikrofon a zkuste to znovu." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nepodaƙilo se vytvoƙit tuto samolepku" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ObrĂĄzek se nepodaƙilo oƙíznout" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Teď se nepodaƙilo aktualizovat sdĂ­lenĂ­ hlasovĂ© aktivity" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nepodaƙilo se nahrĂĄt avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nepodaƙilo se nahrĂĄt banner" @@ -10230,7 +10226,7 @@ msgstr "Vytvoƙit a sdĂ­let" msgid "Create a community" msgstr "Vytvoƙit komunitu" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Vytvoƙte komunitu pro sebe a svĂ© pƙátele, kde si mĆŻĆŸete povĂ­dat." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Oƙíznout pozadĂ­ pozvĂĄnky" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "NĂĄhled oƙezu" @@ -10500,30 +10496,15 @@ msgstr "Oƙíznout banner profilu" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "OƙíznutĂœ obrĂĄzek je pƙíliĆĄ velkĂœ. Vyberte menĆĄĂ­ oblast nebo menĆĄĂ­ soubor (max. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "OƙezĂĄvĂĄnĂ­ animovanĂœch souborĆŻ {formatLabel} zatĂ­m nenĂ­ podporovĂĄno. PouĆŸije se pĆŻvodnĂ­ obrĂĄzek." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "OƙezĂĄvĂĄnĂ­ animovanĂœch souborĆŻ {formatLabel} zatĂ­m nenĂ­ podporovĂĄno. PouĆŸije se pĆŻvodnĂ­ nahranĂœ soubor." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "OƙezĂĄvĂĄnĂ­ animovanĂœch souborĆŻ zatĂ­m nenĂ­ podporovĂĄno. PouĆŸije se pĆŻvodnĂ­ obrĂĄzek." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "OƙezĂĄvĂĄnĂ­ animovanĂœch souborĆŻ zatĂ­m nenĂ­ podporovĂĄno. PouĆŸije se pĆŻvodnĂ­ nahranĂœ soubor." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "OƙezĂĄvĂĄnĂ­ {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "NemĂĄte Ășčet?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Nezobrazovat" @@ -16560,8 +16541,8 @@ msgstr "Avatary skupinovĂœch konverzacĂ­ pouĆŸĂ­vajĂ­ stejnĂ© masky stavĆŻ jako msgid "Group DMs" msgstr "SkupinovĂ© konverzace" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ikona skupiny" @@ -16624,8 +16605,8 @@ msgstr "NastavenĂ­ skupiny" msgid "Group typing states" msgstr "Stavy psanĂ­ ve skupině" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Skupina aktualizovĂĄna" @@ -16803,7 +16784,7 @@ msgstr "Srdce" msgid "Hebrew" msgstr "HebrejĆĄtina" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "VĂœĆĄka" @@ -17510,7 +17491,7 @@ msgstr "ObrĂĄzek zkopĂ­rovĂĄn do schrĂĄnky" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ObrĂĄzek nelze pouĆŸĂ­t" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Vzhled a ovlĂĄdĂĄnĂ­" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ZdĂĄ se, ĆŸe pouĆŸĂ­vĂĄte {0}. PƙidĂĄnĂ­ dalĆĄĂ­ho zpracovĂĄnĂ­ zvuku v aplikaci {PRODUCT_NAME} mĆŻĆŸe zpĆŻsobit kolĂ­sĂĄnĂ­ hlasitosti nebo zkreslenĂ­. PƙímĂœ vstup propouĆĄtĂ­ zvuk beze změn." @@ -22577,7 +22558,7 @@ msgstr "Nic nebylo nalezeno" msgid "No mentions yet" msgstr "ZatĂ­m ĆŸĂĄdnĂ© zmĂ­nky" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Mikrofon nenalezen" @@ -23806,7 +23787,7 @@ msgstr "Otevƙít systĂ©movou soukromou konverzaci" msgid "Open system picker" msgstr "Otevƙít systĂ©movĂœ vĂœběr" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Otevƙít ĆĄablonu JSON" @@ -23820,7 +23801,7 @@ msgstr "Otevƙít dialog pro zabanovĂĄnĂ­ v tĂ©to komunitě." msgid "Open the context menu" msgstr "Otevƙít kontextovou nabĂ­dku" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Otevƙete odkaz nĂ­ĆŸe ve svĂ©m prohlĂ­ĆŸeči, zkopĂ­rujte celou odpověď JSON a vloĆŸte ji do pole." @@ -24331,7 +24312,7 @@ msgstr "PoslednĂ­ch 7 dnĂ­" msgid "Paste" msgstr "VloĆŸit" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "VloĆŸte URL ĆĄablony platformy {theOtherPlatform} a importujte jejĂ­ strukturu do novĂ© komunity." @@ -25191,6 +25172,11 @@ msgstr "Typ pƙedplatnĂ©ho" msgid "Premium until date" msgstr "Datum konce pƙedplatnĂ©ho" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Pƙipravuji" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Odznak profilu" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "ProfilovĂ© bannery jsou funkce {PREMIUM_PRODUCT_NAME}. ZĂ­skejte {PREMIUM_PRODUCT_NAME} a pƙidejte si banner do svĂ©ho profilu." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Na tĂ©to instanci nejsou zapnutĂ© profilovĂ© bannery." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Bannery profilu vyĆŸadujĂ­ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Bannery profilu vyĆŸadujĂ­ {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "StisknutĂ­m mluvit" msgid "Push-to-talk (limited)" msgstr "StisknutĂ­m mluvit (omezenĂĄ funkčnost)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "V reĆŸimu PƙímĂœ vstup se nastavenĂ­ StisknutĂ­m mluvit ignoruje. Chcete-li ho pouĆŸĂ­t, pƙepněte na reĆŸim Hlas v popƙedĂ­ nebo VlastnĂ­." @@ -26551,8 +26537,8 @@ msgstr "Odebrat pƙílohu" msgid "Remove authenticator app" msgstr "Odebrat ověƙovacĂ­ aplikaci" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Odebrat avatar" @@ -26561,8 +26547,8 @@ msgstr "Odebrat avatar" msgid "Remove background" msgstr "Odebrat pozadĂ­" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Odebrat banner" @@ -26625,10 +26611,10 @@ msgstr "Odebrat ze seznamu oken nahoƙe" msgid "Remove from URL-only GIF favorites" msgstr "Odebrat z oblĂ­benĂœch GIFĆŻ uloĆŸenĂœch pouze jako URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Odebrat ikonu" @@ -27331,7 +27317,7 @@ msgstr "Znovu odeslĂĄno" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Resetovat" @@ -28074,7 +28060,7 @@ msgstr "RumunĆĄtina" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Otočit po směru hodinovĂœch ručiček" @@ -28153,8 +28139,8 @@ msgstr "Sytost" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "OvlĂĄdacĂ­ prvky enkodĂ©ru pro sdĂ­lenĂ­ obrazovky" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "SdĂ­lenĂ­ obrazovky ukončeno" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Zobrazit červenĂœ odznak na ikoně aplikace, kdyĆŸ mĂĄte nepƙečtenĂ© zprĂĄvy" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Zobrazit pouze barvu zvĂœrazněnĂ­, ignorovat globĂĄlnĂ­ profil" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Zobrazovat vlastnĂ­ emoji v automatickĂ©m doplƈovĂĄnĂ­ vĂœrazĆŻ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Zobrazit vĂœchozĂ­ avatar, ignorovat globĂĄlnĂ­ profil" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Zobrazit indikĂĄtor nepƙečtenĂœch zprĂĄv u ztlumenĂœch kanĂĄlĆŻ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Zobrazit avatar globĂĄlnĂ­ho profilu v tĂ©to komunitě" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Zobrazit banner globĂĄlnĂ­ho profilu v tĂ©to komunitě" @@ -30720,7 +30706,7 @@ msgstr "Pƙeskočit" msgid "Skip \"Mark all as read\" confirmation" msgstr "Pƙeskočit potvrzenĂ­ \"Označit vĆĄe jako pƙečtenĂ©\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Pƙeskočit oƙíznutĂ­" @@ -32346,7 +32332,7 @@ msgstr "Pƙepnout na pohodlnĂ© rozvrĆŸenĂ­" msgid "Switch to dense layout" msgstr "Pƙepnout na zhuĆĄtěnĂ© rozvrĆŸenĂ­" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Pƙepnout na pƙímĂœ vstup" @@ -32734,7 +32720,7 @@ msgstr "Úkoly" msgid "Teleporting you to another voice region..." msgstr "PƙesouvĂĄme vĂĄs do jinĂ©ho hlasovĂ©ho regionu..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Ć ablona" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Role udělila {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Zdroj sdĂ­lenĂ­ obrazovky pƙestal odesĂ­lat video, takĆŸe bylo ukončeno sdĂ­lenĂ­ obrazovky." @@ -33453,6 +33439,11 @@ msgstr "Tento Ășčet nelze zablokovat." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Tuto akci nelze vrĂĄtit zpět. VĆĄechna souvisejĂ­cĂ­ data, včetně uĆŸivatele bota, budou trvale smazĂĄna." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Tato animace je pƙíliĆĄ dlouhĂĄ nebo pƙíliĆĄ velkĂĄ na oƙíznutĂ­. Zkuste kratĆĄĂ­ nebo menĆĄĂ­ soubor." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Tento bot nenĂ­ veƙejnĂœ a ostatnĂ­ uĆŸivatelĂ© ho nemohou pƙidat." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Tento bot vyĆŸaduje administrĂĄtorskĂĄ oprĂĄvněnĂ­. Udělte mu je, pouze pokud plně dĆŻvěƙujete vĂœvojáƙi. PoĆŸĂĄdejte ho, aby mĂ­sto toho vyĆŸadoval mĂ©ně oprĂĄvněnĂ­. Pokud si nejste jisti, zavƙete tuto strĂĄnku." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Tento prohlĂ­ĆŸeč neumĂ­ oƙíznout animovanĂ© soubory {avifFormatLabel}. Nahrajte mĂ­sto toho GIF nebo WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Tato konzole prohlĂ­ĆŸeče je nĂĄstroj pro vĂœvojáƙe." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ve vaĆĄem prohlĂ­ĆŸeči je vypnutĂĄ technologie WebAssembly, takĆŸe nelze oƙíznout animovanĂ© obrĂĄzky." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Tato skupina je plnĂĄ. NeĆŸ pƙidĂĄte dalĆĄĂ­ lidi, někoho odeberte." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Tento kĂłd pro pƙedĂĄnĂ­ vyprĆĄel. Vygenerujte si novĂœ, abyste mohli pokračovat." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Tento obrĂĄzek se nepodaƙilo pƙečíst. MĆŻĆŸe bĂœt poĆĄkozenĂœ." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "NahrĂĄt" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Nahrajte vlastnĂ­ avatar pro tuto komunitu" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "NahrĂĄt vlastnĂ­ banner pro tuto komunitu" @@ -36155,10 +36163,10 @@ msgstr "NahrĂĄvat soubory a mĂ©dia do zprĂĄv." msgid "Upload files and media in this channel." msgstr "NahrĂĄvat soubory a mĂ©dia v tomto kanĂĄlu." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "NahrĂĄt ikonu" @@ -36401,8 +36409,8 @@ msgstr "PouĆŸĂ­t uhelnĂœ motiv (černočernĂ© plochy)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "PouĆŸĂ­t vlastnĂ­ obrĂĄzek" @@ -36462,8 +36470,8 @@ msgstr "PouĆŸijte filtry nebo zadejte klíčovĂĄ slova k nalezenĂ­ zprĂĄv" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "PouĆŸĂ­t globĂĄlnĂ­ profil" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ÚčastnĂ­ci hlasovĂ©ho chatu" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ZpracovĂĄnĂ­ hlasu" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "S {PREMIUM_PRODUCT_NAME} mĆŻĆŸete pouĆŸĂ­vat animovanĂ© avatary ({ANIMATED_AVATAR_FORMATS}) a profilovĂ© bannery, pƙizpĆŻsobit si uĆŸivatelskou značku a odemknout mnoho dalĆĄĂ­ch vĂœhod {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "K pouĆŸĂ­vĂĄnĂ­ emoji z jinĂœch komunit zde potƙebujete oprĂĄvněnĂ­ \" msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "K pouĆŸĂ­vĂĄnĂ­ samolepek z jinĂœch komunit zde potƙebujete oprĂĄvněnĂ­ „{permissionLabel}“." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "NeĆŸ budete moci vytvoƙit komunitu, musĂ­te dokončit registraci svĂ©ho Ășčtu." @@ -39356,8 +39364,8 @@ msgstr "Abyste mohli v tĂ©to komunitě posĂ­lat zprĂĄvy, musĂ­te dokončit regis msgid "You need to verify a phone number to send messages in this community." msgstr "Abyste mohli v tĂ©to komunitě posĂ­lat zprĂĄvy, musĂ­te si ověƙit telefonnĂ­ číslo." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "NeĆŸ budete moct vytvoƙit komunitu, musĂ­te si ověƙit e-mailovou adresu." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "VaĆĄe uloĆŸenĂ© rozliĆĄenĂ­ {savedResolution} s frekvencĂ­ {savedFrameRate} snĂ­mkĆŻ za sekundu vyĆŸaduje {premiumProductName}, takĆŸe sdĂ­lenĂ­ pouĆŸĂ­vĂĄ rozliĆĄenĂ­ {resolution} s frekvencĂ­ {frameRate} snĂ­mkĆŻ za sekundu." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "SdĂ­lenĂ­ obrazovky se nepodaƙilo publikovat s kompatibilnĂ­m video kodekem, proto bylo zastaveno. Zkuste sdĂ­let znovu." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "VĂĄĆĄ vlastnĂ­ odkaz na pozvĂĄnku byl nastaven na {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "EnkodĂ©r videa pƙestal kĂłdovat snĂ­mky, takĆŸe sdĂ­lenĂ­ obrazovky bylo ukončeno. Zkuste sdĂ­let znovu." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "PƙiblĂ­ĆŸenĂ­" diff --git a/fluxer_app/src/features/i18n/locales/da/messages.po b/fluxer_app/src/features/i18n/locales/da/messages.po index e4821b053..dad4dc8c6 100644 --- a/fluxer_app/src/features/i18n/locales/da/messages.po +++ b/fluxer_app/src/features/i18n/locales/da/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, kommer snart" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Billedets mĂ„l passer ikke til {label}. VĂŠlg et andet billede, eller upload et statisk billede, du kan beskĂŠre." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Filen for {label} er for stor. VĂŠlg en fil, der er mindre end {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label}-billeder kan ikke vĂŠre animerede. Brug et statisk billede." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Aktivitetsdeling" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "AktivitetstĂŠrskel" @@ -3566,11 +3561,11 @@ msgstr "Tillad {everyoneMention} og {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Tillad {PRODUCT_NAME} at fĂ„ adgang til dit kamera i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Tillad {PRODUCT_NAME} at fĂ„ adgang til din mikrofon i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Giv {PRODUCT_NAME} adgang til din mikrofon. Tjek din browsers adresselinje eller indstillinger." @@ -3673,7 +3668,7 @@ msgstr "Tillad medlemmer uden tilladelsen {readMessageHistoryPermissionLabel} at msgid "Allow mentions for this role" msgstr "Tillad omtaler for denne rolle" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Tillad mikrofon" @@ -3942,25 +3937,21 @@ msgstr "og yderligere {remainingCount}" msgid "Animate on interaction" msgstr "Animer ved interaktion" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animerede {AVIF_FORMAT_LABEL}-filer understĂžttes ikke. Upload i stedet en statisk {AVIF_FORMAT_LABEL}-fil." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animeret {avifFormatLabel} understĂžttes ikke" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animerede avatarer ({ANIMATED_AVATAR_FORMATS}) er kun tilgĂŠngelige for {PREMIUM_PRODUCT_NAME}-abonnenter." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animerede avatarer ({ANIMATED_AVATAR_FORMATS}) er ikke tilgĂŠngelige pĂ„ denne instans. Upload i stedet et statisk billede." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animerede avatarer ({animatedAvatarFormats}) krĂŠver {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animerede avatarer og profilbannere" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animerede avatarer er ikke tilgĂŠngelige" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animerede avatarer krĂŠver {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ForhĂ„ndsvisning af animeret billede" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animerede billeder understĂžttes ikke for denne ressource." @@ -4947,7 +4938,7 @@ msgstr "Registrer sprog automatisk" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Indstil aktivitetstĂŠrskel automatisk" @@ -5127,15 +5118,15 @@ msgstr "TilgĂŠngelig i computerappen." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatarfilen er for stor. VĂŠlg en fil, der er mindre end {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avataren er for stor – vĂŠlg en under {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Valg af avatartilstand" @@ -5187,11 +5178,11 @@ msgstr "Ikke til stede lige nu" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Udelukkede brugere" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Bannerfilen er for stor. VĂŠlg en fil, der er mindre end {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Valg af bannertilstand" @@ -6107,8 +6098,8 @@ msgstr "KĂžb en {premiumProductName}-gave fra fanen {premiumProductName} for at msgid "Buy gift" msgstr "KĂžb gave" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Ved at oprette et fĂŠllesskab accepterer du at fĂžlge og hĂ„ndhĂŠve <0>retningslinjerne for fĂŠllesskabet hos {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Kan ikke uploade filer her" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centreret" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Skift profilbillede" @@ -6627,9 +6618,9 @@ msgstr "Skift baggrund" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Skift banner" @@ -6668,13 +6659,13 @@ msgstr "Skift kaldenavn i gruppen" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Skift ikon" @@ -7669,8 +7660,8 @@ msgstr "IndlĂžs gave" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "FuldfĂžr oprettelsen af din konto" @@ -8518,8 +8509,8 @@ msgstr "FĂŠllesskabet fremmer koordinerede angreb eller mĂ„lrettet chikane." msgid "Community filter" msgstr "FĂŠllesskabsfilter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "FĂŠllesskabsikon" @@ -8763,6 +8754,11 @@ msgstr "Knapper i skrivefeltet" msgid "Composer focus" msgstr "Fokus pĂ„ skrivefelt" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimerer" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Tilslut et kamera eller en virtuel optagelsesenhed, og prĂžv igen." msgid "Connect a display, then try again." msgstr "Tilslut en skĂŠrm, og prĂžv igen." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Tilslut en mikrofon og prĂžv igen." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Kunne ikke oprette dette klistermĂŠrke" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Kunne ikke beskĂŠre billede" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Kunne ikke opdatere deling af taleaktivitet lige nu" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Kunne ikke uploade avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Kunne ikke uploade banner" @@ -10230,7 +10226,7 @@ msgstr "Opret og del" msgid "Create a community" msgstr "Opret et fĂŠllesskab" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Opret et fĂŠllesskab, hvor du og dine venner kan chatte." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "BeskĂŠr invitationens baggrund" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "BeskĂŠringsforhĂ„ndsvisning" @@ -10500,30 +10496,15 @@ msgstr "BeskĂŠr profilbanner" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Det beskĂ„rede billede er for stort. VĂŠlg et mindre omrĂ„de eller en mindre fil (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "BeskĂŠring af animerede {formatLabel}-filer understĂžttes ikke endnu. Det originale billede vil blive brugt." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "BeskĂŠring af animerede {formatLabel}-filer understĂžttes ikke endnu. Den originale fil vil blive brugt." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "BeskĂŠring af animerede filer understĂžttes ikke endnu. Det originale billede vil blive brugt." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "BeskĂŠring af animerede filer understĂžttes ikke endnu. Den originale fil vil blive brugt." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "BeskĂŠrer {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Har du ikke en konto?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Vis ikke" @@ -16560,8 +16541,8 @@ msgstr "Avatarer for gruppechats bruger de samme statusmasker som almindelige av msgid "Group DMs" msgstr "Gruppechats" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Gruppeikon" @@ -16624,8 +16605,8 @@ msgstr "Gruppeindstillinger" msgid "Group typing states" msgstr "Gruppens skriveindikatorer" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Gruppe opdateret" @@ -16803,7 +16784,7 @@ msgstr "Hjerte" msgid "Hebrew" msgstr "Hebraisk" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "HĂžjde" @@ -17510,7 +17491,7 @@ msgstr "Billede kopieret til udklipsholder" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Billedet kunne ikke bruges" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Udseende og funktionalitet" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Det ser ud til, at du bruger {0}. Ekstra lydbehandling fra {PRODUCT_NAME} kan fĂ„ lyden til at pumpe eller blive forvrĂŠnget. Direkte input sender din lyd igennem uĂŠndret." @@ -22577,7 +22558,7 @@ msgstr "Ingen resultater fundet" msgid "No mentions yet" msgstr "Ingen omtaler endnu" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Mikrofon ikke fundet" @@ -23806,7 +23787,7 @@ msgstr "Åbn system-DM" msgid "Open system picker" msgstr "Åbn systemvĂŠlger" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Åbn skabelon-JSON" @@ -23820,7 +23801,7 @@ msgstr "Åbn dialogboksen for udelukkelse for dette fĂŠllesskab." msgid "Open the context menu" msgstr "Åbn genvejsmenuen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Åbn linket herunder i din browser, kopier derefter hele JSON-svaret, og indsĂŠt det i feltet." @@ -24331,7 +24312,7 @@ msgstr "Seneste 7 dage" msgid "Paste" msgstr "SĂŠt ind" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "IndsĂŠt en skabelon-URL fra {theOtherPlatform} for at importere strukturen til et nyt fĂŠllesskab." @@ -25191,6 +25172,11 @@ msgstr "Premium-type" msgid "Premium until date" msgstr "Premium indtil dato" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Forbereder" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Profilbadge" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profilbannere er en {PREMIUM_PRODUCT_NAME}-funktion. FĂ„ {PREMIUM_PRODUCT_NAME} for at tilfĂžje et banner til din profil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profilbannere er ikke aktiveret pĂ„ denne instans." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profilbannere krĂŠver {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profilbannere krĂŠver {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Tryk for at tale" msgid "Push-to-talk (limited)" msgstr "Tryk for at tale (begrĂŠnset)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Tryk for at tale ignoreres ved direkte input. Skift til Fokuseret tale eller Tilpasset for at bruge det." @@ -26551,8 +26537,8 @@ msgstr "Fjern vedhĂŠftet fil" msgid "Remove authenticator app" msgstr "Fjern godkendelsesapp" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Fjern profilbillede" @@ -26561,8 +26547,8 @@ msgstr "Fjern profilbillede" msgid "Remove background" msgstr "Fjern baggrund" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Fjern banner" @@ -26625,10 +26611,10 @@ msgstr "SlĂ„ altid Ăžverst fra" msgid "Remove from URL-only GIF favorites" msgstr "Fjern fra URL-baserede GIF-favoritter" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Fjern ikon" @@ -27331,7 +27317,7 @@ msgstr "Sendt igen" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Nulstil" @@ -28074,7 +28060,7 @@ msgstr "RumĂŠnsk" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Roter med uret" @@ -28153,8 +28139,8 @@ msgstr "MĂŠtning" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Indstillinger for videokodning ved skĂŠrmdeling" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "SkĂŠrmdeling afsluttet" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Vis et rĂždt badge pĂ„ appikonet, nĂ„r du har ulĂŠste beskeder" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Vis kun accentfarve, ignorer din globale profil" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Vis tilpassede emojis i autofuldfĂžrelse af udtryk" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Vis standardavatar, ignorer din globale profil" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Vis indikator for ulĂŠste beskeder i kanaler sat pĂ„ lydlĂžs" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Vis din globale profilavatar i dette fĂŠllesskab" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Vis dit globale profilbanner i dette fĂŠllesskab" @@ -30720,7 +30706,7 @@ msgstr "Spring over" msgid "Skip \"Mark all as read\" confirmation" msgstr "Spring \"MarkĂ©r alle som lĂŠst\"-bekrĂŠftelse over" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Spring beskĂŠring over" @@ -32346,7 +32332,7 @@ msgstr "Skift til rummeligt layout" msgid "Switch to dense layout" msgstr "Skift til kompakt visning" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Skift til direkte input" @@ -32734,7 +32720,7 @@ msgstr "Opgaver" msgid "Teleporting you to another voice region..." msgstr "Flytter dig til en anden taleregion
" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Skabelon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rollen gav {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "SkĂŠrmdelingskilden er stoppet med at sende video, sĂ„ din skĂŠrmdeling blev stoppet." @@ -33453,6 +33439,11 @@ msgstr "Denne konto kan ikke blokeres." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Denne handling kan ikke fortrydes. Alle tilknyttede data, inklusive botbrugeren, slettes permanent." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Denne animation er for lang eller for stor til at beskĂŠre. PrĂžv en kortere eller mindre fil." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Denne bot er ikke offentlig og kan ikke tilfĂžjes af andre brugere." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Denne bot anmoder om administratorrettigheder. Giv kun adgang, hvis du har fuld tillid til udvikleren. Bed dem i stedet om at anmode om fĂŠrre tilladelser. Luk denne side, hvis du er i tvivl." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Denne browser kan ikke beskĂŠre animerede {avifFormatLabel}-filer. Upload en GIF eller WebP i stedet." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Denne browserkonsol er et udviklervĂŠrktĂžj." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Denne browser har WebAssembly slĂ„et fra, sĂ„ animerede billeder kan ikke beskĂŠres." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Denne gruppe er fuld. Fjern en person, fĂžr du tilfĂžjer flere." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Denne overdragelseskode er udlĂžbet. Generer en ny for at fortsĂŠtte." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Dette billede kunne ikke lĂŠses. Det er muligvis beskadiget." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Upload" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Upload et brugerdefineret avatarbillede til dette fĂŠllesskab" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Upload et brugerdefineret banner til dette fĂŠllesskab" @@ -36155,10 +36163,10 @@ msgstr "Upload filer og medier i beskeder." msgid "Upload files and media in this channel." msgstr "Upload filer og medier i denne kanal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Upload ikon" @@ -36401,8 +36409,8 @@ msgstr "Brug kulsort tema (kulsorte overflader)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Brug et tilpasset billede" @@ -36462,8 +36470,8 @@ msgstr "Brug filtre eller indtast sĂžgeord for at finde beskeder" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Brug global profil" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Deltagere i taleopkald" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Talebehandling" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Med {PREMIUM_PRODUCT_NAME} kan du bruge animerede avatarer ({ANIMATED_AVATAR_FORMATS}) og profilbannere, tilpasse dit tag og lĂ„se op for mange andre {PREMIUM_PRODUCT_NAME}-fordele." @@ -39334,8 +39342,8 @@ msgstr "Du skal have tilladelsen \"{permissionLabel}\" for at bruge emojis fra a msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Du skal have tilladelsen \"{permissionLabel}\" for at bruge klistermĂŠrker fra andre fĂŠllesskaber her." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Du skal fuldfĂžre oprettelsen af din konto, fĂžr du kan oprette et fĂŠllesskab." @@ -39356,8 +39364,8 @@ msgstr "Du skal fuldfĂžre oprettelsen af din konto for at sende beskeder i dette msgid "You need to verify a phone number to send messages in this community." msgstr "Du skal bekrĂŠfte et telefonnummer for at sende beskeder i dette fĂŠllesskab." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Du skal bekrĂŠfte din e-mailadresse, fĂžr du kan oprette et fĂŠllesskab." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Din gemte {savedResolution} med {savedFrameRate} FPS krĂŠver {premiumProductName}, sĂ„ delinger bruger {resolution} med {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Din skĂŠrmdeling kunne ikke sendes med et kompatibelt videokodek, sĂ„ den blev stoppet. PrĂžv at dele igen." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Dit brugerdefinerede invitationslink er nu {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Din video-encoder stoppede med at kode billeder, sĂ„ din skĂŠrmdeling blev stoppet. PrĂžv at dele igen." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/de/messages.po b/fluxer_app/src/features/i18n/locales/de/messages.po index 23c285800..435094155 100644 --- a/fluxer_app/src/features/i18n/locales/de/messages.po +++ b/fluxer_app/src/features/i18n/locales/de/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, bald verfĂŒgbar" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Die Abmessungen von {label} passen nicht zu diesem Asset. WĂ€hle ein anderes Bild oder lade ein statisches Bild hoch, das du zuschneiden kannst." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Die Datei \"{label}\" ist zu groß. WĂ€hle eine Datei, die kleiner als {maxSizeLabel} ist." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label}-Bilder dĂŒrfen nicht animiert sein. Verwende ein statisches Bild." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "AktivitĂ€tsfreigabe" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "AktivitĂ€tsschwelle" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention} und {hereMention} erlauben" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Erlaube {PRODUCT_NAME} unter {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME} den Zugriff auf deine Kamera." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Erlaube {PRODUCT_NAME} den Zugriff auf dein Mikrofon in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Erlaube {PRODUCT_NAME}, auf dein Mikrofon zuzugreifen. ÜberprĂŒfe die Adressleiste oder die Einstellungen deines Browsers." @@ -3673,7 +3668,7 @@ msgstr "Erlaube Mitgliedern ohne die Berechtigung „{readMessageHistoryPermissi msgid "Allow mentions for this role" msgstr "ErwĂ€hnungen fĂŒr diese Rolle zulassen" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Mikrofonzugriff erlauben" @@ -3942,25 +3937,21 @@ msgstr "und {remainingCount} weitere" msgid "Animate on interaction" msgstr "Animation bei Interaktion" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animierte {AVIF_FORMAT_LABEL}-Dateien werden nicht unterstĂŒtzt. Lade stattdessen eine statische {AVIF_FORMAT_LABEL}-Datei hoch." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animiertes {avifFormatLabel} wird nicht unterstĂŒtzt" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animierte Avatare ({ANIMATED_AVATAR_FORMATS}) sind exklusiv fĂŒr {PREMIUM_PRODUCT_NAME}-Abonnenten verfĂŒgbar." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animierte Avatare ({ANIMATED_AVATAR_FORMATS}) sind auf dieser Instanz nicht verfĂŒgbar. Lade stattdessen ein statisches Bild hoch." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animierte Avatare ({animatedAvatarFormats}) erfordern {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animierte Avatare und Profilbanner" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animierte Avatare nicht verfĂŒgbar" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animierte Avatare erfordern {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Vorschau des animierten Bildes" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animierte Bilder werden fĂŒr dieses Asset nicht unterstĂŒtzt." @@ -4947,7 +4938,7 @@ msgstr "Sprache automatisch erkennen" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "AktivitĂ€tsschwelle automatisch festlegen" @@ -5127,15 +5118,15 @@ msgstr "VerfĂŒgbar in der Desktop-App." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Die Avatar-Datei ist zu groß. WĂ€hle eine Datei, die kleiner als {imageMaxSizeLabel} ist." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Der Avatar ist zu groß – wĂ€hle ein Bild unter {imageMaxSizeLabel} aus." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avatar-Modus auswĂ€hlen" @@ -5187,11 +5178,11 @@ msgstr "Gerade abwesend" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Gebannte Nutzer" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Die Bannerdatei ist zu groß. WĂ€hle eine Datei, die kleiner als {imageMaxSizeLabel} ist." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Bannermodus auswĂ€hlen" @@ -6107,8 +6098,8 @@ msgstr "Kaufe ein {premiumProductName}-Geschenk im Tab „{premiumProductName} msgid "Buy gift" msgstr "Geschenk kaufen" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Durch das Erstellen einer Community stimmst du zu, die <0>Community-Richtlinien von {PRODUCT_NAME} zu befolgen und einzuhalten." @@ -6361,7 +6352,7 @@ msgstr "Dateien können hier nicht hochgeladen werden" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Zentriert" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Profilbild Ă€ndern" @@ -6627,9 +6618,9 @@ msgstr "Hintergrund Ă€ndern" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Banner Ă€ndern" @@ -6668,13 +6659,13 @@ msgstr "Spitznamen in der Gruppe Ă€ndern" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Symbol Ă€ndern" @@ -7669,8 +7660,8 @@ msgstr "Geschenk einlösen" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Deinen Account beanspruchen" @@ -8518,8 +8509,8 @@ msgstr "Community fördert kollektive Angriffe oder gezielte BelĂ€stigung." msgid "Community filter" msgstr "Community-Filter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Community-Icon" @@ -8763,6 +8754,11 @@ msgstr "SchaltflĂ€chen der Nachrichteneingabe" msgid "Composer focus" msgstr "Fokus auf Nachrichteneingabe" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimieren" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Schließe eine Kamera oder ein virtuelles AufnahmegerĂ€t an und versuche msgid "Connect a display, then try again." msgstr "Schließe einen Bildschirm an und versuche es erneut." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Verbinde ein Mikrofon und versuche es erneut." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Sticker konnte nicht erstellt werden" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Bild konnte nicht zugeschnitten werden" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Freigabe der SprachaktivitĂ€t konnte derzeit nicht aktualisiert werden" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Avatar konnte nicht hochgeladen werden" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Banner konnte nicht hochgeladen werden" @@ -10230,7 +10226,7 @@ msgstr "Erstellen & teilen" msgid "Create a community" msgstr "Community erstellen" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Erstelle eine Community, in der du und deine Freunde chatten können." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Einladungshintergrund zuschneiden" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Vorschau zuschneiden" @@ -10500,30 +10496,15 @@ msgstr "Profilbanner zuschneiden" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Das zugeschnittene Bild ist zu groß. WĂ€hle einen kleineren Bereich oder eine kleinere Datei (max. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Das Zuschneiden von animierten {formatLabel}-Dateien wird noch nicht unterstĂŒtzt. Das Originalbild wird verwendet." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Das Zuschneiden von animierten {formatLabel}-Dateien wird noch nicht unterstĂŒtzt. Der ursprĂŒngliche Upload wird verwendet." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Das Zuschneiden animierter Dateien wird noch nicht unterstĂŒtzt. Das Originalbild wird verwendet." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Das Zuschneiden animierter Dateien wird noch nicht unterstĂŒtzt. Es wird der ursprĂŒngliche Upload verwendet." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Zuschneiden von {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Du hast noch keinen Account?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Nicht anzeigen" @@ -16560,8 +16541,8 @@ msgstr "Gruppen-DM-Avatare verwenden dieselben Statusmasken wie normale Avatare, msgid "Group DMs" msgstr "Gruppen-DMs" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Gruppensymbol" @@ -16624,8 +16605,8 @@ msgstr "Gruppeneinstellungen" msgid "Group typing states" msgstr "Gruppen-Tippstatus" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Gruppe aktualisiert" @@ -16803,7 +16784,7 @@ msgstr "Herz" msgid "Hebrew" msgstr "HebrĂ€isch" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Höhe" @@ -17510,7 +17491,7 @@ msgstr "Bild in Zwischenablage kopiert" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Bild konnte nicht verwendet werden" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Aussehen und Verhalten" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Es sieht so aus, als wĂŒrdest du {0} verwenden. Wenn du die Verarbeitung von {PRODUCT_NAME} zusĂ€tzlich aktivierst, kann dies zu Pumpen oder Verzerrungen fĂŒhren. Eine direkte Eingabe leitet dein Audio unverĂ€ndert weiter." @@ -22577,7 +22558,7 @@ msgstr "Keine Treffer gefunden" msgid "No mentions yet" msgstr "Noch keine ErwĂ€hnungen" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Kein Mikrofon gefunden" @@ -23806,7 +23787,7 @@ msgstr "System-DM öffnen" msgid "Open system picker" msgstr "Systemauswahl öffnen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Vorlagen-JSON öffnen" @@ -23820,7 +23801,7 @@ msgstr "Banndialog fĂŒr diese Community öffnen." msgid "Open the context menu" msgstr "KontextmenĂŒ öffnen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Öffne den Link unten in deinem Browser, kopiere dann die gesamte JSON-Antwort und fĂŒge sie in das Feld ein." @@ -24331,7 +24312,7 @@ msgstr "Letzte 7 Tage" msgid "Paste" msgstr "EinfĂŒgen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "FĂŒge eine {theOtherPlatform}-Vorlagen-URL ein, um ihre Struktur in eine neue Community zu importieren." @@ -25191,6 +25172,11 @@ msgstr "Premium-Typ" msgid "Premium until date" msgstr "Premium bis" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Vorbereiten" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Profilabzeichen" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profilbanner sind eine {PREMIUM_PRODUCT_NAME}-Funktion. Mit {PREMIUM_PRODUCT_NAME} kannst du deinem Profil ein Banner hinzufĂŒgen." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profilbanner sind auf dieser Instanz nicht aktiviert." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "FĂŒr Profilbanner ist {premiumProductName} erforderlich" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profilbanner erfordern {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-Talk" msgid "Push-to-talk (limited)" msgstr "Push-to-Talk (begrenzt)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-Talk wird bei direkter Eingabe ignoriert. Wechsle zu „Fokussierter Sprachchat“ oder „Benutzerdefiniert“, um es zu verwenden." @@ -26551,8 +26537,8 @@ msgstr "Anhang entfernen" msgid "Remove authenticator app" msgstr "Authenticator-App entfernen" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Profilbild entfernen" @@ -26561,8 +26547,8 @@ msgstr "Profilbild entfernen" msgid "Remove background" msgstr "Hintergrund entfernen" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Banner entfernen" @@ -26625,10 +26611,10 @@ msgstr "Nicht mehr obenan anzeigen" msgid "Remove from URL-only GIF favorites" msgstr "Aus der Liste der per URL gespeicherten GIFs entfernen" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Symbol entfernen" @@ -27331,7 +27317,7 @@ msgstr "Erneut gesendet" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ZurĂŒcksetzen" @@ -28074,7 +28060,7 @@ msgstr "RumĂ€nisch" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Im Uhrzeigersinn drehen" @@ -28153,8 +28139,8 @@ msgstr "SĂ€ttigung" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Encoder-Einstellungen fĂŒr die Bildschirmfreigabe" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Bildschirmfreigabe beendet" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Rotes Badge auf dem App-Icon bei ungelesenen Nachrichten anzeigen" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Nur Akzentfarbe anzeigen, globale Profileinstellungen ignorieren" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Eigene Emojis in der AusdrucksvervollstĂ€ndigung anzeigen" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Standard-Avatar anzeigen, globales Profil ignorieren" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Markierung fĂŒr ungelesene Nachrichten bei stummgeschalteten KanĂ€len anzeigen" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Zeige dein globales Profilbild in dieser Community" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Zeige dein globales Profilbanner in dieser Community" @@ -30720,7 +30706,7 @@ msgstr "Überspringen" msgid "Skip \"Mark all as read\" confirmation" msgstr "BestĂ€tigung fĂŒr \"Alle als gelesen markieren\" ĂŒberspringen" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Zuschneiden ĂŒberspringen" @@ -32346,7 +32332,7 @@ msgstr "Zu \"Komfortabel\" wechseln" msgid "Switch to dense layout" msgstr "Zu kompakter Ansicht wechseln" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Direkte Eingabe nutzen" @@ -32734,7 +32720,7 @@ msgstr "Aufgaben" msgid "Teleporting you to another voice region..." msgstr "Wird zu einer anderen Sprachregion teleportiert 
" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Vorlage" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Die Rolle gewĂ€hrte {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Die Quelle der Bildschirmfreigabe hat keine Videodaten mehr gesendet. Deshalb wurde deine Bildschirmfreigabe beendet." @@ -33453,6 +33439,11 @@ msgstr "Dieser Account kann nicht blockiert werden." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Diese Aktion kann nicht rĂŒckgĂ€ngig gemacht werden. Alle zugehörigen Daten, einschließlich des Bot-Benutzers, werden dauerhaft gelöscht." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Diese Animation ist zu lang oder zu groß zum Zuschneiden. Versuche es mit einer kĂŒrzeren oder kleineren Datei." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Dieser Bot ist nicht öffentlich und kann nicht von anderen Nutzern hinz msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Dieser Bot fordert die Administratorberechtigung an. Erteile sie nur, wenn du dem Entwickler vollstĂ€ndig vertraust. Bitte ihn stattdessen, weniger Berechtigungen anzufordern. Schließe diese Seite, wenn du unsicher bist." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Dieser Browser kann keine animierten {avifFormatLabel}-Dateien zuschneiden. Lade stattdessen eine GIF- oder WebP-Datei hoch." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Diese Browser-Konsole ist ein Entwickler-Tool." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "In diesem Browser ist WebAssembly deaktiviert, daher können animierte Bilder nicht zugeschnitten werden." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Diese Gruppe ist voll. Entferne jemanden, bevor du weitere Personen hinz msgid "This handoff code has expired. Generate a new one to continue." msgstr "Dieser Übergabecode ist abgelaufen. Erstelle einen neuen, um fortzufahren." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Dieses Bild konnte nicht gelesen werden. Es ist möglicherweise beschĂ€digt." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Hochladen" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Lade ein eigenes Profilbild fĂŒr diese Community hoch" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Lade ein eigenes Banner fĂŒr diese Community hoch" @@ -36155,10 +36163,10 @@ msgstr "Dateien und Medien in Nachrichten hochladen." msgid "Upload files and media in this channel." msgstr "Dateien und Medien in diesem Kanal hochladen." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Symbol hochladen" @@ -36401,8 +36409,8 @@ msgstr "Kohlrabenschwarz (pechschwarze OberflĂ€chen)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Eigenes Bild verwenden" @@ -36462,8 +36470,8 @@ msgstr "Nachrichten mit Filtern oder Stichwörtern finden" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Globales Profil verwenden" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Sprachchat-Teilnehmer" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Sprachverarbeitung" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Mit {PREMIUM_PRODUCT_NAME} kannst du animierte Avatare ({ANIMATED_AVATAR_FORMATS}) und Profilbanner verwenden, deinen Tag anpassen und viele weitere {PREMIUM_PRODUCT_NAME}-Vorteile freischalten." @@ -39334,8 +39342,8 @@ msgstr "Du benötigst die Berechtigung \"{permissionLabel}\", um hier Emojis aus msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Du benötigst die Berechtigung \"{permissionLabel}\", um hier Sticker aus anderen Communitys zu verwenden." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Du musst zuerst deinen Account beanspruchen, bevor du eine Community erstellen kannst." @@ -39356,8 +39364,8 @@ msgstr "Du musst deinen Account beanspruchen, um Nachrichten in dieser Community msgid "You need to verify a phone number to send messages in this community." msgstr "Du musst eine Telefonnummer verifizieren, um Nachrichten in dieser Community senden zu können." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Du musst deine E-Mail-Adresse bestĂ€tigen, bevor du eine Community erstellen kannst." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Deine gespeicherte {savedResolution} mit {savedFrameRate} FPS benötigt {premiumProductName}, daher werden Shares mit {resolution} mit {frameRate} FPS verwendet." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Deine Bildschirmfreigabe konnte nicht mit einem kompatiblen Videocodec veröffentlicht werden und wurde daher beendet. Versuche es erneut." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Deine Vanity-URL wurde auf {inviteEndpoint}/{vanitySlug} festgelegt" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Dein Video-Encoder hat aufgehört, Frames zu kodieren, daher wurde deine Bildschirmfreigabe beendet. Versuche es erneut." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoomen" diff --git a/fluxer_app/src/features/i18n/locales/el/messages.po b/fluxer_app/src/features/i18n/locales/el/messages.po index bb509dcbd..5ee4dd521 100644 --- a/fluxer_app/src/features/i18n/locales/el/messages.po +++ b/fluxer_app/src/features/i18n/locales/el/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, ÏƒÏÎœÏ„ÎżÎŒÎ± ÎŽÎčαΞέσÎčÎŒÎż" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "ΟÎč ÎŽÎčÎ±ÏƒÏ„ÎŹÏƒÎ”Îčς ÎłÎčα {label} ΎΔΜ ταÎčρÎčÎŹÎ¶ÎżÏ…Îœ ΌΔ αυτό Ï„Îż ÏƒÏ„ÎżÎčÏ‡Î”ÎŻÎż. ΕπÎčλέΟτΔ ÎŽÎčÎ±Ï†ÎżÏÎ”Ï„ÎčÎșÎź ΔÎčÎșόΜα Îź αΜΔÎČÎŹÏƒÏ„Î” ÎŒÎčα στατÎčÎșÎź ΔÎčÎșόΜα Ï€ÎżÏ… ÎŒÏ€ÎżÏÎ”ÎŻÏ„Î” Μα πΔρÎčÎșόψΔτΔ." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "΀ο Î±ÏÏ‡Î”ÎŻÎż {label} Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż. ΕπÎčλέΟτΔ έΜα Î±ÏÏ‡Î”ÎŻÎż ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż από {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "ΟÎč ΔÎčÎșόΜΔς ÎłÎčα {label} ΎΔΜ ÎŒÏ€ÎżÏÎżÏÎœ Μα Î”ÎŻÎœÎ±Îč ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ”Ï‚. ΧρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÏ„Î” ÎŒÎčα στατÎčÎșÎź ΔÎčÎșόΜα." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "ΚοÎčÎœÎź Ï‡ÏÎźÏƒÎ· ΎραστηρÎčÎżÏ„ÎźÏ„Ï‰Îœ" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "ΌρÎčÎż ΎραστηρÎčότητας" @@ -3566,11 +3561,11 @@ msgstr "Να ΔπÎčÏ„ÏÎ­Ï€ÎżÎœÏ„Î±Îč ÎżÎč Î±ÎœÎ±Ï†ÎżÏÎ­Ï‚ {everyoneMention} Îș msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "ΕπÎčτρέψτΔ ÏƒÏ„Îż {PRODUCT_NAME} Μα έχΔÎč πρόσÎČαση στηΜ ÎșÎŹÎŒÎ”ÏÎŹ σας στÎčς {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "ΕπÎčτρέψτΔ ÏƒÏ„Îż {PRODUCT_NAME} Μα έχΔÎč πρόσÎČαση ÏƒÏ„Îż ÎŒÎčÎșρόφωΜό σας στÎčς {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "ΕπÎčτρέψτΔ ÏƒÏ„Îż {PRODUCT_NAME} Μα έχΔÎč πρόσÎČαση ÏƒÏ„Îż ÎŒÎčÎșρόφωΜό σας. Î•Î»Î­ÎłÎŸÏ„Î” τη ÎłÏÎ±ÎŒÎŒÎź ÎŽÎčΔυΞύΜσΔωΜ Îź τÎčς ÏÏ…ÎžÎŒÎŻÏƒÎ”Îčς Ï„ÎżÏ… Ï€ÏÎżÎłÏÎŹÎŒÎŒÎ±Ï„ÎżÏ‚ πΔρÎčÎźÎłÎ·ÏƒÎźÏ‚ σας." @@ -3673,7 +3668,7 @@ msgstr "Να ΔπÎčτρέπΔταÎč στα Όέλη Ï‡Ï‰ÏÎŻÏ‚ Ï„Îż ÎŽÎčÎșÎ±ÎŻÏ‰ msgid "Allow mentions for this role" msgstr "Να ΔπÎčÏ„ÏÎ­Ï€ÎżÎœÏ„Î±Îč ÎżÎč Î±ÎœÎ±Ï†ÎżÏÎ­Ï‚ ÎłÎčα αυτόΜ Ï„ÎżÎœ ÏÏŒÎ»Îż" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Να ΔπÎčτρέπΔταÎč Ï„Îż ÎŒÎčÎșÏÏŒÏ†Ï‰ÎœÎż" @@ -3942,25 +3937,21 @@ msgstr "ÎșαÎč {remainingCount} αÎșόΌη" msgid "Animate on interaction" msgstr "Εφέ ÎșÎŻÎœÎ·ÏƒÎ·Ï‚ στηΜ Î±Î»Î»Î·Î»Î”Ï€ÎŻÎŽÏÎ±ÏƒÎ·" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± Î±ÏÏ‡Î”ÎŻÎ± {AVIF_FORMAT_LABEL} ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶ÎżÎœÏ„Î±Îč. ΑΜΔÎČÎŹÏƒÏ„Î” έΜα στατÎčÎșό Î±ÏÏ‡Î”ÎŻÎż {AVIF_FORMAT_LABEL} αΜτ' Î±Ï…Ï„ÎżÏ." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± {avifFormatLabel} ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶ÎżÎœÏ„Î±Îč" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ({ANIMATED_AVATAR_FORMATS}) Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčΌα Î±Ï€ÎżÎșλΔÎčστÎčÎșÎŹ ÏƒÏ„ÎżÏ…Ï‚ ÏƒÏ…ÎœÎŽÏÎżÎŒÎ·Ï„Î­Ï‚ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ({ANIMATED_AVATAR_FORMATS}) ΎΔΜ Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčΌα σΔ Î±Ï…Ï„ÎźÎœ τηΜ Ï€Î±ÏÎżÏ…ÏƒÎŻÎ±. ΑΜΔÎČÎŹÏƒÏ„Î” ÎŒÎčα στατÎčÎșÎź ΔÎčÎșόΜα αΜτ' Î±Ï…Ï„ÎżÏ." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ({animatedAvatarFormats}) απαÎčÏ„ÎżÏÎœ {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ΚÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ÎșαÎč banner Ï€ÏÎżÏ†ÎŻÎ»" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ΎΔΜ Î”ÎŻÎœÎ±Îč ÎŽÎčαΞέσÎčΌα" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "΀α ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar απαÎčÏ„ÎżÏÎœ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Î ÏÎżÎ”Ï€ÎčσÎșόπηση ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ·Ï‚ ΔÎčÎșόΜας" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ΟÎč ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ”Ï‚ ΔÎčÎșόΜΔς ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶ÎżÎœÏ„Î±Îč ÎłÎčα αυτό Ï„Îż ÏƒÏ„ÎżÎčÏ‡Î”ÎŻÎż." @@ -4947,7 +4938,7 @@ msgstr "ΑυτόΌατη Î±ÎœÎŻÏ‡ÎœÎ”Ï…ÏƒÎ· ÎłÎ»ÏŽÏƒÏƒÎ±Ï‚" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "ΑυτόΌατη ρύΞΌÎčση ÎżÏÎŻÎżÏ… ΎραστηρÎčότητας" @@ -5127,15 +5118,15 @@ msgstr "ΔÎčαΞέσÎčÎŒÎż στηΜ Î”Ï†Î±ÏÎŒÎżÎłÎź ÎłÎčα Ï…Ï€ÎżÎ»ÎżÎłÎčστέ #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "ΕÎčÎșόΜα Ï€ÏÎżÏ†ÎŻÎ»" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "΀ο Î±ÏÏ‡Î”ÎŻÎż avatar Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż. ΕπÎčλέΟτΔ έΜα Î±ÏÏ‡Î”ÎŻÎż ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż από {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "΀ο avatar Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż. ΕπÎčλέΟτΔ έΜα ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż από {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "ΕπÎčλογΟ λΔÎčÏ„ÎżÏ…ÏÎłÎŻÎ±Ï‚ avatar" @@ -5187,11 +5178,11 @@ msgstr "ΑπώΜ τώρα" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Î‘Ï€ÎżÎșλΔÎčÏƒÎŒÎ­ÎœÎżÎč Ï‡ÏÎźÏƒÏ„Î”Ï‚" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "΀ο Î±ÏÏ‡Î”ÎŻÎż Ï„ÎżÏ… banner Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż. ΕπÎčλέΟτΔ έΜα Î±ÏÏ‡Î”ÎŻÎż ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż από {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "ΕπÎčλογΟ λΔÎčÏ„ÎżÏ…ÏÎłÎŻÎ±Ï‚ banner" @@ -6107,8 +6098,8 @@ msgstr "Î‘ÎłÎżÏÎŹÏƒÏ„Î” έΜα ÎŽÏŽÏÎż {premiumProductName} από τηΜ Îșα msgid "Buy gift" msgstr "Î‘ÎłÎżÏÎŹ ÎŽÏŽÏÎżÏ…" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ΔηΌÎčÎżÏ…ÏÎłÏŽÎœÏ„Î±Ï‚ ÎŒÎčα ÎșÎżÎčΜότητα, ÏƒÏ…ÎŒÏ†Ï‰ÎœÎ”ÎŻÏ„Î” Μα αÎșÎżÎ»ÎżÏ…ÎžÎ”ÎŻÏ„Î” ÎșαÎč Μα Ï„Î·ÏÎ”ÎŻÏ„Î” τÎčς <0>ÎżÎŽÎ·ÎłÎŻÎ”Ï‚ ÎșÎżÎčΜότητας Ï„ÎżÏ… {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "ΔΔΜ ÎŒÏ€ÎżÏÎ”ÎŻÏ„Î” Μα αΜΔÎČÎŹÏƒÎ”Ï„Î” Î±ÏÏ‡Î”ÎŻÎ± ΔΎώ" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ÎŁÏ„Îż ÎșÎ­ÎœÏ„ÏÎż" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ΑλλαγΟ avatar" @@ -6627,9 +6618,9 @@ msgstr "ΑλλαγΟ Ï†ÏŒÎœÏ„ÎżÏ…" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "ΑλλαγΟ banner" @@ -6668,13 +6659,13 @@ msgstr "ΑλλαγΟ ÏˆÎ”Ï…ÎŽÏŽÎœÏ…ÎŒÎżÏ… στηΜ ÎżÎŒÎŹÎŽÎ±" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "ΑλλαγΟ ΔÎčÎșÎżÎœÎčÎŽÎŻÎżÏ…" @@ -7669,8 +7660,8 @@ msgstr "ΠαραλαÎČÎź ÎŽÏŽÏÎżÏ…" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "ΔÎčΔÎșÎŽÎčÎșÎźÏƒÏ„Î” Ï„ÎżÎœ Î»ÎżÎłÎ±ÏÎčασΌό σας" @@ -8518,8 +8509,8 @@ msgstr "Η ÎșÎżÎčΜότητα ÎŽÎčΔυÎșÎżÎ»ÏÎœÎ”Îč τÎčς ÎżÎŒÎ±ÎŽÎčÎșές Δ msgid "Community filter" msgstr "ÎŠÎŻÎ»Ï„ÏÎż ÎșÎżÎčΜότητας" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ΕÎčÎșÎżÎœÎŻÎŽÎčÎż ÎșÎżÎčΜότητας" @@ -8763,6 +8754,11 @@ msgstr "ÎšÎżÏ…ÎŒÏ€ÎčÎŹ σύΜταΟης" msgid "Composer focus" msgstr "Î•ÏƒÏ„ÎŻÎ±ÏƒÎ· ÏƒÏ„Îż Ï€Î”ÎŽÎŻÎż σύΜταΟης" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "ÎŁÏ…ÎŒÏ€ÎŻÎ”ÏƒÎ·" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ÎŁÏ…ÎœÎŽÎ­ÏƒÏ„Î” ÎŒÎčα ÎșÎŹÎŒÎ”ÏÎ± Îź ÎŒÎčα συσÎșÎ”Ï…Îź ΔÎčÎșÎżÎœ msgid "Connect a display, then try again." msgstr "ÎŁÏ…ÎœÎŽÎ­ÏƒÏ„Î” ÎŒÎčα ÎżÎžÏŒÎœÎ· ÎșαÎč ÎŽÎżÎșÎčÎŒÎŹÏƒÏ„Î” ÎŸÎ±ÎœÎŹ." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ÎŁÏ…ÎœÎŽÎ­ÏƒÏ„Î” έΜα ÎŒÎčÎșÏÏŒÏ†Ï‰ÎœÎż ÎșαÎč ÎŽÎżÎșÎčÎŒÎŹÏƒÏ„Î” ÎŸÎ±ÎœÎŹ." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ΔΔΜ ÎźÏ„Î±Îœ ÎŽÏ…ÎœÎ±Ï„Îź η ΎηΌÎčÎżÏ…ÏÎłÎŻÎ± Î±Ï…Ï„ÎżÏ Ï„ÎżÏ… Î±Ï…Ï„ÎżÎșÏŒÎ»Î»Î·Ï„ÎżÏ…" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ΔΔΜ ÎźÏ„Î±Îœ ÎŽÏ…ÎœÎ±Ï„Îź η πΔρÎčÎșÎżÏ€Îź της ΔÎčÎșόΜας" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ΔΔΜ ÎźÏ„Î±Îœ ÎŽÏ…ÎœÎ±Ï„Îź η ΔΜηΌέρωση της ÎșÎżÎčÎœÎżÏ€ÎżÎŻÎ·ÏƒÎ·Ï‚ φωΜητÎčÎșÎźÏ‚ ΎραστηρÎčότητας Î±Ï…Ï„Îź τη στÎčÎłÎŒÎź" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ΔΔΜ ÎźÏ„Î±Îœ ÎŽÏ…ÎœÎ±Ï„Îź η ΌΔταφόρτωση της ΔÎčÎșόΜας Ï€ÏÎżÏ†ÎŻÎ»" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ΔΔΜ ÎźÏ„Î±Îœ ÎŽÏ…ÎœÎ±Ï„Îź η ΌΔταφόρτωση της ΔÎčÎșόΜας Î”ÎŸÏ‰Ï†ÏÎ»Î»ÎżÏ…" @@ -10230,7 +10226,7 @@ msgstr "ΔηΌÎčÎżÏ…ÏÎłÎŻÎ± ÎșαÎč ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ·" msgid "Create a community" msgstr "ΔηΌÎčÎżÏ…ÏÎłÎŻÎ± ÎșÎżÎčΜότητας" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ΔηΌÎčÎżÏ…ÏÎłÎźÏƒÏ„Î” ÎŒÎčα ÎșÎżÎčΜότητα ÎłÎčα Μα ÏƒÏ…ÎœÎżÎŒÎčÎ»Î”ÎŻÏ„Î” ΌΔ Ï„ÎżÏ…Ï‚ Ï†ÎŻÎ»ÎżÏ…Ï‚ σας." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "ΠΔρÎčÎșÎżÏ€Îź Ï†ÏŒÎœÏ„ÎżÏ… πρόσÎșλησης" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Î ÏÎżÎ”Ï€ÎčσÎșόπηση πΔρÎčÎșÎżÏ€ÎźÏ‚" @@ -10500,30 +10496,15 @@ msgstr "ΠΔρÎčÎșÎżÏ€Îź banner Ï€ÏÎżÏ†ÎŻÎ»" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Η πΔρÎčÎșÎżÎŒÎŒÎ­ÎœÎ· ΔÎčÎșόΜα Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Î·. ΕπÎčλέΟτΔ ÎŒÎčα ÎŒÎčÎșρότΔρη πΔρÎčÎżÏ‡Îź Îź έΜα ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż Î±ÏÏ‡Î”ÎŻÎż (ÎŒÎ­Îł. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Η πΔρÎčÎșÎżÏ€Îź ÎșÎčÎœÎżÏÎŒÎ”ÎœÏ‰Îœ Î±ÏÏ‡Î”ÎŻÏ‰Îœ {formatLabel} ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶Î”Ï„Î±Îč αÎșόΌα. Θα χρησÎčÎŒÎżÏ€ÎżÎčηΞΔί η αρχÎčÎșÎź ΔÎčÎșόΜα." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Η πΔρÎčÎșÎżÏ€Îź ÎșÎčÎœÎżÏÎŒÎ”ÎœÏ‰Îœ Î±ÏÏ‡Î”ÎŻÏ‰Îœ {formatLabel} ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶Î”Ï„Î±Îč αÎșόΌα. Θα χρησÎčÎŒÎżÏ€ÎżÎčηΞΔί η αρχÎčÎșÎź ΌΔταφόρτωση." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Η πΔρÎčÎșÎżÏ€Îź ÎșÎčÎœÎżÏÎŒÎ”ÎœÏ‰Îœ Î±ÏÏ‡Î”ÎŻÏ‰Îœ ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶Î”Ï„Î±Îč αÎșόΌα. Θα χρησÎčÎŒÎżÏ€ÎżÎčηΞΔί η αρχÎčÎșÎź ΔÎčÎșόΜα." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Η πΔρÎčÎșÎżÏ€Îź ÎșÎčÎœÎżÏÎŒÎ”ÎœÏ‰Îœ Î±ÏÏ‡Î”ÎŻÏ‰Îœ ΎΔΜ Ï…Ï€ÎżÏƒÏ„Î·ÏÎŻÎ¶Î”Ï„Î±Îč αÎșόΌα. Θα χρησÎčÎŒÎżÏ€ÎżÎčηΞΔί η αρχÎčÎșÎź ΌΔταφόρτωση." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "ÎšÎżÏ€Îź {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ΔΔΜ έχΔÎčς Î»ÎżÎłÎ±ÏÎčασΌό;" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Να ΌηΜ Î”ÎŒÏ†Î±ÎœÎŻÎ¶Î”Ï„Î±Îč" @@ -16560,8 +16541,8 @@ msgstr "΀α avatar ÎżÎŒÎ±ÎŽÎčÎșώΜ ÏƒÏ…ÎœÎżÎŒÎčλÎčώΜ χρησÎčÎŒÎżÏ€ÎżÎčÎż msgid "Group DMs" msgstr "ΟΌαΎÎčÎșές ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ”Ï‚" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ΕÎčÎșÎżÎœÎŻÎŽÎčÎż ÎżÎŒÎŹÎŽÎ±Ï‚" @@ -16624,8 +16605,8 @@ msgstr "ÎĄÏ…ÎžÎŒÎŻÏƒÎ”Îčς ÎżÎŒÎŹÎŽÎ±Ï‚" msgid "Group typing states" msgstr "ÎšÎ±Ï„Î±ÏƒÏ„ÎŹÏƒÎ”Îčς πληÎșÏ„ÏÎżÎ»ÏŒÎłÎ·ÏƒÎ·Ï‚ ÎżÎŒÎŹÎŽÎ±Ï‚" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Η ÎżÎŒÎŹÎŽÎ± ΔΜηΌΔρώΞηÎșΔ" @@ -16803,7 +16784,7 @@ msgstr "ΚαρΎÎčÎŹ" msgid "Hebrew" msgstr "ΕÎČραϊÎșÎŹ" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "ÎŽÏˆÎżÏ‚" @@ -17510,7 +17491,7 @@ msgstr "Η ΔÎčÎșόΜα αΜτÎčÎłÏÎŹÏ†Î·ÎșΔ ÏƒÏ„Îż πρόχΔÎčÏÎż" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Η ΔÎčÎșόΜα ΎΔΜ ÎźÏ„Î±Îœ ΎυΜατό Μα χρησÎčÎŒÎżÏ€ÎżÎčηΞΔί" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση ÎșαÎč Î±ÎŻÏƒÎžÎ·ÏƒÎ·" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ÎŠÎ±ÎŻÎœÎ”Ï„Î±Îč ότÎč χρησÎčÎŒÎżÏ€ÎżÎčÎ”ÎŻÏ„Î” {0}. Η Ï€ÏÎżÏƒÎžÎźÎșη της Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ±Ï‚ Ï„ÎżÏ… {PRODUCT_NAME} από Ï€ÎŹÎœÏ‰ ÎŒÏ€ÎżÏÎ”ÎŻ Μα Ï€ÏÎżÎșαλέσΔÎč ÎŽÎčαÎșÏ…ÎŒÎŹÎœÏƒÎ”Îčς έΜτασης Îź παραΌόρφωση. Η ÎŹÎŒÎ”ÏƒÎ· Î”ÎŻÏƒÎżÎŽÎżÏ‚ Ï€Î”ÏÎœÎŹÎ”Îč Ï„ÎżÎœ ÎźÏ‡Îż σας Ï‡Ï‰ÏÎŻÏ‚ Î”Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ±." @@ -22577,7 +22558,7 @@ msgstr "ΔΔΜ ÎČρέΞηÎșαΜ Î±Ï€ÎżÏ„Î”Î»Î­ÏƒÎŒÎ±Ï„Î±" msgid "No mentions yet" msgstr "ΔΔΜ Ï…Ï€ÎŹÏÏ‡ÎżÏ…Îœ Î±ÎœÎ±Ï†ÎżÏÎ­Ï‚ αÎșόΌα" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "ΔΔΜ ÎČρέΞηÎșΔ ÎŒÎčÎșÏÏŒÏ†Ï‰ÎœÎż" @@ -23806,7 +23787,7 @@ msgstr "Î†ÎœÎżÎčÎłÎŒÎ± DM ÏƒÏ…ÏƒÏ„ÎźÎŒÎ±Ï„ÎżÏ‚" msgid "Open system picker" msgstr "Î†ÎœÎżÎčÎłÎŒÎ± ΔπÎčλογέα ÏƒÏ…ÏƒÏ„ÎźÎŒÎ±Ï„ÎżÏ‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Î†ÎœÎżÎčÎłÎŒÎ± JSON Ï€ÏÎżÏ„ÏÏ€ÎżÏ…" @@ -23820,7 +23801,7 @@ msgstr "Î†ÎœÎżÎčÎłÎŒÎ± Ï„ÎżÏ… Ï€Î±ÏÎ±ÎžÏÏÎżÏ… ÎŽÎčÎ±Î»ÏŒÎłÎżÏ… Î±Ï€ÎżÎșλΔÎč msgid "Open the context menu" msgstr "Î†ÎœÎżÎčÎłÎŒÎ± Ï„ÎżÏ… ÎŒÎ”ÎœÎżÏ πΔρÎčÎČÎŹÎ»Î»ÎżÎœÏ„ÎżÏ‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Î‘ÎœÎżÎŻÎŸÏ„Î” Ï„ÎżÎœ παραÎșÎŹÏ„Ï‰ ÏƒÏÎœÎŽÎ”ÏƒÎŒÎż ÏƒÏ„Îż Ï€ÏÏŒÎłÏÎ±ÎŒÎŒÎ± πΔρÎčÎźÎłÎ·ÏƒÎźÏ‚ σας, ÎŒÎ”Ï„ÎŹ αΜτÎčÎłÏÎŹÏˆÏ„Î” ÎżÎ»ÏŒÎșληρη τηΜ απόÎșρÎčση JSON ÎșαÎč ΔπÎčÎșÎżÎ»Î»ÎźÏƒÏ„Î” τηΜ ÏƒÏ„Îż Ï€Î»Î±ÎŻÏƒÎčÎż." @@ -24331,7 +24312,7 @@ msgstr "Î€Î”Î»Î”Ï…Ï„Î±ÎŻÎ”Ï‚ 7 ηΌέρΔς" msgid "Paste" msgstr "ΕπÎčÎșόλληση" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "ΕπÎčÎșÎżÎ»Î»ÎźÏƒÏ„Î” έΜα URL Ï€ÏÎżÏ„ÏÏ€ÎżÏ… {theOtherPlatform} ÎłÎčα Μα ΔÎčÏƒÎ±ÎłÎŹÎłÎ”Ï„Î” τη ÎŽÎżÎŒÎź Ï„ÎżÏ… σΔ ÎŒÎčα Μέα ÎșÎżÎčΜότητα." @@ -25191,6 +25172,11 @@ msgstr "Î€ÏÏ€ÎżÏ‚ Premium" msgid "Premium until date" msgstr "Î—ÎŒÎ”ÏÎżÎŒÎ·ÎœÎŻÎ± Î»ÎźÎŸÎ·Ï‚ Premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Î•Ï„ÎżÎčÎŒÎ±ÏƒÎŻÎ±" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Î ÏÎżÏ†ÎŻÎ»" msgid "Profile badge" msgstr "ÎŁÎźÎŒÎ± Ï€ÏÎżÏ†ÎŻÎ»" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "΀α banner Ï€ÏÎżÏ†ÎŻÎ» Î”ÎŻÎœÎ±Îč λΔÎčÏ„ÎżÏ…ÏÎłÎŻÎ± Ï„ÎżÏ… {PREMIUM_PRODUCT_NAME}. Î‘Ï€ÎżÎșÏ„ÎźÏƒÏ„Î” Ï„Îż {PREMIUM_PRODUCT_NAME} ÎłÎčα Μα Ï€ÏÎżÏƒÎžÎ­ÏƒÎ”Ï„Î” banner ÏƒÏ„Îż Ï€ÏÎżÏ†ÎŻÎ» σας." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "΀α banner Ï€ÏÎżÏ†ÎŻÎ» ΎΔΜ Î”ÎŻÎœÎ±Îč Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčηΌέΜα σΔ Î±Ï…Ï„ÎźÎœ τηΜ Ï€Î±ÏÎżÏ…ÏƒÎŻÎ±." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "΀α banner Ï€ÏÎżÏ†ÎŻÎ» απαÎčÏ„ÎżÏÎœ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "΀α banner Ï€ÏÎżÏ†ÎŻÎ» απαÎčÏ„ÎżÏÎœ {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (πΔρÎčÎżÏÎčÏƒÎŒÎ­ÎœÎż)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Η λΔÎčÏ„ÎżÏ…ÏÎłÎŻÎ± push-to-talk Î±ÎłÎœÎżÎ”ÎŻÏ„Î±Îč στηΜ ÎŹÎŒÎ”ÏƒÎ· ΔÎčÏƒÎ±ÎłÏ‰ÎłÎź. ΜΔταÎČÎ”ÎŻÏ„Î” σΔ ΔστÎčασΌέΜη Ï†Ï‰ÎœÎź Îź Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÎ· ÎłÎčα Μα τη χρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÎ”Ï„Î”." @@ -26551,8 +26537,8 @@ msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· ÏƒÏ…ÎœÎ·ÎŒÎŒÎ­ÎœÎżÏ…" msgid "Remove authenticator app" msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· Î”Ï†Î±ÏÎŒÎżÎłÎźÏ‚ Î”Î»Î­ÎłÏ‡ÎżÏ… ταυτότητας" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· avatar" @@ -26561,8 +26547,8 @@ msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· avatar" msgid "Remove background" msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· Ï†ÏŒÎœÏ„ÎżÏ…" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "ÎšÎ±Ï„ÎŹÏÎłÎ·ÏƒÎ· banner" @@ -26625,10 +26611,10 @@ msgstr "Î‘Ï†Î±ÎŻÏÎ”ÏƒÎ· από τηΜ ÎșÎżÏÏ…Ï†Îź" msgid "Remove from URL-only GIF favorites" msgstr "Î‘Ï†Î±ÎŻÏÎ”ÏƒÎ· από τα Î±ÎłÎ±Ï€Î·ÎŒÎ­ÎœÎ± GIF Ï€ÎżÏ… Î±Ï€ÎżÎžÎ·ÎșÎ”ÏÎżÎœÏ„Î±Îč ÎŒÏŒÎœÎż Όέσω URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Î‘Ï†Î±ÎŻÏÎ”ÏƒÎ· ΔÎčÎșÎżÎœÎčÎŽÎŻÎżÏ…" @@ -27331,7 +27317,7 @@ msgstr "Î•ÏƒÏ„ÎŹÎ»Î· ÎŸÎ±ÎœÎŹ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Î•Ï€Î±ÎœÎ±Ï†ÎżÏÎŹ" @@ -28074,7 +28060,7 @@ msgstr "ÎĄÎżÏ…ÎŒÎ±ÎœÎčÎșÎŹ" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ΠΔρÎčÏƒÏ„ÏÎżÏ†Îź ΎΔΟÎčÏŒÏƒÏ„ÏÎżÏ†Î±" @@ -28153,8 +28139,8 @@ msgstr "ÎšÎżÏÎ”ÏƒÎŒÏŒÏ‚" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ÎˆÎ»Î”ÎłÏ‡ÎżÏ‚ ÎșωΎÎčÎșÎżÏ€ÎżÎčÎ·Ï„Îź ÎșÎżÎčÎœÎźÏ‚ Ï‡ÏÎźÏƒÎ·Ï‚ ÎżÎžÏŒÎœÎ·Ï‚" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Η ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ· ÎżÎžÏŒÎœÎ·Ï‚ ÎŽÎčαÎșόπηÎșΔ" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση ÎșόÎșÎșÎčΜης έΜΎΔÎčΟης ÏƒÏ„Îż ΔÎčÎșÎżÎœÎŻÎŽÎčÎż της Î”Ï†Î±ÏÎŒÎżÎłÎźÏ‚ όταΜ έχΔτΔ Όη Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎŒÎ­ÎœÎ± ΌηΜύΌατα" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση ÎŒÏŒÎœÎż Ï‡ÏÏŽÎŒÎ±Ï„ÎżÏ‚ έΌφασης, Î±ÎłÎœÎżÏŽÎœÏ„Î±Ï‚ Ï„Îż ÎșαΞολÎčÎșό Ï€ÏÎżÏ†ÎŻÎ» σας" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÏ‰Îœ emoji στηΜ αυτόΌατη ÏƒÏ…ÎŒÏ€Î»ÎźÏÏ‰ÏƒÎ· ΔÎșÏ†ÏÎŹÏƒÎ”Ï‰Îœ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση Ï€ÏÎżÎ”Ï€ÎčÎ»Î”ÎłÎŒÎ­ÎœÎżÏ… avatar, Î±ÎłÎœÎżÏŽÎœÏ„Î±Ï‚ Ï„Îż ÎșαΞολÎčÎșό Ï€ÏÎżÏ†ÎŻÎ» σας" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση έΜΎΔÎčΟης Όη Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎŒÎ­ÎœÏ‰Îœ στα ÎșÎ±ÎœÎŹÎ»Îčα σΔ ÏƒÎŻÎłÎ±ÏƒÎ·" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση Ï„ÎżÏ… avatar Ï„ÎżÏ… ÎșαΞολÎčÎșÎżÏ Ï€ÏÎżÏ†ÎŻÎ» σας σΔ Î±Ï…Ï„ÎźÎœ τηΜ ÎșÎżÎčΜότητα" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Î•ÎŒÏ†ÎŹÎœÎčση Ï„ÎżÏ… banner Ï„ÎżÏ… ÎșαΞολÎčÎșÎżÏ Ï€ÏÎżÏ†ÎŻÎ» σας σΔ Î±Ï…Ï„ÎźÎœ τηΜ ÎșÎżÎčΜότητα" @@ -30720,7 +30706,7 @@ msgstr "Î Î±ÏÎŹÎ»Î”Îčψη" msgid "Skip \"Mark all as read\" confirmation" msgstr "Î Î±ÏÎŹÎ»Î”Îčψη ΔπÎčÎČΔÎČÎ±ÎŻÏ‰ÏƒÎ·Ï‚ \"ΕπÎčÏƒÎźÎŒÎ±ÎœÏƒÎ· όλωΜ ως Î±ÎœÎ±ÎłÎœÏ‰ÏƒÎŒÎ­ÎœÏ‰Îœ\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Î Î±ÏÎŹÎ»Î”Îčψη πΔρÎčÎșÎżÏ€ÎźÏ‚" @@ -32346,7 +32332,7 @@ msgstr "Î•ÎœÎ±Î»Î»Î±ÎłÎź σΔ ÎŹÎœÎ”Ï„Î· ÎŽÎčÎŹÏ„Î±ÎŸÎ·" msgid "Switch to dense layout" msgstr "Î•ÎœÎ±Î»Î»Î±ÎłÎź σΔ ÏƒÏ…ÎŒÏ€Î±ÎłÎź ÎŽÎčÎŹÏ„Î±ÎŸÎ·" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Î•ÎœÎ±Î»Î»Î±ÎłÎź σΔ Î±Ï€Î”Ï…ÎžÎ”ÎŻÎ±Ï‚ ΔÎčÏƒÎ±ÎłÏ‰ÎłÎź" @@ -32734,7 +32720,7 @@ msgstr "Î•ÏÎłÎ±ÏƒÎŻÎ”Ï‚" msgid "Teleporting you to another voice region..." msgstr "ÎŁÎ±Ï‚ ÎŒÎ”Ï„Î±Ï†Î­ÏÎżÏ…ÎŒÎ” σΔ Ώλλη πΔρÎčÎżÏ‡Îź Ï†Ï‰ÎœÎźÏ‚..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Î ÏÏŒÏ„Ï…Ï€Îż" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Ο ÏÏŒÎ»ÎżÏ‚ παραχώρησΔ {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Η Ï€Î·ÎłÎź ÎșÎżÎčÎœÎźÏ‚ Ï‡ÏÎźÏƒÎ·Ï‚ ÎżÎžÏŒÎœÎ·Ï‚ ÏƒÏ„Î±ÎŒÎŹÏ„Î·ÏƒÎ” Μα στέλΜΔÎč ÎČÎŻÎœÏ„Î”Îż, Î”Ï€ÎżÎŒÎ­ÎœÏ‰Ï‚ η ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ· της ÎżÎžÏŒÎœÎ·Ï‚ σας ÎŽÎčαÎșόπηÎșΔ." @@ -33453,6 +33439,11 @@ msgstr "Αυτός Îż Î»ÎżÎłÎ±ÏÎčασΌός ΎΔΜ ÎŒÏ€ÎżÏÎ”ÎŻ Μα ÎŒÏ€Î»ÎżÎș msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Î‘Ï…Ï„Îź η Î”ÎœÎ­ÏÎłÎ”Îčα ΎΔΜ ÎŒÏ€ÎżÏÎ”ÎŻ Μα αΜαÎčÏÎ”ÎžÎ”ÎŻ. Όλα τα σχΔτÎčÎșÎŹ ÎŽÎ”ÎŽÎżÎŒÎ­ÎœÎ±, συΌπΔρÎčλαΌÎČÎ±ÎœÎżÎŒÎ­ÎœÎżÏ… Ï„ÎżÏ… Ï‡ÏÎźÏƒÏ„Î· bot, Ξα ÎŽÎčÎ±ÎłÏÎ±Ï†ÎżÏÎœ ÎżÏÎčστÎčÎșÎŹ." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Αυτό Ï„Îż ÎșÎčÎœÎżÏÎŒÎ”ÎœÎż σχέΎÎčÎż Î”ÎŻÎœÎ±Îč Ï€ÎżÎ»Ï ÎŒÎ”ÎłÎŹÎ»Îż Îź έχΔÎč Ï€ÎŹÏÎ± Ï€ÎżÎ»Î»ÎŹ Îșαρέ ÎłÎčα Μα ÎłÎŻÎœÎ”Îč πΔρÎčÎșÎżÏ€Îź. ΔοÎșÎčÎŒÎŹÏƒÏ„Î” έΜα ÎŒÎčÎșÏÏŒÏ„Î”ÏÎż Î±ÏÏ‡Î”ÎŻÎż." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Αυτό Ï„Îż bot ΎΔΜ Î”ÎŻÎœÎ±Îč ΎηΌόσÎčÎż ÎșαÎč ΎΔΜ ÎŒÏ€Îż msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Αυτό Ï„Îż bot Î¶Î·Ï„ÎŹ Ï„Îż ÎŽÎčÎșÎ±ÎŻÏ‰ÎŒÎ± ÎŽÎčαχΔÎčρÎčÏƒÏ„Îź. Î Î±ÏÎ±Ï‡Ï‰ÏÎźÏƒÏ„Î” Ï„Îż ÎŒÏŒÎœÎż αΜ ΔΌπÎčστΔύΔστΔ Ï€Î»ÎźÏÏ‰Ï‚ Ï„ÎżÎœ Ï€ÏÎżÎłÏÎ±ÎŒÎŒÎ±Ï„ÎčÏƒÏ„Îź. ΚαλύτΔρα Î¶Î·Ï„ÎźÏƒÏ„Î” Ï„ÎżÏ… Μα πΔρÎčÎżÏÎŻÏƒÎ”Îč τα ÎŽÎčÎșαÎčώΌατα Ï€ÎżÏ… Î¶Î·Ï„ÎŹ. ÎšÎ»Î”ÎŻÏƒÏ„Î” Î±Ï…Ï„ÎźÎœ τη ÏƒÎ”Î»ÎŻÎŽÎ± αΜ ΎΔΜ Î”ÎŻÏƒÏ„Î” ÏƒÎŻÎłÎżÏ…ÏÎżÎč." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Αυτό Ï„Îż Ï€ÏÏŒÎłÏÎ±ÎŒÎŒÎ± πΔρÎčÎźÎłÎ·ÏƒÎ·Ï‚ ΎΔΜ ÎŒÏ€ÎżÏÎ”ÎŻ Μα πΔρÎčÎșόψΔÎč ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± Î±ÏÏ‡Î”ÎŻÎ± {avifFormatLabel}. ΑΜΔÎČÎŹÏƒÏ„Î” έΜα Î±ÏÏ‡Î”ÎŻÎż GIF Îź WebP αΜτ' Î±Ï…Ï„ÎżÏ." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Î‘Ï…Ï„Îź η ÎșÎżÎœÏƒÏŒÎ»Î± Ï„ÎżÏ… Ï€ÏÎżÎłÏÎŹÎŒÎŒÎ±Ï„ÎżÏ‚ πΔρÎčÎźÎłÎ·ÏƒÎ·Ï‚ Î”ÎŻÎœÎ±Îč έΜα Î”ÏÎłÎ±Î»Î”ÎŻÎż Ï€ÏÎżÎłÏÎ±ÎŒÎŒÎ±Ï„ÎčστώΜ." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Αυτός Îż πΔρÎčÎ·ÎłÎ·Ï„ÎźÏ‚ έχΔÎč Î±Ï€Î”ÎœÎ”ÏÎłÎżÏ€ÎżÎčηΌέΜη τη WebAssembly, ÎżÏ€ÏŒÏ„Î” ÎżÎč ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ”Ï‚ ΔÎčÎșόΜΔς ΎΔΜ ÎŒÏ€ÎżÏÎżÏÎœ Μα πΔρÎčÎșÎżÏ€ÎżÏÎœ." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Î‘Ï…Ï„Îź η ÎżÎŒÎŹÎŽÎ± Î”ÎŻÎœÎ±Îč Ï€Î»ÎźÏÎ·Ï‚. ΑφαÎčρέστΔ ÎșÎŹ msgid "This handoff code has expired. Generate a new one to continue." msgstr "Αυτός Îż ÎșωΎÎčÎșός Ï€Î±ÏÎŹÎŽÎżÏƒÎ·Ï‚ έχΔÎč Î»ÎźÎŸÎ”Îč. ΔηΌÎčÎżÏ…ÏÎłÎźÏƒÏ„Î” έΜαΜ ÎœÎ­Îż ÎłÎčα Μα ÏƒÏ…ÎœÎ”Ï‡ÎŻÏƒÎ”Ï„Î”." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Î‘Ï…Ï„Îź η ΔÎčÎșόΜα ΎΔΜ ÎŽÎčαÎČÎŹÏƒÏ„Î·ÎșΔ. ÎœÏ€ÎżÏÎ”ÎŻ Μα Î”ÎŻÎœÎ±Îč ÎșατΔστραΌΌέΜη." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "ΑΜέÎČασΌα" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "ΑΜέÎČασΌα Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÎżÏ… avatar ÎłÎčα Î±Ï…Ï„ÎźÎœ τηΜ ÎșÎżÎčΜότητα" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "ΑΜέÎČασΌα Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÎżÏ… banner ÎłÎčα Î±Ï…Ï„ÎźÎœ τηΜ ÎșÎżÎčΜότητα" @@ -36155,10 +36163,10 @@ msgstr "ΑΜέÎČασΌα Î±ÏÏ‡Î”ÎŻÏ‰Îœ ÎșαÎč Ï€ÎżÎ»Ï…ÎŒÎ­ÏƒÏ‰Îœ σΔ ΌηΜύ msgid "Upload files and media in this channel." msgstr "ΑΜέÎČασΌα Î±ÏÏ‡Î”ÎŻÏ‰Îœ ÎșαÎč Ï€ÎżÎ»Ï…ÎŒÎ­ÏƒÏ‰Îœ σΔ αυτό Ï„Îż ÎșÎ±ÎœÎŹÎ»Îč." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "ΑΜέÎČασΌα ΔÎčÎșÎżÎœÎčÎŽÎŻÎżÏ…" @@ -36401,8 +36409,8 @@ msgstr "Î§ÏÎźÏƒÎ· ÎžÎ­ÎŒÎ±Ï„ÎżÏ‚ Coal (ÎșÎ±Ï„ÎŹÎŒÎ±Ï…ÏÎ”Ï‚ ΔπÎčÏ†ÎŹÎœÎ”ÎčΔ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Î§ÏÎźÏƒÎ· Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÎ·Ï‚ ΔÎčÎșόΜας" @@ -36462,8 +36470,8 @@ msgstr "ΧρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÏ„Î” Ï†ÎŻÎ»Ï„ÏÎ± Îź πληÎșÏ„ÏÎżÎ»ÎżÎłÎźÏƒÏ„ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Î§ÏÎźÏƒÎ· ÎșαΞολÎčÎșÎżÏ Ï€ÏÎżÏ†ÎŻÎ»" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ÎŁÏ…ÎŒÎŒÎ”Ï„Î­Ï‡ÎżÎœÏ„Î”Ï‚ φωΜητÎčÎșÎźÏ‚ ÏƒÏ…ÎœÎżÎŒÎčÎ»ÎŻÎ±Ï‚" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Î•Ï€Î”ÎŸÎ”ÏÎłÎ±ÏƒÎŻÎ± Ï†Ï‰ÎœÎźÏ‚" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ΟυÎčσÎșόΜσÎčΜ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "ΜΔ Ï„Îż {PREMIUM_PRODUCT_NAME}, ÎŒÏ€ÎżÏÎ”ÎŻÏ„Î” Μα χρησÎčÎŒÎżÏ€ÎżÎčÎ”ÎŻÏ„Î” ÎșÎčÎœÎżÏÎŒÎ”ÎœÎ± avatar ({ANIMATED_AVATAR_FORMATS}) ÎșαÎč banner Ï€ÏÎżÏ†ÎŻÎ», Μα Ï€ÏÎżÏƒÎ±ÏÎŒÏŒÎ¶Î”Ï„Î” τηΜ ΔτÎčÎșέτα σας ÎșαÎč Μα ΟΔÎșλΔÎčΎώΜΔτΔ Ï€ÎżÎ»Î»ÎŹ Ώλλα Ï€ÏÎżÎœÏŒÎŒÎčα Ï„ÎżÏ… {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "ΧρΔÎčÎŹÎ¶Î”ÏƒÏ„Î” Ï„Îż ÎŽÎčÎșÎ±ÎŻÏ‰ÎŒÎ± «{permissionLabel}» ÎłÎčα msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "ΧρΔÎčÎŹÎ¶Î”ÏƒÏ„Î” Ï„Îż ÎŽÎčÎșÎ±ÎŻÏ‰ÎŒÎ± «{permissionLabel}» ÎłÎčα Μα χρησÎčÎŒÎżÏ€ÎżÎčÎźÏƒÎ”Ï„Î” Î±Ï…Ï„ÎżÎșόλλητα από ÎŹÎ»Î»Î”Ï‚ ÎșÎżÎčΜότητΔς ΔΎώ." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ΠρέπΔÎč Μα ÎŽÎčΔÎșÎŽÎčÎșÎźÏƒÎ”Ï„Î” Ï„ÎżÎœ Î»ÎżÎłÎ±ÏÎčασΌό σας πρÎčΜ ΎηΌÎčÎżÏ…ÏÎłÎźÏƒÎ”Ï„Î” ÎŒÎčα ÎșÎżÎčΜότητα." @@ -39356,8 +39364,8 @@ msgstr "ΠρέπΔÎč Μα ÎŽÎčΔÎșÎŽÎčÎșÎźÏƒÎ”Ï„Î” Ï„ÎżÎœ Î»ÎżÎłÎ±ÏÎčασΌό msgid "You need to verify a phone number to send messages in this community." msgstr "ΠρέπΔÎč Μα ΔπαληΞΔύσΔτΔ έΜαΜ αρÎčΞΌό Ï„Î·Î»Î”Ï†ÏŽÎœÎżÏ… ÎłÎčα Μα ÏƒÏ„Î”ÎŻÎ»Î”Ï„Î” ΌηΜύΌατα σΔ Î±Ï…Ï„ÎźÎœ τηΜ ÎșÎżÎčΜότητα." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ΠρέπΔÎč Μα ΔπαληΞΔύσΔτΔ τη ÎŽÎčΔύΞυΜση email σας πρÎčΜ ΎηΌÎčÎżÏ…ÏÎłÎźÏƒÎ”Ï„Î” ÎŒÎčα ÎșÎżÎčΜότητα." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Η Î±Ï€ÎżÎžÎ·ÎșΔυΌέΜη Ï€ÎżÎčότητα {savedResolution} στα {savedFrameRate} FPS απαÎčÏ„Î”ÎŻ {premiumProductName}, ÎżÏ€ÏŒÏ„Î” ÎżÎč ÎșÎżÎčÎœÎżÏ€ÎżÎčÎźÏƒÎ”Îčς χρησÎčÎŒÎżÏ€ÎżÎčÎżÏÎœ {resolution} στα {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Η ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ· ÎżÎžÏŒÎœÎ·Ï‚ σας ΎΔΜ ΌπόρΔσΔ Μα ÎŽÎ·ÎŒÎżÏƒÎčÎ”Ï…Ï„Î”ÎŻ ΌΔ συΌÎČατό ÎșωΎÎčÎșÎżÏ€ÎżÎčÎ·Ï„Îź ÎČÎŻÎœÏ„Î”Îż, Î”Ï€ÎżÎŒÎ­ÎœÏ‰Ï‚ ÎŽÎčαÎșόπηÎșΔ. ΔοÎșÎčÎŒÎŹÏƒÏ„Î” Μα ÎŒÎżÎčÏÎ±ÏƒÏ„Î”ÎŻÏ„Î” ÎŸÎ±ÎœÎŹ." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Η Ï€ÏÎżÏƒÎ±ÏÎŒÎżÏƒÎŒÎ­ÎœÎ· ÎŽÎčΔύΞυΜση URL έχΔÎč ÎżÏÎčÏƒÏ„Î”ÎŻ σΔ {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Ο ÎșωΎÎčÎșÎżÏ€ÎżÎčÎ·Ï„ÎźÏ‚ ÎČÎŻÎœÏ„Î”Îż ÏƒÏ„Î±ÎŒÎŹÏ„Î·ÏƒÎ” Μα ÎșωΎÎčÎșÎżÏ€ÎżÎčΔί Îșαρέ, ÎżÏ€ÏŒÏ„Î” η ÎșÎżÎčÎœÎź Ï‡ÏÎźÏƒÎ· ÎżÎžÏŒÎœÎ·Ï‚ ÎŽÎčαÎșόπηÎșΔ. ΔοÎșÎčÎŒÎŹÏƒÏ„Î” Μα τηΜ ÎŒÎżÎčÏÎ±ÏƒÏ„Î”ÎŻÏ„Î” ÎŸÎ±ÎœÎŹ." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Î–ÎżÏ…ÎŒ" diff --git a/fluxer_app/src/features/i18n/locales/en-GB/messages.po b/fluxer_app/src/features/i18n/locales/en-GB/messages.po index f3b4bf3fd..72696b165 100644 --- a/fluxer_app/src/features/i18n/locales/en-GB/messages.po +++ b/fluxer_app/src/features/i18n/locales/en-GB/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, coming soon" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} file is too large. Choose a file smaller than {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} images cannot be animated. Use a static image." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Activity sharing" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Activity threshold" @@ -3566,11 +3561,11 @@ msgstr "Allow {everyoneMention} and {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." @@ -3673,7 +3668,7 @@ msgstr "Allow members without the {readMessageHistoryPermissionLabel} permission msgid "Allow mentions for this role" msgstr "Allow mentions for this role" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Allow microphone" @@ -3942,25 +3937,21 @@ msgstr "and {remainingCount} more" msgid "Animate on interaction" msgstr "Animate on interaction" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animated {avifFormatLabel} not supported" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animated avatars & profile banners" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animated avatars not available" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animated avatars require {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Animated image preview" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animated images are not supported for this asset." @@ -4947,7 +4938,7 @@ msgstr "Auto-detect language" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Auto-set activity threshold" @@ -5127,15 +5118,15 @@ msgstr "Available in the desktop app." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar is too large — pick one under {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avatar mode selection" @@ -5187,11 +5178,11 @@ msgstr "Away right now" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Banned users" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Banner mode selection" @@ -6107,8 +6098,8 @@ msgstr "Buy a {premiumProductName} gift from the {premiumProductName} tab to sha msgid "Buy gift" msgstr "Buy gift" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." @@ -6361,7 +6352,7 @@ msgstr "Can't upload files here" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centred" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Change avatar" @@ -6627,9 +6618,9 @@ msgstr "Change background" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Change banner" @@ -6668,13 +6659,13 @@ msgstr "Change group nickname" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Change icon" @@ -7669,8 +7660,8 @@ msgstr "Claim gift" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Claim your account" @@ -8518,8 +8509,8 @@ msgstr "Community facilitates pile-ons or targeted abuse." msgid "Community filter" msgstr "Community filter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Community icon" @@ -8763,6 +8754,12 @@ msgstr "Composer buttons" msgid "Composer focus" msgstr "Composer focus" +# auto-i18n: reviewed unchanged +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Compressing" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8914,7 @@ msgstr "Connect a camera or virtual capture device, then try again." msgid "Connect a display, then try again." msgstr "Connect a display, then try again." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Connect a microphone and try again." @@ -9783,7 +9780,7 @@ msgid "Couldn't create this sticker" msgstr "Couldn't create this sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Couldn't crop image" @@ -10159,12 +10156,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Couldn't update voice activity sharing right now" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Couldn't upload avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Couldn't upload banner" @@ -10230,7 +10227,7 @@ msgstr "Create & share" msgid "Create a community" msgstr "Create a community" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Create a community for you and your friends to chat." @@ -10489,7 +10486,7 @@ msgid "Crop invite background" msgstr "Crop invite background" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Crop preview" @@ -10500,30 +10497,15 @@ msgstr "Crop profile banner" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Cropping animated files isn't supported yet. The original image will be used." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Cropping animated files isn't supported yet. The original upload will be used." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Cropping {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12579,8 @@ msgstr "Don't have an account?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Don't show" @@ -16560,8 +16542,8 @@ msgstr "Group DM avatars using the same status masks as regular avatars, includi msgid "Group DMs" msgstr "Group DMs" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Group icon" @@ -16624,8 +16606,8 @@ msgstr "Group settings" msgid "Group typing states" msgstr "Group typing states" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Group updated" @@ -16803,7 +16785,7 @@ msgstr "Heart" msgid "Hebrew" msgstr "Hebrew" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Height" @@ -17510,7 +17492,7 @@ msgstr "Image copied to clipboard" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Image couldn't be used" @@ -19671,7 +19653,7 @@ msgid "Look and feel" msgstr "Look and feel" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." @@ -22577,7 +22559,7 @@ msgstr "No matches found" msgid "No mentions yet" msgstr "No mentions yet" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "No microphone found" @@ -23806,7 +23788,7 @@ msgstr "Open system DM" msgid "Open system picker" msgstr "Open system picker" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Open template JSON" @@ -23820,7 +23802,7 @@ msgstr "Open the ban dialog for this community." msgid "Open the context menu" msgstr "Open the context menu" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Open the link below in your browser, then copy the entire JSON response and paste it into the box." @@ -24331,7 +24313,7 @@ msgstr "Past 7 days" msgid "Paste" msgstr "Paste" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Paste a {theOtherPlatform} template URL to import its structure into a new community." @@ -25191,6 +25173,11 @@ msgstr "Premium type" msgid "Premium until date" msgstr "Premium until date" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparing" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25484,22 @@ msgstr "Profile" msgid "Profile badge" msgstr "Profile badge" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profile banners are not enabled on this instance." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profile banners require {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profile banners require {premiumProductName}." @@ -25838,7 +25825,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (limited)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." @@ -26551,8 +26538,8 @@ msgstr "Remove attachment" msgid "Remove authenticator app" msgstr "Remove authenticator app" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Remove avatar" @@ -26561,8 +26548,8 @@ msgstr "Remove avatar" msgid "Remove background" msgstr "Remove background" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Remove banner" @@ -26625,10 +26612,10 @@ msgstr "Remove from top" msgid "Remove from URL-only GIF favorites" msgstr "Remove from URL-only GIF favourites" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Remove icon" @@ -27331,7 +27318,7 @@ msgstr "Resent" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Reset" @@ -28074,7 +28061,7 @@ msgstr "Romanian" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Rotate clockwise" @@ -28153,8 +28140,8 @@ msgstr "Saturation" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28354,7 @@ msgid "Screen share encoder controls" msgstr "Screen share encoder controls" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Screen share ended" @@ -30035,7 +30022,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Show a red badge on the app icon when you have unread messages" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Show accent colour only, ignoring your global profile" @@ -30104,7 +30091,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Show custom emojis in expression autocomplete" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Show default avatar, ignoring your global profile" @@ -30443,12 +30430,12 @@ msgid "Show unread indicator on muted channels" msgstr "Show unread indicator on muted channels" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Show your global profile avatar in this community" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Show your global profile banner in this community" @@ -30720,7 +30707,7 @@ msgstr "Skip" msgid "Skip \"Mark all as read\" confirmation" msgstr "Skip \"Mark all as read\" confirmation" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Skip cropping" @@ -32346,7 +32333,7 @@ msgstr "Switch to comfy layout" msgid "Switch to dense layout" msgstr "Switch to dense layout" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Switch to direct input" @@ -32734,7 +32721,7 @@ msgstr "Tasks" msgid "Teleporting you to another voice region..." msgstr "Teleporting you to another voice region..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Template" @@ -33236,7 +33223,7 @@ msgid "The role granted {permissions}" msgstr "The role granted {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "The screen share source stopped sending video, so your screen share was stopped." @@ -33453,6 +33440,11 @@ msgstr "This account can't be blocked." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "This animation is too long or too large to crop. Try a shorter or smaller file." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33464,23 @@ msgstr "This bot is not public and cannot be added by other users." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "This browser console is a developer tool." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "This browser has WebAssembly turned off, so animated images can't be cropped." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33762,11 @@ msgstr "This group is full. Remove someone before adding more people." msgid "This handoff code has expired. Generate a new one to continue." msgstr "This handoff code has expired. Generate a new one to continue." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "This image couldn't be read. It may be damaged." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36087,12 @@ msgid "Upload" msgstr "Upload" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Upload a custom avatar for this community" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Upload a custom banner for this community" @@ -36155,10 +36164,10 @@ msgstr "Upload files and media in messages." msgid "Upload files and media in this channel." msgstr "Upload files and media in this channel." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Upload icon" @@ -36401,8 +36410,8 @@ msgstr "Use coal theme (pitch-black surfaces)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Use custom image" @@ -36462,8 +36471,8 @@ msgstr "Use filters or enter keywords to find messages" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Use global profile" @@ -37826,7 +37835,7 @@ msgid "Voice participants" msgstr "Voice participants" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Voice processing" @@ -38077,7 +38086,6 @@ msgstr "We couldn't import that theme library file." msgid "We couldn't reach the attachment upload service. {PRODUCT_NAME} can fall back to the standard upload path for messages up to {fallbackSizeFormatted} total, but these attachments exceed that combined limit and can't be sent until connectivity is restored. Try again later or contact <0>{SUPPORT_EMAIL} if this keeps happening." msgstr "We couldn't reach the attachment upload service. {PRODUCT_NAME} can fall back to the standard upload path for messages up to {fallbackSizeFormatted} total, but these attachments exceed that combined limit and can't be sent until connectivity is restored. Try again later or contact <0>{SUPPORT_EMAIL} if this keeps happening." -# auto-i18n: reviewed unchanged #: src/features/messaging/components/alerts/AttachmentUploadConnectivityModal.tsx:25 msgid "We couldn't reach the attachment upload service. {PRODUCT_NAME} can fall back to the standard upload path for messages up to {fallbackSizeFormatted} total, but these attachments exceed that combined limit and can't be sent until connectivity is restored. Try again later or contact the administrators of this instance if this keeps happening." msgstr "We couldn't reach the attachment upload service. {PRODUCT_NAME} can fall back to the standard upload path for messages up to {fallbackSizeFormatted} total, but these attachments exceed that combined limit and can't be sent until connectivity is restored. Try again later or contact the administrators of this instance if this keeps happening." @@ -38685,7 +38693,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customise your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." @@ -38935,7 +38943,6 @@ msgstr "You can remove the <0>{readMessageHistoryPermissionLabel} permission msgid "You can sign back in at any time." msgstr "You can sign back in at any time." -# auto-i18n: reviewed unchanged #. Last line of the set-aside confirmation in the required-action modal on a self-hosted instance. The instance is run by its own administrators, not by the app maker. #: src/features/auth/components/modals/required_action/RequiredActionDescriptors.ts:342 msgid "You can still ask the administrators of this instance for a human review at any time." @@ -39336,8 +39343,8 @@ msgstr "You need the \"{permissionLabel}\" permission to use emoji from other co msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "You need the \"{permissionLabel}\" permission to use stickers from other communities here." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "You need to claim your account before you can create a community." @@ -39358,8 +39365,8 @@ msgstr "You need to claim your account to send messages in this community." msgid "You need to verify a phone number to send messages in this community." msgstr "You need to verify a phone number to send messages in this community." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "You need to verify your email address before you can create a community." @@ -39982,7 +39989,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." @@ -40081,7 +40088,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." @@ -40102,7 +40109,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/en-US/messages.po b/fluxer_app/src/features/i18n/locales/en-US/messages.po index 1cfa78bd0..c8e7472c9 100644 --- a/fluxer_app/src/features/i18n/locales/en-US/messages.po +++ b/fluxer_app/src/features/i18n/locales/en-US/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, coming soon" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} file is too large. Choose a file smaller than {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} images cannot be animated. Use a static image." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Activity sharing" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Activity threshold" @@ -3566,11 +3561,11 @@ msgstr "Allow {everyoneMention} and {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." @@ -3673,7 +3668,7 @@ msgstr "Allow members without the {readMessageHistoryPermissionLabel} permission msgid "Allow mentions for this role" msgstr "Allow mentions for this role" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Allow microphone" @@ -3942,25 +3937,21 @@ msgstr "and {remainingCount} more" msgid "Animate on interaction" msgstr "Animate on interaction" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animated {avifFormatLabel} not supported" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animated avatars & profile banners" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animated avatars not available" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animated avatars require {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Animated image preview" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animated images are not supported for this asset." @@ -4947,7 +4938,7 @@ msgstr "Auto-detect language" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Auto-set activity threshold" @@ -5127,15 +5118,15 @@ msgstr "Available in the desktop app." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar is too large — pick one under {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avatar mode selection" @@ -5187,11 +5178,11 @@ msgstr "Away right now" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Banned users" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Banner mode selection" @@ -6107,8 +6098,8 @@ msgstr "Buy a {premiumProductName} gift from the {premiumProductName} tab to sha msgid "Buy gift" msgstr "Buy gift" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." @@ -6361,7 +6352,7 @@ msgstr "Can't upload files here" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centered" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Change avatar" @@ -6627,9 +6618,9 @@ msgstr "Change background" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Change banner" @@ -6668,13 +6659,13 @@ msgstr "Change group nickname" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Change icon" @@ -7669,8 +7660,8 @@ msgstr "Claim gift" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Claim your account" @@ -8518,8 +8509,8 @@ msgstr "Community facilitates pile-ons or targeted abuse." msgid "Community filter" msgstr "Community filter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Community icon" @@ -8763,6 +8754,11 @@ msgstr "Composer buttons" msgid "Composer focus" msgstr "Composer focus" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Compressing" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Connect a camera or virtual capture device, then try again." msgid "Connect a display, then try again." msgstr "Connect a display, then try again." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Connect a microphone and try again." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Couldn't create this sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Couldn't crop image" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Couldn't update voice activity sharing right now" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Couldn't upload avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Couldn't upload banner" @@ -10230,7 +10226,7 @@ msgstr "Create & share" msgid "Create a community" msgstr "Create a community" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Create a community for you and your friends to chat." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Crop invite background" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Crop preview" @@ -10500,30 +10496,15 @@ msgstr "Crop profile banner" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Cropping animated files isn't supported yet. The original image will be used." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Cropping animated files isn't supported yet. The original upload will be used." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Cropping {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Don't have an account?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Don't show" @@ -16560,8 +16541,8 @@ msgstr "Group DM avatars using the same status masks as regular avatars, includi msgid "Group DMs" msgstr "Group DMs" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Group icon" @@ -16624,8 +16605,8 @@ msgstr "Group settings" msgid "Group typing states" msgstr "Group typing states" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Group updated" @@ -16803,7 +16784,7 @@ msgstr "Heart" msgid "Hebrew" msgstr "Hebrew" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Height" @@ -17510,7 +17491,7 @@ msgstr "Image copied to clipboard" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Image couldn't be used" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Look and feel" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." @@ -22577,7 +22558,7 @@ msgstr "No matches found" msgid "No mentions yet" msgstr "No mentions yet" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "No microphone found" @@ -23806,7 +23787,7 @@ msgstr "Open system DM" msgid "Open system picker" msgstr "Open system picker" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Open template JSON" @@ -23820,7 +23801,7 @@ msgstr "Open the ban dialog for this community." msgid "Open the context menu" msgstr "Open the context menu" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Open the link below in your browser, then copy the entire JSON response and paste it into the box." @@ -24331,7 +24312,7 @@ msgstr "Past 7 days" msgid "Paste" msgstr "Paste" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Paste a {theOtherPlatform} template URL to import its structure into a new community." @@ -25191,6 +25172,11 @@ msgstr "Premium type" msgid "Premium until date" msgstr "Premium until date" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparing" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profile" msgid "Profile badge" msgstr "Profile badge" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profile banners are not enabled on this instance." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profile banners require {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profile banners require {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (limited)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." @@ -26551,8 +26537,8 @@ msgstr "Remove attachment" msgid "Remove authenticator app" msgstr "Remove authenticator app" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Remove avatar" @@ -26561,8 +26547,8 @@ msgstr "Remove avatar" msgid "Remove background" msgstr "Remove background" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Remove banner" @@ -26625,10 +26611,10 @@ msgstr "Remove from top" msgid "Remove from URL-only GIF favorites" msgstr "Remove from URL-only GIF favorites" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Remove icon" @@ -27331,7 +27317,7 @@ msgstr "Resent" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Reset" @@ -28074,7 +28060,7 @@ msgstr "Romanian" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Rotate clockwise" @@ -28153,8 +28139,8 @@ msgstr "Saturation" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Screen share encoder controls" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Screen share ended" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Show a red badge on the app icon when you have unread messages" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Show accent color only, ignoring your global profile" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Show custom emojis in expression autocomplete" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Show default avatar, ignoring your global profile" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Show unread indicator on muted channels" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Show your global profile avatar in this community" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Show your global profile banner in this community" @@ -30720,7 +30706,7 @@ msgstr "Skip" msgid "Skip \"Mark all as read\" confirmation" msgstr "Skip \"Mark all as read\" confirmation" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Skip cropping" @@ -32346,7 +32332,7 @@ msgstr "Switch to comfy layout" msgid "Switch to dense layout" msgstr "Switch to dense layout" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Switch to direct input" @@ -32734,7 +32720,7 @@ msgstr "Tasks" msgid "Teleporting you to another voice region..." msgstr "Teleporting you to another voice region..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Template" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "The role granted {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "The screen share source stopped sending video, so your screen share was stopped." @@ -33453,6 +33439,11 @@ msgstr "This account can't be blocked." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "This animation is too long or too large to crop. Try a shorter or smaller file." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "This bot is not public and cannot be added by other users." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "This browser console is a developer tool." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "This browser has WebAssembly turned off, so animated images can't be cropped." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "This group is full. Remove someone before adding more people." msgid "This handoff code has expired. Generate a new one to continue." msgstr "This handoff code has expired. Generate a new one to continue." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "This image couldn't be read. It may be damaged." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Upload" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Upload a custom avatar for this community" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Upload a custom banner for this community" @@ -36155,10 +36163,10 @@ msgstr "Upload files and media in messages." msgid "Upload files and media in this channel." msgstr "Upload files and media in this channel." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Upload icon" @@ -36401,8 +36409,8 @@ msgstr "Use coal theme (pitch-black surfaces)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Use custom image" @@ -36462,8 +36470,8 @@ msgstr "Use filters or enter keywords to find messages" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Use global profile" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Voice participants" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Voice processing" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." @@ -39334,8 +39342,8 @@ msgstr "You need the \"{permissionLabel}\" permission to use emoji from other co msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "You need the \"{permissionLabel}\" permission to use stickers from other communities here." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "You need to claim your account before you can create a community." @@ -39356,8 +39364,8 @@ msgstr "You need to claim your account to send messages in this community." msgid "You need to verify a phone number to send messages in this community." msgstr "You need to verify a phone number to send messages in this community." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "You need to verify your email address before you can create a community." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProductName}, so shares use {resolution} at {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/es-419/messages.po b/fluxer_app/src/features/i18n/locales/es-419/messages.po index 9664fb50c..9a5de6e23 100644 --- a/fluxer_app/src/features/i18n/locales/es-419/messages.po +++ b/fluxer_app/src/features/i18n/locales/es-419/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, prĂłximamente" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Las dimensiones de {label} no coinciden con este recurso. Elige otra imagen o sube una imagen estĂĄtica que puedas recortar." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "El archivo {label} es demasiado grande. Elige un archivo de menos de {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Las imĂĄgenes de {label} no pueden tener animaciĂłn. Usa una imagen estĂĄtica." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Compartir actividad" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Umbral de actividad" @@ -3566,11 +3561,11 @@ msgstr "Permitir {everyoneMention} y {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Permite que {PRODUCT_NAME} acceda a tu cĂĄmara en {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Permite que {PRODUCT_NAME} acceda a tu micrĂłfono en {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Permite que {PRODUCT_NAME} acceda a tu micrĂłfono. Revisa la barra de direcciones o la configuraciĂłn de tu navegador." @@ -3673,7 +3668,7 @@ msgstr "Permitir que los miembros sin el permiso {readMessageHistoryPermissionLa msgid "Allow mentions for this role" msgstr "Permitir menciones para este rol" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Permitir micrĂłfono" @@ -3942,25 +3937,21 @@ msgstr "y {remainingCount} mĂĄs" msgid "Animate on interaction" msgstr "Animar al interactuar" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Los archivos {AVIF_FORMAT_LABEL} animados no son compatibles. Sube un archivo {AVIF_FORMAT_LABEL} estĂĄtico en su lugar." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "El formato {avifFormatLabel} animado no es compatible" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Los avatares animados ({ANIMATED_AVATAR_FORMATS}) estĂĄn disponibles exclusivamente para suscriptores de {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Los avatares animados ({ANIMATED_AVATAR_FORMATS}) no estĂĄn disponibles en esta instancia. Sube una imagen estĂĄtica en su lugar." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Los avatares animados ({animatedAvatarFormats}) requieren {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatares y banners de perfil animados" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatares animados no disponibles" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Los avatares animados requieren {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Vista previa de imagen animada" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Las imĂĄgenes animadas no son compatibles con este recurso." @@ -4947,7 +4938,7 @@ msgstr "Detectar idioma automĂĄticamente" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Establecer umbral de actividad automĂĄticamente" @@ -5127,15 +5118,15 @@ msgstr "Disponible en la aplicaciĂłn de escritorio." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "El archivo del avatar es demasiado grande. Elige un archivo de menos de {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "El avatar es demasiado grande. Elige uno de menos de {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "SelecciĂłn de modo de avatar" @@ -5187,11 +5178,11 @@ msgstr "Ausente en este momento" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Usuarios baneados" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "El archivo del banner es demasiado grande. Elige un archivo de menos de {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "SelecciĂłn del modo del banner" @@ -6107,8 +6098,8 @@ msgstr "Compra un regalo de {premiumProductName} desde la pestaña {premiumProdu msgid "Buy gift" msgstr "Comprar regalo" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Al crear una comunidad, aceptas seguir y respetar las <0>normas de la comunidad de {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "No se pueden subir archivos aquĂ­" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrado" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Cambiar avatar" @@ -6627,9 +6618,9 @@ msgstr "Cambiar fondo" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Cambiar banner" @@ -6668,13 +6659,13 @@ msgstr "Cambiar apodo en el grupo" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Cambiar Ă­cono" @@ -7669,8 +7660,8 @@ msgstr "Reclamar regalo" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Completa el registro de tu cuenta" @@ -8518,8 +8509,8 @@ msgstr "La comunidad facilita los ataques masivos o el acoso dirigido." msgid "Community filter" msgstr "Filtro de comunidad" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ícono de la comunidad" @@ -8763,6 +8754,11 @@ msgstr "Botones del editor de mensajes" msgid "Composer focus" msgstr "Foco del editor de mensajes" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Comprimiendo" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Conecta una cĂĄmara o un dispositivo de captura virtual y vuelve a inten msgid "Connect a display, then try again." msgstr "Conecta una pantalla y vuelve a intentarlo." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Conecta un micrĂłfono e intĂ©ntalo de nuevo." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "No se pudo crear este sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "No se pudo recortar la imagen" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "No se pudo actualizar la opciĂłn de compartir actividad de voz en este momento" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "No se pudo subir el avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "No se pudo subir el banner" @@ -10230,7 +10226,7 @@ msgstr "Crear y compartir" msgid "Create a community" msgstr "Crear una comunidad" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Crea una comunidad para chatear con tus amigos." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Recortar fondo de invitaciĂłn" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Vista previa del recorte" @@ -10500,30 +10496,15 @@ msgstr "Recortar banner de perfil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "La imagen recortada es demasiado grande. Elige un ĂĄrea mĂĄs pequeña o un archivo mĂĄs pequeño (mĂĄx. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "TodavĂ­a no se admite recortar archivos {formatLabel} animados. Se usarĂĄ la imagen original." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "TodavĂ­a no se admite recortar archivos {formatLabel} animados. Se usarĂĄ el archivo original subido." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "AĂșn no se admite recortar archivos animados. Se usarĂĄ la imagen original." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "TodavĂ­a no se admite recortar archivos animados. Se usarĂĄ el archivo original subido." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Recortando {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ÂżNo tienes una cuenta?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "No mostrar" @@ -16560,8 +16541,8 @@ msgstr "Los avatares de MD de grupo usan las mismas mĂĄscaras de estado que los msgid "Group DMs" msgstr "MD grupales" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ícono del grupo" @@ -16624,8 +16605,8 @@ msgstr "ConfiguraciĂłn del grupo" msgid "Group typing states" msgstr "Estados de escritura del grupo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupo actualizado" @@ -16803,7 +16784,7 @@ msgstr "CorazĂłn" msgid "Hebrew" msgstr "Hebreo" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Altura" @@ -17510,7 +17491,7 @@ msgstr "Imagen copiada al portapapeles" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "No se pudo usar la imagen" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Apariencia y estilo" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Parece que estĂĄs usando {0}. Si agregas el procesamiento de {PRODUCT_NAME} encima, puede causar bombeo o distorsiĂłn. La entrada directa pasa tu audio sin modificaciones." @@ -22577,7 +22558,7 @@ msgstr "No se encontraron resultados" msgid "No mentions yet" msgstr "AĂșn no hay menciones" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "No se encontrĂł ningĂșn micrĂłfono" @@ -23806,7 +23787,7 @@ msgstr "Abrir MD del sistema" msgid "Open system picker" msgstr "Abrir selector del sistema" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Abrir plantilla JSON" @@ -23820,7 +23801,7 @@ msgstr "Abrir el diĂĄlogo de baneo para esta comunidad." msgid "Open the context menu" msgstr "Abrir el menĂș contextual" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Abre el siguiente enlace en tu navegador, luego copia la respuesta JSON completa y pĂ©gala en el cuadro." @@ -24331,7 +24312,7 @@ msgstr "Últimos 7 dĂ­as" msgid "Paste" msgstr "Pegar" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Pega la URL de una plantilla de {theOtherPlatform} para importar su estructura a una nueva comunidad." @@ -25191,6 +25172,11 @@ msgstr "Tipo de premium" msgid "Premium until date" msgstr "Fecha de fin de premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparando" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Perfil" msgid "Profile badge" msgstr "Insignia de perfil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Los banners de perfil son una funciĂłn de {PREMIUM_PRODUCT_NAME}. ObtĂ©n {PREMIUM_PRODUCT_NAME} para agregar un banner a tu perfil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Los banners de perfil no estĂĄn habilitados en esta instancia." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Los banners de perfil requieren {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Los banners de perfil requieren {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Pulsar para hablar" msgid "Push-to-talk (limited)" msgstr "Pulsar para hablar (limitado)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "La funciĂłn pulsar para hablar se ignora en la entrada directa. Cambia a voz enfocada o personalizada para usarla." @@ -26551,8 +26537,8 @@ msgstr "Eliminar archivo adjunto" msgid "Remove authenticator app" msgstr "Eliminar app de autenticaciĂłn" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Eliminar avatar" @@ -26561,8 +26547,8 @@ msgstr "Eliminar avatar" msgid "Remove background" msgstr "Eliminar fondo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Eliminar banner" @@ -26625,10 +26611,10 @@ msgstr "Quitar de la parte superior" msgid "Remove from URL-only GIF favorites" msgstr "Quitar de los GIF favoritos guardados por URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Quitar Ă­cono" @@ -27331,7 +27317,7 @@ msgstr "Reenviado" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Restablecer" @@ -28074,7 +28060,7 @@ msgstr "Rumano" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Girar a la derecha" @@ -28153,8 +28139,8 @@ msgstr "SaturaciĂłn" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Controles del codificador para compartir pantalla" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Se detuvo el uso compartido de pantalla" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Mostrar una insignia roja en el Ă­cono de la app cuando tengas mensajes sin leer" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Mostrar solo el color de Ă©nfasis, ignorando tu perfil global" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Mostrar emojis personalizados en el autocompletado de expresiones" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Mostrar avatar predeterminado, ignorando tu perfil global" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Mostrar indicador de no leĂ­dos en canales silenciados" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Mostrar tu avatar de perfil global en esta comunidad" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Mostrar tu banner de perfil global en esta comunidad" @@ -30720,7 +30706,7 @@ msgstr "Omitir" msgid "Skip \"Mark all as read\" confirmation" msgstr "Omitir la confirmaciĂłn de \"Marcar todo como leĂ­do\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Omitir recorte" @@ -32346,7 +32332,7 @@ msgstr "Cambiar a diseño cĂłmodo" msgid "Switch to dense layout" msgstr "Cambiar a diseño compacto" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Cambiar a entrada directa" @@ -32734,7 +32720,7 @@ msgstr "Tareas" msgid "Teleporting you to another voice region..." msgstr "TeletransportĂĄndote a otra regiĂłn de voz..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Plantilla" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "El rol otorgaba {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "La fuente de uso compartido de pantalla dejĂł de enviar video, por lo que se detuvo el uso compartido de pantalla." @@ -33453,6 +33439,11 @@ msgstr "No se puede bloquear esta cuenta." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Esta acciĂłn no se puede deshacer. Todos los datos asociados, incluyendo el bot, se eliminarĂĄn permanentemente." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Esta animaciĂłn es demasiado larga o grande para recortarla. Intenta con un archivo mĂĄs corto o pequeño." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Este bot no es pĂșblico y no puede ser añadido por otros usuarios." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Este bot solicita el permiso de administrador. ConcĂ©deselo solo si confĂ­as plenamente en el desarrollador. PĂ­dele que solicite menos permisos. Cierra esta pĂĄgina si no estĂĄs seguro." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Este navegador no puede recortar archivos animados de {avifFormatLabel}. Sube un GIF o WebP en su lugar." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Esta consola del navegador es una herramienta para desarrolladores." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Este navegador tiene WebAssembly desactivado, por lo que no se pueden recortar imĂĄgenes animadas." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Este grupo estĂĄ lleno. Elimina a alguien antes de agregar a mĂĄs person msgid "This handoff code has expired. Generate a new one to continue." msgstr "Este cĂłdigo de transferencia ha expirado. Genera uno nuevo para continuar." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Esta imagen no se pudo leer. PodrĂ­a estar dañada." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Subir" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Subir un avatar personalizado para esta comunidad" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Sube un banner personalizado para esta comunidad" @@ -36155,10 +36163,10 @@ msgstr "Sube archivos y contenido multimedia en los mensajes." msgid "Upload files and media in this channel." msgstr "Sube archivos y contenido multimedia en este canal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Subir Ă­cono" @@ -36401,8 +36409,8 @@ msgstr "Usar tema carbĂłn (superficies negro intenso)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Usar imagen personalizada" @@ -36462,8 +36470,8 @@ msgstr "Usa filtros o ingresa palabras clave para encontrar mensajes" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Usar perfil global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Participantes en la llamada" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Procesamiento de voz" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Con {PREMIUM_PRODUCT_NAME}, puedes usar avatares animados ({ANIMATED_AVATAR_FORMATS}) y banners de perfil, personalizar tu etiqueta y desbloquear muchos otros beneficios de {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Necesitas el permiso \"{permissionLabel}\" para usar emojis de otras com msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Necesitas el permiso \"{permissionLabel}\" para usar stickers de otras comunidades aquĂ­." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Debes completar el registro de tu cuenta antes de poder crear una comunidad." @@ -39356,8 +39364,8 @@ msgstr "Debes completar el registro de tu cuenta para enviar mensajes en esta co msgid "You need to verify a phone number to send messages in this community." msgstr "Necesitas verificar un nĂșmero de telĂ©fono para enviar mensajes en esta comunidad." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Necesitas verificar tu direcciĂłn de correo electrĂłnico antes de poder crear una comunidad." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Tu {savedResolution} guardado a {savedFrameRate} FPS requiere {premiumProductName}, por lo que los envĂ­os usan {resolution} a {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "No se pudo publicar tu pantalla compartida con un cĂłdec de video compatible, por lo que se detuvo. Intenta compartir de nuevo." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Tu URL personalizada se estableciĂł en {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Tu codificador de video dejĂł de procesar fotogramas, por lo que se detuvo tu uso compartido de pantalla. Intenta compartir de nuevo." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/es-ES/messages.po b/fluxer_app/src/features/i18n/locales/es-ES/messages.po index 89e982058..ae6761b11 100644 --- a/fluxer_app/src/features/i18n/locales/es-ES/messages.po +++ b/fluxer_app/src/features/i18n/locales/es-ES/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, prĂłximamente" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Las dimensiones de {label} no coinciden con este recurso. Elige otra imagen o sube una imagen estĂĄtica que puedas recortar." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "El archivo {label} es demasiado grande. Elige un archivo de menos de {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Las imĂĄgenes de {label} no pueden estar animadas. Usa una imagen estĂĄtica." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Compartir actividad" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Umbral de actividad" @@ -3566,11 +3561,11 @@ msgstr "Permitir {everyoneMention} y {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Permite que {PRODUCT_NAME} acceda a tu cĂĄmara en {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Permite que {PRODUCT_NAME} acceda a tu micrĂłfono en {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Permite que {PRODUCT_NAME} acceda a tu micrĂłfono. Comprueba la barra de direcciones o los ajustes de tu navegador." @@ -3673,7 +3668,7 @@ msgstr "Permitir que los miembros sin el permiso {readMessageHistoryPermissionLa msgid "Allow mentions for this role" msgstr "Permitir menciones para este rol" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Permitir micrĂłfono" @@ -3942,25 +3937,21 @@ msgstr "y {remainingCount} mĂĄs" msgid "Animate on interaction" msgstr "Animar al interactuar" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "No se admiten archivos {AVIF_FORMAT_LABEL} animados. Sube un archivo {AVIF_FORMAT_LABEL} estĂĄtico en su lugar." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "El formato {avifFormatLabel} animado no es compatible" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Los avatares animados ({ANIMATED_AVATAR_FORMATS}) estĂĄn disponibles exclusivamente para los suscriptores de {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Los avatares animados ({ANIMATED_AVATAR_FORMATS}) no estĂĄn disponibles en esta instancia. Sube una imagen estĂĄtica en su lugar." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Los avatares animados ({animatedAvatarFormats}) requieren {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatares y banners de perfil animados" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatares animados no disponibles" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Los avatares animados requieren {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Vista previa de imagen animada" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Las imĂĄgenes animadas no son compatibles con este recurso." @@ -4947,7 +4938,7 @@ msgstr "Detectar idioma automĂĄticamente" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Establecer umbral de actividad automĂĄticamente" @@ -5127,15 +5118,15 @@ msgstr "Disponible en la aplicaciĂłn de escritorio." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "El archivo del avatar es demasiado grande. Elige un archivo de menos de {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "El avatar es demasiado grande. Elige uno de menos de {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "SelecciĂłn del modo de avatar" @@ -5187,11 +5178,11 @@ msgstr "Ausente ahora mismo" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Usuarios baneados" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Imagen de banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "El archivo del banner es demasiado grande. Elige un archivo de menos de {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "SelecciĂłn del modo del banner" @@ -6107,8 +6098,8 @@ msgstr "Compra un regalo de {premiumProductName} en la pestaña {premiumProductN msgid "Buy gift" msgstr "Comprar regalo" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Al crear una comunidad, aceptas seguir y respetar las <0>normas de la comunidad de {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "No se pueden subir archivos aquĂ­" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrado" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Cambiar avatar" @@ -6627,9 +6618,9 @@ msgstr "Cambiar fondo" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Cambiar banner" @@ -6668,13 +6659,13 @@ msgstr "Cambiar apodo en el grupo" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Cambiar icono" @@ -7669,8 +7660,8 @@ msgstr "Reclamar regalo" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Completa el registro de tu cuenta" @@ -8518,8 +8509,8 @@ msgstr "La comunidad facilita los ataques masivos o el acoso dirigido." msgid "Community filter" msgstr "Filtro de comunidades" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Icono de la comunidad" @@ -8763,6 +8754,11 @@ msgstr "Botones del editor de mensajes" msgid "Composer focus" msgstr "Foco del editor de mensajes" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Comprimiendo" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Conecta una cĂĄmara o un dispositivo de captura virtual y vuelve a inten msgid "Connect a display, then try again." msgstr "Conecta una pantalla y vuelve a intentarlo." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Conecta un micrĂłfono y vuelve a intentarlo." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "No se pudo crear esta pegatina" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "No se pudo recortar la imagen" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "No se ha podido actualizar la opciĂłn de compartir actividad de voz ahora mismo" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "No se pudo subir el avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "No se pudo subir el banner" @@ -10230,7 +10226,7 @@ msgstr "Crear y compartir" msgid "Create a community" msgstr "Crear una comunidad" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Crea una comunidad para chatear con tus amigos." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Recortar fondo de invitaciĂłn" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Vista previa del recorte" @@ -10500,30 +10496,15 @@ msgstr "Recortar el banner del perfil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "La imagen recortada es demasiado grande. Elige un ĂĄrea o un archivo mĂĄs pequeño (mĂĄx. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "AĂșn no se admite recortar archivos {formatLabel} animados. Se usarĂĄ la imagen original." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "TodavĂ­a no se admite recortar archivos {formatLabel} animados. Se usarĂĄ el archivo original subido." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "TodavĂ­a no se admite recortar archivos animados. Se usarĂĄ la imagen original." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "TodavĂ­a no se admite recortar archivos animados. Se usarĂĄ el archivo original subido." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Recortando {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ÂżNo tienes una cuenta?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "No mostrar" @@ -16560,8 +16541,8 @@ msgstr "Los avatares de MD de grupo usan las mismas mĂĄscaras de estado que los msgid "Group DMs" msgstr "MD de grupo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Icono del grupo" @@ -16624,8 +16605,8 @@ msgstr "Ajustes del grupo" msgid "Group typing states" msgstr "Estados de escritura del grupo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupo actualizado" @@ -16803,7 +16784,7 @@ msgstr "CorazĂłn" msgid "Hebrew" msgstr "Hebreo" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Altura" @@ -17510,7 +17491,7 @@ msgstr "Imagen copiada al portapapeles" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "No se ha podido usar la imagen" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Apariencia y estilo" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Parece que estĂĄs usando {0}. Añadir el procesamiento de {PRODUCT_NAME} puede causar bombeo o distorsiĂłn. La entrada directa transmite el audio sin modificar." @@ -22577,7 +22558,7 @@ msgstr "No se encontraron coincidencias" msgid "No mentions yet" msgstr "AĂșn no hay menciones" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "No se ha encontrado ningĂșn micrĂłfono" @@ -23806,7 +23787,7 @@ msgstr "Abrir MD del sistema" msgid "Open system picker" msgstr "Abrir selector del sistema" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Abrir JSON de plantilla" @@ -23820,7 +23801,7 @@ msgstr "Abrir el diĂĄlogo de baneo para esta comunidad." msgid "Open the context menu" msgstr "Abrir el menĂș contextual" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Abre el siguiente enlace en tu navegador, luego copia la respuesta JSON completa y pĂ©gala en el cuadro." @@ -24331,7 +24312,7 @@ msgstr "Últimos 7 dĂ­as" msgid "Paste" msgstr "Pegar" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Pega la URL de una plantilla de {theOtherPlatform} para importar su estructura a una nueva comunidad." @@ -25191,6 +25172,11 @@ msgstr "Tipo de premium" msgid "Premium until date" msgstr "Fecha de fin de premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparando" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Perfil" msgid "Profile badge" msgstr "Insignia de perfil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Los banners de perfil son una funciĂłn de {PREMIUM_PRODUCT_NAME}. ObtĂ©n {PREMIUM_PRODUCT_NAME} para añadir un banner a tu perfil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Los banners de perfil no estĂĄn habilitados en esta instancia." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Los banners de perfil requieren {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Los banners de perfil requieren {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Pulsar para hablar" msgid "Push-to-talk (limited)" msgstr "Pulsar para hablar (limitado)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "La funciĂłn \"Pulsar para hablar\" se ignora en la entrada directa. Cambia a voz enfocada o personalizada para usarla." @@ -26551,8 +26537,8 @@ msgstr "Eliminar archivo adjunto" msgid "Remove authenticator app" msgstr "Eliminar aplicaciĂłn de autenticaciĂłn" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Eliminar avatar" @@ -26561,8 +26547,8 @@ msgstr "Eliminar avatar" msgid "Remove background" msgstr "Eliminar fondo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Eliminar banner" @@ -26625,10 +26611,10 @@ msgstr "Quitar de la parte superior" msgid "Remove from URL-only GIF favorites" msgstr "Eliminar de los GIF favoritos guardados por URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Eliminar icono" @@ -27331,7 +27317,7 @@ msgstr "Reenviado" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Restablecer" @@ -28074,7 +28060,7 @@ msgstr "Rumano" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Girar a la derecha" @@ -28153,8 +28139,8 @@ msgstr "SaturaciĂłn" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Controles del codificador para compartir pantalla" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "FinalizĂł el uso compartido de pantalla" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Mostrar un distintivo rojo en el icono de la aplicaciĂłn cuando tengas mensajes sin leer" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Mostrar solo el color de Ă©nfasis, ignorando tu perfil global" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Mostrar emojis personalizados en el autocompletado de expresiones" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Mostrar avatar predeterminado, ignorando tu perfil global" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Mostrar indicador de no leĂ­dos en canales silenciados" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Mostrar tu avatar de perfil global en esta comunidad" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Mostrar tu banner de perfil global en esta comunidad" @@ -30720,7 +30706,7 @@ msgstr "Omitir" msgid "Skip \"Mark all as read\" confirmation" msgstr "Omitir la confirmaciĂłn de \"Marcar todo como leĂ­do\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Omitir recorte" @@ -32346,7 +32332,7 @@ msgstr "Cambiar a diseño cĂłmodo" msgid "Switch to dense layout" msgstr "Cambiar a diseño compacto" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Cambiar a entrada directa" @@ -32734,7 +32720,7 @@ msgstr "Tareas" msgid "Teleporting you to another voice region..." msgstr "Teletransportando a otra regiĂłn de voz..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Plantilla" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "El rol otorgaba {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "La fuente de uso compartido de pantalla dejĂł de enviar vĂ­deo, por lo que se detuvo el uso compartido de pantalla." @@ -33453,6 +33439,11 @@ msgstr "No se puede bloquear esta cuenta." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Esta acciĂłn no se puede deshacer. Todos los datos asociados, incluido el usuario bot, se eliminarĂĄn permanentemente." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Esta animaciĂłn es demasiado larga o grande para recortarla. Prueba con un archivo mĂĄs corto o pequeño." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Este bot no es pĂșblico y no puede ser añadido por otros usuarios." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Este bot solicita permiso de administrador. ConcĂ©deselo solo si confĂ­as plenamente en el desarrollador. PĂ­dele que solicite menos permisos. Cierra esta pĂĄgina si no estĂĄs seguro." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Este navegador no puede recortar archivos animados de {avifFormatLabel}. Sube un GIF o WebP en su lugar." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Esta consola del navegador es una herramienta para desarrolladores." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Este navegador tiene WebAssembly desactivado, por lo que no se pueden recortar imĂĄgenes animadas." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Este grupo estĂĄ lleno. Elimina a alguien antes de añadir a mĂĄs person msgid "This handoff code has expired. Generate a new one to continue." msgstr "Este cĂłdigo de transferencia ha caducado. Genera uno nuevo para continuar." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "No se ha podido leer esta imagen. Es posible que estĂ© dañada." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Subir" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Sube un avatar personalizado para esta comunidad" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Sube un banner personalizado para esta comunidad" @@ -36155,10 +36163,10 @@ msgstr "Sube archivos y contenido multimedia en los mensajes." msgid "Upload files and media in this channel." msgstr "Sube archivos y contenido multimedia a este canal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Subir icono" @@ -36401,8 +36409,8 @@ msgstr "Usar tema carbĂłn (superficies totalmente negras)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Usar imagen personalizada" @@ -36462,8 +36470,8 @@ msgstr "Usa filtros o introduce palabras clave para encontrar mensajes" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Usar perfil global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Participantes en el chat de voz" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Procesamiento de voz" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Con {PREMIUM_PRODUCT_NAME}, puedes usar avatares animados ({ANIMATED_AVATAR_FORMATS}), banners de perfil, personalizar tu etiqueta y desbloquear muchas otras ventajas de {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Necesitas el permiso \"{permissionLabel}\" para usar aquĂ­ los emojis de msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Necesitas el permiso \"{permissionLabel}\" para usar pegatinas de otras comunidades aquĂ­." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Debes completar el registro de tu cuenta antes de poder crear una comunidad." @@ -39356,8 +39364,8 @@ msgstr "Debes completar el registro de tu cuenta para enviar mensajes en esta co msgid "You need to verify a phone number to send messages in this community." msgstr "Tienes que verificar un nĂșmero de telĂ©fono para enviar mensajes en esta comunidad." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Tienes que verificar tu direcciĂłn de correo electrĂłnico antes de poder crear una comunidad." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Tu {savedResolution} a {savedFrameRate} FPS requiere {premiumProductName}, por lo que las comparticiones usan {resolution} a {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "No se ha podido publicar tu pantalla compartida con un cĂłdec de vĂ­deo compatible, por lo que se ha detenido. Intenta compartir de nuevo." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Tu URL personalizada se ha establecido en {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "El codificador de vĂ­deo dejĂł de codificar fotogramas, por lo que se detuvo el uso compartido de pantalla. Intenta compartir de nuevo." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/fi/messages.po b/fluxer_app/src/features/i18n/locales/fi/messages.po index f2bc44bea..34e0b48b5 100644 --- a/fluxer_app/src/features/i18n/locales/fi/messages.po +++ b/fluxer_app/src/features/i18n/locales/fi/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, tulossa pian" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Kuva ei vastaa kohteen {label} mittoja. Valitse toinen kuva tai lĂ€hetĂ€ staattinen kuva, jonka voit rajata." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label}-tiedosto on liian suuri. Valitse tiedosto, joka on pienempi kuin {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label}-kuvat eivĂ€t voi olla animoituja. KĂ€ytĂ€ staattista kuvaa." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Aktiviteetin jakaminen" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Aktiivisuuskynnys" @@ -3566,11 +3561,11 @@ msgstr "Salli {everyoneMention} ja {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Salli {PRODUCT_NAME}-sovelluksen kĂ€yttÀÀ kameraasi kohdassa {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Salli {PRODUCT_NAME}-sovelluksen kĂ€yttÀÀ mikrofonia kohdassa {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Salli {PRODUCT_NAME}-sovelluksen kĂ€yttÀÀ mikrofonia. Tarkista selaimesi osoitepalkki tai asetukset." @@ -3673,7 +3668,7 @@ msgstr "Salli jĂ€senten, joilla ei ole {readMessageHistoryPermissionLabel} -kĂ€y msgid "Allow mentions for this role" msgstr "Salli maininnat tĂ€lle roolille" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Salli mikrofonin kĂ€yttö" @@ -3942,25 +3937,21 @@ msgstr "ja {remainingCount} muuta" msgid "Animate on interaction" msgstr "Animoi napautettaessa" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animoidut {AVIF_FORMAT_LABEL}-tiedostot eivĂ€t ole tuettuja. Lataa sen sijaan staattinen {AVIF_FORMAT_LABEL}-tiedosto." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animoitua {avifFormatLabel}-tiedostoa ei tueta" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animoidut avatarit ({ANIMATED_AVATAR_FORMATS}) ovat saatavilla vain {PREMIUM_PRODUCT_NAME}-tilaajille." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animoidut avatarit ({ANIMATED_AVATAR_FORMATS}) eivĂ€t ole kĂ€ytettĂ€vissĂ€ tĂ€ssĂ€ instanssissa. Lataa sen sijaan staattinen kuva." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animoidut avatarit ({animatedAvatarFormats}) edellyttĂ€vĂ€t {premiumProductName}-tilausta." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animoidut avatarit ja profiilibannerit" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animoidut avatarit eivĂ€t ole kĂ€ytettĂ€vissĂ€" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animoidut avatarit edellyttĂ€vĂ€t {premiumProductName}-tilausta" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Animoidun kuvan esikatselu" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animoituja kuvia ei tueta tĂ€lle resurssille." @@ -4947,7 +4938,7 @@ msgstr "Tunnista kieli automaattisesti" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Aseta aktiivisuuskynnys automaattisesti" @@ -5127,15 +5118,15 @@ msgstr "Saatavilla työpöytĂ€sovelluksessa." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Profiilikuva" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Profiilikuva on liian suuri. Valitse tiedosto, joka on pienempi kuin {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Profiilikuva on liian suuri. Valitse kuva, jonka koko on alle {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Profiilikuvatilan valinta" @@ -5187,11 +5178,11 @@ msgstr "Poissa juuri nyt" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Porttikielletyt kĂ€yttĂ€jĂ€t" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banneri" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Banneritiedosto on liian suuri. Valitse tiedosto, joka on pienempi kuin {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Banneritilan valinta" @@ -6107,8 +6098,8 @@ msgstr "Osta {premiumProductName}-lahja {premiumProductName}-vĂ€lilehdeltĂ€ ja j msgid "Buy gift" msgstr "Osta lahjaksi" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Luomalla yhteisön sitoudut noudattamaan ja yllĂ€pitĂ€mÀÀn <0>{PRODUCT_NAME}-yhteisön sÀÀntöjĂ€." @@ -6361,7 +6352,7 @@ msgstr "Tiedostoja ei voi lĂ€hettÀÀ tĂ€hĂ€n" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Keskitetty" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Vaihda profiilikuva" @@ -6627,9 +6618,9 @@ msgstr "Vaihda tausta" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Vaihda banneri" @@ -6668,13 +6659,13 @@ msgstr "Vaihda ryhmĂ€n lempinimi" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Vaihda kuvake" @@ -7669,8 +7660,8 @@ msgstr "Lunasta lahja" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Viimeistele tilisi rekisteröinti" @@ -8518,8 +8509,8 @@ msgstr "Yhteisö mahdollistaa joukkoahdistelun tai kohdistetun hĂ€irinnĂ€n." msgid "Community filter" msgstr "Yhteisösuodatin" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Yhteisön kuvake" @@ -8763,6 +8754,11 @@ msgstr "ViestikentĂ€n painikkeet" msgid "Composer focus" msgstr "ViestikentĂ€n kohdistus" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Pakataan" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "LiitĂ€ kamera tai virtuaalinen tallennuslaite ja yritĂ€ sitten uudelleen msgid "Connect a display, then try again." msgstr "LiitĂ€ nĂ€yttö ja yritĂ€ uudelleen." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "LiitĂ€ mikrofoni ja yritĂ€ uudelleen." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Tarraa ei voitu luoda" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Kuvan rajaus epĂ€onnistui" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Puheaktiivisuuden jakamista ei voitu pĂ€ivittÀÀ juuri nyt" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Profiilikuvan lataus epĂ€onnistui" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Bannerin lataaminen epĂ€onnistui" @@ -10230,7 +10226,7 @@ msgstr "Luo ja jaa" msgid "Create a community" msgstr "Luo yhteisö" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Luo yhteisö sinulle ja kavereillesi keskustelua varten." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Rajaa kutsun taustakuva" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Rajauksen esikatselu" @@ -10500,30 +10496,15 @@ msgstr "Rajaa profiilibanneri" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Rajattu kuva on liian suuri. Valitse pienempi alue tai pienempi tiedosto (enintÀÀn {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Animoitujen {formatLabel}-tiedostojen rajausta ei vielĂ€ tueta. KĂ€ytetÀÀn alkuperĂ€istĂ€ kuvaa." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Animoitujen {formatLabel}-tiedostojen rajausta ei vielĂ€ tueta. KĂ€ytetÀÀn alkuperĂ€istĂ€ tiedostoa." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Animoitujen tiedostojen rajausta ei vielĂ€ tueta. KĂ€ytetÀÀn alkuperĂ€istĂ€ kuvaa." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Animoitujen tiedostojen rajausta ei vielĂ€ tueta. KĂ€ytetÀÀn alkuperĂ€istĂ€ tiedostoa." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Rajataan {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Eikö sinulla ole tiliĂ€?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ÄlĂ€ nĂ€ytĂ€" @@ -16560,8 +16541,8 @@ msgstr "RyhmĂ€keskustelujen avatarit kĂ€yttĂ€vĂ€t samoja tilanaamioita kuin tava msgid "Group DMs" msgstr "RyhmĂ€keskustelut" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "RyhmĂ€n kuvake" @@ -16624,8 +16605,8 @@ msgstr "RyhmĂ€n asetukset" msgid "Group typing states" msgstr "RyhmĂ€n kirjoitustilat" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "RyhmĂ€ pĂ€ivitetty" @@ -16803,7 +16784,7 @@ msgstr "SydĂ€n" msgid "Hebrew" msgstr "heprea" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Korkeus" @@ -17510,7 +17491,7 @@ msgstr "Kuva kopioitu leikepöydĂ€lle" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Kuvaa ei voitu kĂ€yttÀÀ" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Ulkoasu ja tuntuma" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "NĂ€yttÀÀ siltĂ€, ettĂ€ kĂ€ytĂ€t ohjelmaa {0}. Jos lisÀÀt {PRODUCT_NAME}-kĂ€sittelyn sen pÀÀlle, ÀÀni voi pumpata tai vÀÀristyĂ€. Suora syöte vĂ€littÀÀ ÀÀnen muokkaamattomana." @@ -22577,7 +22558,7 @@ msgstr "Ei tuloksia" msgid "No mentions yet" msgstr "Ei vielĂ€ mainintoja" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Mikrofonia ei löydy" @@ -23806,7 +23787,7 @@ msgstr "Avaa jĂ€rjestelmĂ€n yksityisviesti" msgid "Open system picker" msgstr "Avaa jĂ€rjestelmĂ€n valitsin" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Avaa mallipohjan JSON" @@ -23820,7 +23801,7 @@ msgstr "Avaa tĂ€mĂ€n yhteisön porttikieltoikkuna." msgid "Open the context menu" msgstr "Avaa pikavalikko" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Avaa alla oleva linkki selaimessasi, kopioi koko JSON-vastaus ja liitĂ€ se kenttÀÀn." @@ -24331,7 +24312,7 @@ msgstr "Viimeiset 7 pĂ€ivÀÀ" msgid "Paste" msgstr "LiitĂ€" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "LiitĂ€ {theOtherPlatform}-mallin URL-osoite, niin voit tuoda sen rakenteen uuteen yhteisöön." @@ -25191,6 +25172,11 @@ msgstr "Premium-tyyppi" msgid "Premium until date" msgstr "Premium voimassa tĂ€hĂ€n asti" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Valmistellaan" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profiili" msgid "Profile badge" msgstr "Profiilimerkki" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profiilibannerit ovat {PREMIUM_PRODUCT_NAME}-ominaisuus. Hanki {PREMIUM_PRODUCT_NAME}, niin voit lisĂ€tĂ€ bannerin profiiliisi." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profiilibannereita ei ole otettu kĂ€yttöön tĂ€ssĂ€ instanssissa." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profiilibannerit edellyttĂ€vĂ€t {premiumProductName}-tilausta" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profiilibannerit edellyttĂ€vĂ€t {premiumProductName}-tilausta." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Puhu painamalla (rajoitettu)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk ohitetaan suorassa syötteessĂ€. KĂ€ytĂ€ sitĂ€ vaihtamalla kohdennettuun ÀÀneen tai mukautettuun tilaan." @@ -26551,8 +26537,8 @@ msgstr "Poista liite" msgid "Remove authenticator app" msgstr "Poista todennussovellus" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Poista profiilikuva" @@ -26561,8 +26547,8 @@ msgstr "Poista profiilikuva" msgid "Remove background" msgstr "Poista taustakuva" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Poista banneri" @@ -26625,10 +26611,10 @@ msgstr "ÄlĂ€ pysy pÀÀllĂ€" msgid "Remove from URL-only GIF favorites" msgstr "Poista URL-osoitteena tallennetuista GIF-suosikeista" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Poista kuvake" @@ -27331,7 +27317,7 @@ msgstr "LĂ€hetetty uudelleen" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Palauta" @@ -28074,7 +28060,7 @@ msgstr "romania" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "KierrĂ€ myötĂ€pĂ€ivÀÀn" @@ -28153,8 +28139,8 @@ msgstr "KyllĂ€isyys" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "NĂ€ytönjakamisen kooderin asetukset" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "NĂ€ytönjako pÀÀttyi" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "NĂ€ytĂ€ punainen merkki sovelluskuvakkeessa, kun sinulla on lukemattomia viestejĂ€" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "NĂ€ytĂ€ vain korostusvĂ€ri globaalin profiilisi sijaan" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "NĂ€ytĂ€ mukautetut emojit ilmaisujen automaattisessa tĂ€ydennyksessĂ€" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "NĂ€ytĂ€ oletusprofiilikuva globaalin profiilisi sijaan" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "NĂ€ytĂ€ lukemattomien viestien ilmaisin mykistetyillĂ€ kanavilla" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "NĂ€ytĂ€ globaali profiilikuvasi tĂ€ssĂ€ yhteisössĂ€" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "NĂ€ytĂ€ globaali profiilibannerisi tĂ€ssĂ€ yhteisössĂ€" @@ -30720,7 +30706,7 @@ msgstr "Ohita" msgid "Skip \"Mark all as read\" confirmation" msgstr "Ohita \"Merkitse kaikki luetuiksi\" -vahvistus" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Ohita rajaus" @@ -32346,7 +32332,7 @@ msgstr "Vaihda vĂ€ljÀÀn asetteluun" msgid "Switch to dense layout" msgstr "Vaihda tiiviiseen asetteluun" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Vaihda suoraan syöttöön" @@ -32734,7 +32720,7 @@ msgstr "TehtĂ€vĂ€t" msgid "Teleporting you to another voice region..." msgstr "SiirretÀÀn sinut toiselle ÀÀnialueelle..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Mallipohja" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rooli myönsi {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "NĂ€ytönjakolĂ€hde lopetti videon lĂ€hettĂ€misen, joten nĂ€ytönjako on lopetettu." @@ -33453,6 +33439,11 @@ msgstr "TĂ€tĂ€ tiliĂ€ ei voi estÀÀ." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "TĂ€tĂ€ toimintoa ei voi kumota. Kaikki siihen liittyvĂ€t tiedot, mukaan lukien bottikĂ€yttĂ€jĂ€, poistetaan pysyvĂ€sti." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Animaatio on liian pitkĂ€ tai liian suuri rajattavaksi. Kokeile lyhyempÀÀ tai pienempÀÀ tiedostoa." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "TĂ€mĂ€ botti ei ole julkinen, eivĂ€tkĂ€ muut kĂ€yttĂ€jĂ€t voi lisĂ€tĂ€ s msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "TĂ€mĂ€ botti pyytÀÀ yllĂ€pitĂ€jĂ€n kĂ€yttöoikeutta. MyönnĂ€ se vain, jos luotat kehittĂ€jÀÀn tĂ€ysin. PyydĂ€ kehittĂ€jÀÀ pyytĂ€mÀÀn sen sijaan vĂ€hemmĂ€n kĂ€yttöoikeuksia. Sulje tĂ€mĂ€ sivu, jos olet epĂ€varma." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Selaimesi ei voi rajata animoituja {avifFormatLabel} -tiedostoja. Lataa sen sijaan GIF- tai WebP-tiedosto." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "TĂ€mĂ€ selaimen konsoli on kehittĂ€jĂ€n työkalu." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Selaimesi WebAssembly-tuki on pois pÀÀltĂ€, joten animoituja kuvia ei voi rajata." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "TĂ€mĂ€ ryhmĂ€ on tĂ€ynnĂ€. Poista joku ennen kuin lisÀÀt lisÀÀ ihmis msgid "This handoff code has expired. Generate a new one to continue." msgstr "TĂ€mĂ€ siirtokoodi on vanhentunut. Luo uusi jatkaaksesi." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Kuvan lukeminen epĂ€onnistui. Se saattaa olla vioittunut." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Lataa" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Lataa mukautettu avatar tĂ€lle yhteisölle" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Lataa mukautettu banneri tĂ€lle yhteisölle" @@ -36155,10 +36163,10 @@ msgstr "LĂ€hetĂ€ tiedostoja ja mediaa viesteihin." msgid "Upload files and media in this channel." msgstr "LĂ€hetĂ€ tiedostoja ja mediaa tĂ€hĂ€n kanavaan." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Lataa kuvake" @@ -36401,8 +36409,8 @@ msgstr "KĂ€ytĂ€ hiiliteemaa (sysimustat pinnat)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "KĂ€ytĂ€ omaa kuvaa" @@ -36462,8 +36470,8 @@ msgstr "KĂ€ytĂ€ suodattimia tai kirjoita hakusanoja löytÀÀksesi viestejĂ€" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "KĂ€ytĂ€ globaalia profiilia" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ÄÀnipuhelun osallistujat" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ÄÀnenkĂ€sittely" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "{PREMIUM_PRODUCT_NAME}-tilauksella voit kĂ€yttÀÀ animoituja avatareita ({ANIMATED_AVATAR_FORMATS}) ja profiilibannereita, mukauttaa tunnistettasi ja avata monia muita {PREMIUM_PRODUCT_NAME}-etuja." @@ -39334,8 +39342,8 @@ msgstr "Tarvitset \"{permissionLabel}\" -kĂ€yttöoikeuden kĂ€yttÀÀksesi muiden msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Tarvitset \"{permissionLabel}\" -kĂ€yttöoikeuden kĂ€yttÀÀksesi muiden yhteisöjen tarroja tÀÀllĂ€." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Sinun on viimeisteltĂ€vĂ€ tilisi rekisteröinti, ennen kuin voit luoda yhteisön." @@ -39356,8 +39364,8 @@ msgstr "Sinun on viimeisteltĂ€vĂ€ tilisi rekisteröinti, jotta voit lĂ€hettÀÀ msgid "You need to verify a phone number to send messages in this community." msgstr "Sinun on vahvistettava puhelinnumero lĂ€hettÀÀksesi viestejĂ€ tĂ€ssĂ€ yhteisössĂ€." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Vahvista sĂ€hköpostiosoitteesi, ennen kuin voit luoda yhteisön." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Tallentamasi {savedResolution} ja {savedFrameRate} FPS vaativat {premiumProductName} -tilauksen, joten jaot kĂ€yttĂ€vĂ€t {resolution} ja {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "NĂ€yttösi jakamista ei voitu julkaista yhteensopivalla videokoodekilla, joten se pysĂ€ytettiin. YritĂ€ jakaa uudelleen." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Mukautetuksi URL-osoitteeksi on asetettu {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Videokooderisi lopetti kuvien koodaamisen, joten nĂ€ytön jakaminen pysĂ€ytettiin. YritĂ€ jakaa uudelleen." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoomaus" diff --git a/fluxer_app/src/features/i18n/locales/fr/messages.po b/fluxer_app/src/features/i18n/locales/fr/messages.po index 9f683f11f..e85d2f0d6 100644 --- a/fluxer_app/src/features/i18n/locales/fr/messages.po +++ b/fluxer_app/src/features/i18n/locales/fr/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, bientĂŽt disponible" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Les dimensions de {label} ne correspondent pas Ă  cette ressource. Choisissez une autre image ou importez une image statique que vous pouvez recadrer." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Le fichier {label} est trop volumineux. Choisissez un fichier de taille infĂ©rieure Ă  {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Les images {label} ne peuvent pas ĂȘtre animĂ©es. Utilisez une image statique." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Partage d’activitĂ©" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Seuil d'activitĂ©" @@ -3566,11 +3561,11 @@ msgstr "Autoriser {everyoneMention} et {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Autorisez {PRODUCT_NAME} Ă  accĂ©der Ă  votre camĂ©ra dans {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Autorisez {PRODUCT_NAME} Ă  accĂ©der Ă  votre micro dans {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Autorisez {PRODUCT_NAME} Ă  accĂ©der Ă  votre microphone. VĂ©rifiez la barre d'adresse ou les paramĂštres de votre navigateur." @@ -3673,7 +3668,7 @@ msgstr "Autoriser les membres sans la permission {readMessageHistoryPermissionLa msgid "Allow mentions for this role" msgstr "Autoriser les mentions pour ce rĂŽle" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Autoriser l’accĂšs au micro" @@ -3942,25 +3937,21 @@ msgstr "et {remainingCount} de plus" msgid "Animate on interaction" msgstr "Animer lors de l'interaction" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Les fichiers {AVIF_FORMAT_LABEL} animĂ©s ne sont pas pris en charge. Veuillez plutĂŽt importer un fichier {AVIF_FORMAT_LABEL} statique." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Le format animĂ© {avifFormatLabel} n'est pas pris en charge" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Les avatars animĂ©s ({ANIMATED_AVATAR_FORMATS}) sont rĂ©servĂ©s aux abonnĂ©s {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Les avatars animĂ©s ({ANIMATED_AVATAR_FORMATS}) ne sont pas disponibles sur cette instance. Importez une image statique." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Les avatars animĂ©s ({animatedAvatarFormats}) nĂ©cessitent {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatars animĂ©s et banniĂšres de profil" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatars animĂ©s non disponibles" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Les avatars animĂ©s nĂ©cessitent {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Aperçu de l'image animĂ©e" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Les images animĂ©es ne sont pas prises en charge pour cet Ă©lĂ©ment." @@ -4947,7 +4938,7 @@ msgstr "DĂ©tection automatique de la langue" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "DĂ©finir automatiquement le seuil d'activitĂ©" @@ -5127,15 +5118,15 @@ msgstr "Disponible dans l'application de bureau." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Le fichier de l'avatar est trop volumineux. Choisissez un fichier de taille infĂ©rieure Ă  {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Le fichier de l’avatar est trop volumineux. Choisissez-en un de moins de {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "SĂ©lection du mode d'avatar" @@ -5187,11 +5178,11 @@ msgstr "Absent(e) pour le moment" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Utilisateurs bannis" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "BanniĂšre" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Le fichier de la banniĂšre est trop volumineux. Choisissez un fichier de taille infĂ©rieure Ă  {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "SĂ©lection du mode de la banniĂšre" @@ -6107,8 +6098,8 @@ msgstr "Achetez un cadeau {premiumProductName} depuis l'onglet {premiumProductNa msgid "Buy gift" msgstr "Offrir" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "En crĂ©ant une communautĂ©, vous acceptez de suivre et de respecter les <0>rĂšgles de la communautĂ© {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Impossible d’envoyer des fichiers ici" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "CentrĂ©" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Changer d'avatar" @@ -6627,9 +6618,9 @@ msgstr "Changer l'arriĂšre-plan" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Changer la banniĂšre" @@ -6668,13 +6659,13 @@ msgstr "Modifier le surnom du groupe" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Changer l'icĂŽne" @@ -7669,8 +7660,8 @@ msgstr "RĂ©cupĂ©rer le cadeau" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Finalisez votre inscription" @@ -8518,8 +8509,8 @@ msgstr "Cette communautĂ© facilite le harcĂšlement collectif ou les abus ciblĂ©s msgid "Community filter" msgstr "Filtrer les communautĂ©s" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "IcĂŽne de la communautĂ©" @@ -8763,6 +8754,11 @@ msgstr "Boutons de la zone de rĂ©daction" msgid "Composer focus" msgstr "Focus de la zone de rĂ©daction" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Compression en cours" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Connectez une camĂ©ra ou un appareil de capture virtuel, puis rĂ©essayez msgid "Connect a display, then try again." msgstr "Connectez un Ă©cran, puis rĂ©essayez." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Connectez un microphone et rĂ©essayez." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Impossible de crĂ©er ce sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Impossible de recadrer l’image" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Impossible de mettre Ă  jour le partage d'activitĂ© vocale pour le moment" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Impossible d’envoyer l’avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Impossible d’envoyer la banniĂšre" @@ -10230,7 +10226,7 @@ msgstr "CrĂ©er et partager" msgid "Create a community" msgstr "CrĂ©er une communautĂ©" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "CrĂ©ez une communautĂ© pour discuter avec vos amis." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Recadrer l'arriĂšre-plan de l'invitation" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Aperçu du recadrage" @@ -10500,30 +10496,15 @@ msgstr "Recadrer la banniĂšre de profil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "L'image recadrĂ©e est trop grande. Choisissez une zone plus petite ou un fichier plus petit (max. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Le recadrage des fichiers {formatLabel} animĂ©s n'est pas encore pris en charge. L'image originale sera utilisĂ©e." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Le recadrage des fichiers {formatLabel} animĂ©s n'est pas encore pris en charge. Le fichier original sera utilisĂ©." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Le recadrage des fichiers animĂ©s n'est pas encore pris en charge. L'image d'origine sera utilisĂ©e." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Le recadrage des fichiers animĂ©s n'est pas encore pris en charge. Le fichier d'origine sera utilisĂ©." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Recadrage de {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Vous n'avez pas de compte ?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Ne pas afficher" @@ -16560,8 +16541,8 @@ msgstr "Les avatars des MP de groupe utilisent les mĂȘmes masques de statut que msgid "Group DMs" msgstr "MP de groupe" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "IcĂŽne du groupe" @@ -16624,8 +16605,8 @@ msgstr "ParamĂštres du groupe" msgid "Group typing states" msgstr "États de saisie du groupe" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Groupe mis Ă  jour" @@ -16803,7 +16784,7 @@ msgstr "CƓur" msgid "Hebrew" msgstr "HĂ©breu" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Hauteur" @@ -17510,7 +17491,7 @@ msgstr "Image copiĂ©e dans le presse-papiers" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Impossible d'utiliser l'image" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Apparence" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Il semble que vous utilisiez {0}. Empiler le traitement de {PRODUCT_NAME} par-dessus peut provoquer des pompages ou des distorsions. L'entrĂ©e directe transmet votre audio sans modification." @@ -22577,7 +22558,7 @@ msgstr "Aucun rĂ©sultat" msgid "No mentions yet" msgstr "Aucune mention pour l'instant" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Aucun microphone dĂ©tectĂ©" @@ -23806,7 +23787,7 @@ msgstr "Ouvrir la conversation privĂ©e avec le systĂšme" msgid "Open system picker" msgstr "Ouvrir le sĂ©lecteur systĂšme" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Ouvrir le modĂšle JSON" @@ -23820,7 +23801,7 @@ msgstr "Ouvrir la boĂźte de dialogue de bannissement pour cette communautĂ©." msgid "Open the context menu" msgstr "Ouvrir le menu contextuel" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Ouvrez le lien ci-dessous dans votre navigateur, puis copiez l'intĂ©gralitĂ© de la rĂ©ponse JSON et collez-la dans le champ." @@ -24331,7 +24312,7 @@ msgstr "7 derniers jours" msgid "Paste" msgstr "Coller" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Collez une URL de modĂšle {theOtherPlatform} pour importer sa structure dans une nouvelle communautĂ©." @@ -25191,6 +25172,11 @@ msgstr "Type d'abonnement premium" msgid "Premium until date" msgstr "Date de fin Premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "PrĂ©paration" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Badge de profil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Les banniĂšres de profil sont une fonctionnalitĂ© {PREMIUM_PRODUCT_NAME}. Obtenez {PREMIUM_PRODUCT_NAME} pour ajouter une banniĂšre Ă  votre profil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Les banniĂšres de profil ne sont pas activĂ©es sur cette instance." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Les banniĂšres de profil nĂ©cessitent {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Les banniĂšres de profil nĂ©cessitent {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Appuyer pour parler" msgid "Push-to-talk (limited)" msgstr "Appuyer pour parler (limitĂ©)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "« Appuyer pour parler » est ignorĂ© en mode « EntrĂ©e directe ». Passez en mode « OptimisĂ© pour la voix » ou « PersonnalisĂ© » pour l’utiliser." @@ -26551,8 +26537,8 @@ msgstr "Supprimer la piĂšce jointe" msgid "Remove authenticator app" msgstr "Supprimer l'application d'authentification" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Supprimer l'avatar" @@ -26561,8 +26547,8 @@ msgstr "Supprimer l'avatar" msgid "Remove background" msgstr "Supprimer l'arriĂšre-plan" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Supprimer la banniĂšre" @@ -26625,10 +26611,10 @@ msgstr "Retirer de l’affichage permanent" msgid "Remove from URL-only GIF favorites" msgstr "Supprimer des favoris GIF enregistrĂ©s par URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Supprimer l'icĂŽne" @@ -27331,7 +27317,7 @@ msgstr "RenvoyĂ©" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "RĂ©initialiser" @@ -28074,7 +28060,7 @@ msgstr "Roumain" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Pivoter dans le sens des aiguilles d'une montre" @@ -28153,8 +28139,8 @@ msgstr "Saturation" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Commandes de l’encodeur de partage d’écran" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Partage d’écran terminĂ©" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Afficher un badge rouge sur l'icĂŽne de l'app en cas de messages non lus" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Afficher uniquement la couleur d'accentuation, en ignorant votre profil global" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Afficher les emojis personnalisĂ©s dans la saisie semi-automatique des expressions" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Afficher l'avatar par dĂ©faut, en ignorant votre profil global" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Afficher l'indicateur de messages non lus sur les salons mis en sourdine" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Afficher votre avatar de profil global dans cette communautĂ©" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Afficher votre banniĂšre de profil global dans cette communautĂ©" @@ -30720,7 +30706,7 @@ msgstr "Passer" msgid "Skip \"Mark all as read\" confirmation" msgstr "Passer la confirmation « Tout marquer comme lu »" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Ignorer le recadrage" @@ -32346,7 +32332,7 @@ msgstr "Passer Ă  la mise en page confortable" msgid "Switch to dense layout" msgstr "Passer Ă  la mise en page dense" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Passer en mode EntrĂ©e directe" @@ -32734,7 +32720,7 @@ msgstr "TĂąches" msgid "Teleporting you to another voice region..." msgstr "Transfert vers une autre rĂ©gion vocale en cours..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ModĂšle" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Le rĂŽle accordait {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "La source de partage d’écran a cessĂ© d’envoyer des vidĂ©os, votre partage d’écran a donc Ă©tĂ© arrĂȘtĂ©." @@ -33453,6 +33439,11 @@ msgstr "Ce compte ne peut pas ĂȘtre bloquĂ©." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Cette action est irrĂ©versible. Toutes les donnĂ©es associĂ©es, y compris l'utilisateur du bot, seront dĂ©finitivement supprimĂ©es." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Cette animation est trop longue ou trop volumineuse pour ĂȘtre rognĂ©e. Essayez un fichier plus court ou plus petit." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ce bot n'est pas public et ne peut pas ĂȘtre ajoutĂ© par d'autres utilis msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ce bot demande la permission d'administrateur. Ne l'accordez que si vous faites entiĂšrement confiance au dĂ©veloppeur. Demandez-lui plutĂŽt de demander moins de permissions. Fermez cette page en cas de doute." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ce navigateur ne peut pas recadrer les fichiers {avifFormatLabel} animĂ©s. TĂ©lĂ©chargez plutĂŽt un GIF ou un WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Cette console de navigateur est un outil de dĂ©veloppement." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ce navigateur a WebAssembly dĂ©sactivĂ©, les images animĂ©es ne peuvent donc pas ĂȘtre recadrĂ©es." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ce groupe est plein. Retirez un membre avant d’ajouter d’autres pers msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ce code de transfert a expirĂ©. GĂ©nĂ©rez-en un nouveau pour continuer." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Cette image n'a pas pu ĂȘtre lue. Elle est peut-ĂȘtre endommagĂ©e." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Importer" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Importer un avatar personnalisĂ© pour cette communautĂ©" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Importer une banniĂšre personnalisĂ©e pour cette communautĂ©" @@ -36155,10 +36163,10 @@ msgstr "Envoyer des fichiers et des mĂ©dias dans les messages." msgid "Upload files and media in this channel." msgstr "Envoyer des fichiers et des mĂ©dias dans ce salon." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Importer une icĂŽne" @@ -36401,8 +36409,8 @@ msgstr "Utiliser le thĂšme charbon (surfaces noir de jais)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Utiliser une image personnalisĂ©e" @@ -36462,8 +36470,8 @@ msgstr "Utilisez les filtres ou saisissez des mots-clĂ©s pour trouver des messag #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Utiliser le profil global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Participants Ă  l'appel" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Traitement de la voix" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Avec {PREMIUM_PRODUCT_NAME}, vous pouvez utiliser des avatars animĂ©s ({ANIMATED_AVATAR_FORMATS}), des banniĂšres de profil, personnaliser votre tag et dĂ©bloquer de nombreux autres avantages {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Vous devez disposer de la permission « {permissionLabel} » pour utilis msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Vous devez disposer de la permission « {permissionLabel} » pour utiliser ici les stickers d’autres communautĂ©s." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Vous devez finaliser votre inscription avant de pouvoir crĂ©er une communautĂ©." @@ -39356,8 +39364,8 @@ msgstr "Vous devez finaliser votre inscription pour envoyer des messages dans ce msgid "You need to verify a phone number to send messages in this community." msgstr "Vous devez vĂ©rifier un numĂ©ro de tĂ©lĂ©phone pour envoyer des messages dans cette communautĂ©." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Vous devez vĂ©rifier votre adresse e-mail avant de pouvoir crĂ©er une communautĂ©." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Votre {savedResolution} Ă  {savedFrameRate} FPS nĂ©cessite {premiumProductName}, les partages utilisent donc {resolution} Ă  {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Votre partage d'Ă©cran n'a pas pu ĂȘtre publiĂ© avec un codec vidĂ©o compatible, il a donc Ă©tĂ© arrĂȘtĂ©. Essayez de partager Ă  nouveau." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Votre URL personnalisĂ©e a Ă©tĂ© dĂ©finie sur {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Votre encodeur vidĂ©o a cessĂ© d'encoder des images, votre partage d'Ă©cran a donc Ă©tĂ© arrĂȘtĂ©. Essayez de partager Ă  nouveau." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/he/messages.po b/fluxer_app/src/features/i18n/locales/he/messages.po index 0dbc8e690..66e74db1a 100644 --- a/fluxer_app/src/features/i18n/locales/he/messages.po +++ b/fluxer_app/src/features/i18n/locales/he/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, Ś‘Ś§ŚšŚ•Ś‘" msgid "{kilobits} kbps" msgstr "{kilobits} Ś§Ś™ŚœŚ•-Ś‘Ś™Ś˜/کڠڙڙڔ" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Ś”ŚžŚžŚ“Ś™Ś کڜ {label} ŚŚ™Ś Ś ŚȘŚ•ŚŚžŚ™Ś ŚœŚ Ś›ŚĄ ڔږڔ. Ś‘Ś—Śš ŚȘŚžŚ•Ś Ś” ŚŚ—ŚšŚȘ ڐڕ Ś”ŚąŚœŚ” ŚȘŚžŚ•Ś Ś” ŚĄŚ˜Ś˜Ś™ŚȘ Ś©ŚŚ€Ś©Śš ŚœŚ—ŚȘŚ•Śš." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "ڔڧڕڑڄ {label} Ś’Ś“Ś•Śœ ŚžŚ“Ś™. Ś‘Ś—Śš ڧڕڑڄ ڧژڟ Śž-{maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "ڐڙ ŚŚ€Ś©Śš ŚœŚ”Ś©ŚȘŚžŚ© Ś‘ŚȘŚžŚ•Ś Ś•ŚȘ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ŚąŚ‘Ś•Śš {label}. ڔکŚȘŚžŚ© Ś‘ŚȘŚžŚ•Ś Ś” ŚĄŚ˜Ś˜Ś™ŚȘ." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "کڙŚȘŚ•ŚŁ Ś€ŚąŚ™ŚœŚ•ŚȘ" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "ŚĄŚŁ Ś€ŚąŚ™ŚœŚ•ŚȘ" @@ -3566,11 +3561,11 @@ msgstr "ŚŚ€Ś©Śš {everyoneMention} Ś•-{hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "ŚŚ€Ś©Śš ڜ-{PRODUCT_NAME} ŚœŚ’Ś©ŚȘ ŚœŚžŚŠŚœŚžŚ” کڜښ Ś‘-{MACOS_SYSTEM_SETTINGS_NAME} ← {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} ← {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "ŚŚ€Ś©Śš ڜ-{PRODUCT_NAME} ŚœŚ’Ś©ŚȘ ŚœŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ کڜښ Ś‘-{MACOS_SYSTEM_SETTINGS_NAME} ← {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} ← {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "ŚŚ€Ś©Śš ڜ-{PRODUCT_NAME} ŚœŚ’Ś©ŚȘ ŚœŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ کڜښ. ڑړڕڧ ڐŚȘ Ś©Ś•ŚšŚȘ ڔڛŚȘڕڑŚȘ ڐڕ ڐŚȘ Ś”Ś”Ś’Ś“ŚšŚ•ŚȘ کڜ Ś”Ś“Ś€Ś“Ś€ŚŸ." @@ -3673,7 +3668,7 @@ msgstr "ŚŚ€Ś©Śš ŚœŚ—Ś‘ŚšŚ™Ś ڜڜڐ Ś”ŚšŚ©ŚŚȘ {readMessageHistoryPermissionLab msgid "Allow mentions for this role" msgstr "ŚŚ€Ś©Śš ŚŚ–Ś›Ś•ŚšŚ™Ś ڜŚȘڀڧڙړ Ś–Ś”" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ŚŚ€Ś©Śš ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ" @@ -3942,25 +3937,21 @@ msgstr "Ś•-{remainingCount} Ś Ś•ŚĄŚ€Ś™Ś" msgid "Animate on interaction" msgstr "ڔڠڀک Ś‘ŚŚ™Ś Ś˜ŚšŚŚ§ŚŠŚ™Ś”" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Ś§Ś•Ś‘ŚŠŚ™ {AVIF_FORMAT_LABEL} ŚžŚ•Ś Ś€Ś©Ś™Ś ŚŚ™Ś Ś Ś ŚȘŚžŚ›Ś™Ś. Ś‘ŚžŚ§Ś•Ś ږڐŚȘ, ڙک ŚœŚ”ŚąŚœŚ•ŚȘ ڧڕڑڄ {AVIF_FORMAT_LABEL} ŚĄŚ˜Ś˜Ś™." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "{avifFormatLabel} ŚžŚ•Ś Ś€Ś© ڐڙڠڕ Ś ŚȘŚžŚš" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ({ANIMATED_AVATAR_FORMATS}) Ś–ŚžŚ™Ś Ś•ŚȘ ŚšŚ§ ŚœŚžŚ Ś•Ś™Ś™ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ({ANIMATED_AVATAR_FORMATS}) ŚŚ™Ś ŚŸ Ś–ŚžŚ™Ś Ś•ŚȘ Ś‘ŚžŚ•Ś€Śą Ś–Ś”. ڙک ŚœŚ”ŚąŚœŚ•ŚȘ ŚȘŚžŚ•Ś Ś” ŚĄŚ˜Ś˜Ś™ŚȘ Ś‘ŚžŚ§Ś•Ś." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ({animatedAvatarFormats}) Ś“Ś•ŚšŚ©Ś•ŚȘ {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ Ś•Ś‘ŚŚ ŚšŚ™Ś ŚžŚ•Ś Ś€Ś©Ś™Ś" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ŚŚ™Ś ŚŸ Ś–ŚžŚ™Ś Ś•ŚȘ" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ Ś“Ś•ŚšŚ©Ś•ŚȘ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ŚȘŚŠŚ•Ś’Ś” ŚžŚ§Ś“Ś™ŚžŚ” کڜ ŚȘŚžŚ•Ś Ś” ŚžŚ•Ś Ś€Ś©ŚȘ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ŚŚ™Ś ŚŸ Ś ŚȘŚžŚ›Ś•ŚȘ ŚąŚ‘Ś•Śš Ś Ś›ŚĄ Ś–Ś”." @@ -4947,7 +4938,7 @@ msgstr "ږڙڔڕڙ کڀڔ ŚŚ•Ś˜Ś•ŚžŚ˜Ś™" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Ś§Ś‘Ś™ŚąŚ” ŚŚ•Ś˜Ś•ŚžŚ˜Ś™ŚȘ کڜ ŚĄŚŁ Ś”Ś€ŚąŚ™ŚœŚ•ŚȘ" @@ -5127,15 +5118,15 @@ msgstr "Ś–ŚžŚ™ŚŸ Ś‘ŚŚ€ŚœŚ™Ś§ŚŠŚ™Ś™ŚȘ Ś”ŚžŚ—Ś©Ś‘." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ڧڕڑڄ Ś”ŚȘŚžŚ•Ś Ś” Ś’Ś“Ś•Śœ ŚžŚ“Ś™. ڙک ŚœŚ‘Ś—Ś•Śš ڧڕڑڄ ڧژڟ Śž-{imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Ś”ŚȘŚžŚ•Ś Ś” Ś’Ś“Ś•ŚœŚ” ŚžŚ“Ś™. ڙک ŚœŚ‘Ś—Ś•Śš ŚȘŚžŚ•Ś Ś” Ś§Ś˜Ś Ś” Śž-{imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Ś‘Ś—Ś™ŚšŚȘ ŚžŚŠŚ‘ ŚŚ•Ś•Ś˜ŚŚš" @@ -5187,11 +5178,11 @@ msgstr "ڜڐ Ś–ŚžŚ™ŚŸ Ś›ŚšŚ’Śą" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "ŚžŚ©ŚȘŚžŚ©Ś™Ś Ś—ŚĄŚ•ŚžŚ™Ś" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Ś‘ŚŚ Śš" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ڧڕڑڄ Ś”Ś‘ŚŚ Śš Ś’Ś“Ś•Śœ ŚžŚ“Ś™. ڙک ŚœŚ‘Ś—Ś•Śš ڧڕڑڄ ڧژڟ Śž-{imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Ś‘Ś—Ś™ŚšŚȘ ŚžŚŠŚ‘ Ś‘ŚŚ Śš" @@ -6107,8 +6098,8 @@ msgstr "Ś Ś™ŚȘڟ ŚœŚ§Ś Ś•ŚȘ ŚžŚȘŚ ŚȘ {premiumProductName} ŚžŚ”ŚœŚ©Ś•Ś Ś™ŚȘ {prem msgid "Buy gift" msgstr "ڧڠڙڙŚȘ ŚžŚȘŚ Ś”" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Ś‘Ś™ŚŠŚ™ŚšŚȘ Ś§Ś”Ś™ŚœŚ”, ڐŚȘŚ” ŚžŚĄŚ›Ś™Ś ŚœŚ€ŚąŚ•Śœ ŚœŚ€Ś™ <0>ڔڠڗڙڕŚȘ Ś”Ś§Ś”Ś™ŚœŚ” کڜ {PRODUCT_NAME} Ś•ŚœŚ©ŚžŚ•Śš ŚąŚœŚ™Ś”ŚŸ." @@ -6361,7 +6352,7 @@ msgstr "ڜڐ Ś Ś™ŚȘڟ ŚœŚ”ŚąŚœŚ•ŚȘ Ś§Ś‘ŚŠŚ™Ś Ś›ŚŚŸ" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ŚžŚžŚ•ŚšŚ›Ś–" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "کڙڠڕڙ ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ" @@ -6627,9 +6618,9 @@ msgstr "کڙڠڕڙ ŚšŚ§Śą" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "کڙڠڕڙ Ś‘ŚŚ Śš" @@ -6668,13 +6659,13 @@ msgstr "کڙڠڕڙ ڔڛڙڠڕڙ Ś‘Ś§Ś‘Ś•ŚŠŚ”" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "کڙڠڕڙ ŚŚ™Ś™Ś§Ś•ŚŸ" @@ -7669,8 +7660,8 @@ msgstr "Ś§Ś‘Śœ ڐŚȘ Ś”ŚžŚȘŚ Ś”" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "ŚȘŚ‘Śą ڐŚȘ Ś”Ś—Ś©Ś‘Ś•ŚŸ کڜښ" @@ -8518,8 +8509,8 @@ msgstr "Ś”Ś§Ś”Ś™ŚœŚ” ŚžŚŚ€Ś©ŚšŚȘ Ś”ŚŠŚ§Ś•ŚȘ Ś”ŚžŚ•Ś Ś™Ś•ŚȘ ڐڕ Ś”ŚȘŚ Ś›ŚœŚ•ŚȘ msgid "Community filter" msgstr "ŚĄŚ™Ś Ś•ŚŸ Ś§Ś”Ś™ŚœŚ•ŚȘ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ŚŚ™Ś™Ś§Ś•ŚŸ Ś§Ś”Ś™ŚœŚ”" @@ -8763,6 +8754,11 @@ msgstr "ڛڀŚȘŚ•ŚšŚ™ ŚȘڙڑŚȘ Ś”Ś”Ś•Ś“ŚąŚ”" msgid "Composer focus" msgstr "ŚžŚ™Ś§Ś•Ś“ ŚȘڙڑŚȘ Ś”Ś”Ś•Ś“ŚąŚ”" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Ś“Ś•Ś—ŚĄ" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Ś—Ś‘Śš ŚžŚŠŚœŚžŚ” ڐڕ Ś”ŚȘڧڟ ŚœŚ›Ś™Ś“Ś” Ś•Ś™ŚšŚ˜Ś•ŚŚœŚ™, ڕڐږ Ś ŚĄ msgid "Connect a display, then try again." msgstr "Ś—Ś‘Śš ŚŠŚ’, ڕڐږ Ś ŚĄŚ” کڕڑ." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Ś—Ś‘Śš ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ Ś•Ś ŚĄŚ” کڕڑ." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ڜڐ Ś Ś™ŚȘڟ ŚœŚ™ŚŠŚ•Śš ڐŚȘ Ś”ŚžŚ“Ś‘Ś§Ś” ڔږڕ" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ڜڐ Ś Ś™ŚȘڟ ŚœŚ—ŚȘŚ•Śš ڐŚȘ Ś”ŚȘŚžŚ•Ś Ś”" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚąŚ“Ś›ŚŸ ڐŚȘ کڙŚȘŚ•ŚŁ Ś”Ś€ŚąŚ™ŚœŚ•ŚȘ Ś”Ś§Ś•ŚœŚ™ŚȘ Ś›ŚąŚȘ" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚ”ŚąŚœŚ•ŚȘ ڐŚȘ Ś”ŚŚ•Ś•Ś˜ŚŚš" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚ”ŚąŚœŚ•ŚȘ ڐŚȘ Ś”Ś‘ŚŚ Śš" @@ -10230,7 +10226,7 @@ msgstr "Ś™ŚŠŚ™ŚšŚ” ڕکڙŚȘŚ•ŚŁ" msgid "Create a community" msgstr "Ś™ŚŠŚ™ŚšŚȘ Ś§Ś”Ś™ŚœŚ”" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ŚŠŚ•Śš Ś§Ś”Ś™ŚœŚ” Ś‘Ś©Ś‘Ś™ŚœŚš Ś•Ś‘Ś©Ś‘Ś™Śœ Ś”Ś—Ś‘ŚšŚ™Ś کڜښ ڛړڙ ŚœŚ©Ś•Ś—Ś—." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Ś—Ś™ŚȘŚ•Śš ŚšŚ§Śą Ś”Ś”Ś–ŚžŚ Ś”" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ŚȘŚŠŚ•Ś’Ś” ŚžŚ§Ś“Ś™ŚžŚ” کڜ Ś—Ś™ŚȘŚ•Śš" @@ -10500,30 +10496,15 @@ msgstr "Ś—Ś™ŚȘŚ•Śš Ś‘ŚŚ Śš Ś€ŚšŚ•Ś€Ś™Śœ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Ś”ŚȘŚžŚ•Ś Ś” ڔڗŚȘڕڛڔ Ś’Ś“Ś•ŚœŚ” ŚžŚ“Ś™. Ś‘Ś—Śš ŚŚ–Ś•Śš ڧژڟ ڙڕŚȘŚš ڐڕ ڧڕڑڄ ڧژڟ ڙڕŚȘŚš (ŚžŚ§ŚĄŚ™ŚžŚ•Ś {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Ś—Ś™ŚȘŚ•Śš Ś§Ś•Ś‘ŚŠŚ™ {formatLabel} ŚžŚ•Ś Ś€Ś©Ś™Ś ŚąŚ“Ś™Ś™ŚŸ ڜڐ Ś ŚȘŚžŚš. Ś™Ś™ŚąŚ©Ś” Ś©Ś™ŚžŚ•Ś© Ś‘ŚȘŚžŚ•Ś Ś” Ś”ŚžŚ§Ś•ŚšŚ™ŚȘ." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Ś—Ś™ŚȘŚ•Śš Ś§Ś•Ś‘ŚŠŚ™ {formatLabel} ŚžŚ•Ś Ś€Ś©Ś™Ś ŚąŚ“Ś™Ś™ŚŸ ڜڐ Ś ŚȘŚžŚš. Ś™Ś™ŚąŚ©Ś” Ś©Ś™ŚžŚ•Ś© ڑڧڕڑڄ Ś”ŚžŚ§Ś•ŚšŚ™ Ś©Ś”Ś•ŚąŚœŚ”." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Ś—Ś™ŚȘŚ•Śš Ś§Ś‘ŚŠŚ™Ś ŚžŚ•Ś Ś€Ś©Ś™Ś ŚąŚ“Ś™Ś™ŚŸ ڜڐ Ś ŚȘŚžŚš. Ś™Ś™ŚąŚ©Ś” Ś©Ś™ŚžŚ•Ś© Ś‘ŚȘŚžŚ•Ś Ś” Ś”ŚžŚ§Ś•ŚšŚ™ŚȘ." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Ś—Ś™ŚȘŚ•Śš Ś§Ś‘ŚŠŚ™Ś ŚžŚ•Ś Ś€Ś©Ś™Ś ŚąŚ“Ś™Ś™ŚŸ ڜڐ Ś ŚȘŚžŚš. Ś™Ś™ŚąŚ©Ś” Ś©Ś™ŚžŚ•Ś© ڑڧڕڑڄ Ś”ŚžŚ§Ś•ŚšŚ™ Ś©Ś”Ś•ŚąŚœŚ”." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Ś—Ś•ŚȘښ {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ŚŚ™ŚŸ ڜښ Ś—Ś©Ś‘Ś•ŚŸ?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ڐڜ ŚȘŚŠŚ™Ś’" @@ -16560,8 +16541,8 @@ msgstr "ŚȘŚžŚ•Ś Ś•ŚȘ Ś”Ś€ŚšŚ•Ś€Ś™Śœ کڜ ŚŠ'ŚŚ˜Ś™Ś Ś§Ś‘Ś•ŚŠŚȘŚ™Ś™Ś ŚžŚ©ŚȘŚžŚ© msgid "Group DMs" msgstr "ŚŠ'ŚŚ˜Ś™Ś Ś§Ś‘Ś•ŚŠŚȘŚ™Ś™Ś" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ŚŚ™Ś™Ś§Ś•ŚŸ Ś”Ś§Ś‘Ś•ŚŠŚ”" @@ -16624,8 +16605,8 @@ msgstr "Ś”Ś’Ś“ŚšŚ•ŚȘ Ś§Ś‘Ś•ŚŠŚ”" msgid "Group typing states" msgstr "ŚžŚŠŚ‘Ś™ Ś”Ś§ŚœŚ“Ś” کڜ Ś§Ś‘Ś•ŚŠŚ”" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Ś”Ś§Ś‘Ś•ŚŠŚ” ŚąŚ•Ś“Ś›Ś Ś”" @@ -16803,7 +16784,7 @@ msgstr "ŚœŚ‘" msgid "Hebrew" msgstr "ŚąŚ‘ŚšŚ™ŚȘ" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "ڒڕڑڔ" @@ -17510,7 +17491,7 @@ msgstr "Ś”ŚȘŚžŚ•Ś Ś” Ś”Ś•ŚąŚȘڧڔ ŚœŚœŚ•Ś— Ś”Ś’Ś–Ś™ŚšŚ™Ś" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚ”Ś©ŚȘŚžŚ© Ś‘ŚȘŚžŚ•Ś Ś”" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "ŚžŚšŚŚ” Ś•ŚȘڗڕکڔ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Ś ŚšŚŚ” کڐŚȘŚ” ŚžŚ©ŚȘŚžŚ© Ś‘-{0}. Ś”Ś•ŚĄŚ€ŚȘ ŚąŚ™Ś‘Ś•Ś“ کڜ {PRODUCT_NAME} ŚąŚœŚ•ŚœŚ” ŚœŚ’ŚšŚ•Ś ŚœŚąŚ™Ś•Ś•ŚȘ ڐڕ ŚœŚ”Ś’Ś‘ŚšŚȘ Ś™ŚȘŚš. ڧڜژ Ś™Ś©Ś™Śš ŚžŚąŚ‘Ś™Śš ڐŚȘ Ś”Ś©ŚžŚą کڜښ ڜڜڐ کڙڠڕڙ." @@ -22577,7 +22558,7 @@ msgstr "ڜڐ Ś ŚžŚŠŚŚ• Ś”ŚȘŚŚžŚ•ŚȘ" msgid "No mentions yet" msgstr "ŚŚ™ŚŸ ŚŚ–Ś›Ś•ŚšŚ™Ś ŚąŚ“Ś™Ś™ŚŸ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "ڜڐ Ś ŚžŚŠŚ ŚžŚ™Ś§ŚšŚ•Ś€Ś•ŚŸ" @@ -23806,7 +23787,7 @@ msgstr "Ś€ŚȘŚ— ڐŚȘ ŚŠ'ڐژ Ś”ŚžŚąŚšŚ›ŚȘ" msgid "Open system picker" msgstr "Ś€ŚȘڙڗŚȘ Ś‘Ś•ŚšŚš Ś”ŚžŚąŚšŚ›ŚȘ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Ś€ŚȘڙڗŚȘ Ś”-JSON کڜ Ś”ŚȘڑڠڙŚȘ" @@ -23820,7 +23801,7 @@ msgstr "Ś€ŚȘڙڗŚȘ Ś—ŚœŚ•ŚŸ Ś”Ś—ŚĄŚ™ŚžŚ” ŚąŚ‘Ś•Śš Ś§Ś”Ś™ŚœŚ” Ś–Ś•." msgid "Open the context menu" msgstr "Ś€ŚȘŚ— ڐŚȘ ŚȘŚ€ŚšŚ™Ś˜ Ś”Ś”Ś§Ś©Śš" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "ڙک ڜڀŚȘڕڗ ڐŚȘ Ś”Ś§Ś™Ś©Ś•Śš ŚœŚžŚ˜Ś” Ś‘Ś“Ś€Ś“Ś€ŚŸ, ŚœŚ”ŚąŚȘڙڧ ڐŚȘ Ś›Śœ ŚȘڒڕڑŚȘ Ś”-JSON Ś•ŚœŚ”Ś“Ś‘Ś™Ś§ ڐڕŚȘŚ” Ś‘ŚȘڙڑڔ." @@ -24331,7 +24312,7 @@ msgstr "7 Ś”Ś™ŚžŚ™Ś Ś”ŚŚ—ŚšŚ•Ś Ś™Ś" msgid "Paste" msgstr "ڔړڑڧ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "ڔړڑڧ Ś›ŚȘڕڑŚȘ URL کڜ ŚȘڑڠڙŚȘ {theOtherPlatform} ڛړڙ ŚœŚ™Ś™Ś‘Ś ڐŚȘ Ś”ŚžŚ‘Ś Ś” Ś©ŚœŚ” ŚœŚ§Ś”Ś™ŚœŚ” ڗړکڔ." @@ -25191,6 +25172,11 @@ msgstr "ŚĄŚ•Ś’ Ś€ŚšŚ™ŚžŚ™Ś•Ś" msgid "Premium until date" msgstr "Ś€ŚšŚ™ŚžŚ™Ś•Ś ŚąŚ“ ŚȘŚŚšŚ™Śš" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ŚžŚ›Ś™ŚŸ" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Ś€ŚšŚ•Ś€Ś™Śœ" msgid "Profile badge" msgstr "ŚȘŚ’ Ś€ŚšŚ•Ś€Ś™Śœ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Ś‘ŚŚ ŚšŚ™Ś Ś‘Ś€ŚšŚ•Ś€Ś™Śœ Ś”Ś ŚȘڛڕڠڔ کڜ {PREMIUM_PRODUCT_NAME}. Ś§Ś‘Śœ {PREMIUM_PRODUCT_NAME} ڛړڙ ŚœŚ”Ś•ŚĄŚ™ŚŁ Ś‘ŚŚ Śš ŚœŚ€ŚšŚ•Ś€Ś™Śœ کڜښ." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Ś‘ŚŚ ŚšŚ™Ś Ś‘Ś€ŚšŚ•Ś€Ś™Śœ ŚŚ™Ś Ś ŚžŚ•Ś€ŚąŚœŚ™Ś Ś‘ŚžŚ•Ś€Śą Ś–Ś”." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Ś‘ŚŚ ŚšŚ™Ś Ś‘Ś€ŚšŚ•Ś€Ś™Śœ Ś“Ś•ŚšŚ©Ś™Ś {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Ś‘ŚŚ ŚšŚ™Ś Ś‘Ś€ŚšŚ•Ś€Ś™Śœ Ś“Ś•ŚšŚ©Ś™Ś {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Ś“Ś™Ś‘Ś•Śš Ś‘ŚœŚ—Ś™ŚŠŚ”" msgid "Push-to-talk (limited)" msgstr "Ś“Ś™Ś‘Ś•Śš Ś‘ŚœŚ—Ś™ŚŠŚ” (ŚžŚ•Ś’Ś‘Śœ)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Ś“Ś™Ś‘Ś•Śš Ś‘ŚœŚ—Ś™ŚŠŚ” ڐڙڠڕ Ś€ŚąŚ™Śœ Ś‘Ś§ŚœŚ˜ Ś™Ś©Ś™Śš. ŚąŚ‘Ś•Śš ŚœŚ§Ś•Śœ ŚžŚžŚ•Ś§Ś“ ڐڕ ŚœŚžŚŠŚ‘ ŚžŚ•ŚȘŚŚ ڐڙکڙŚȘ ڛړڙ ŚœŚ”Ś©ŚȘŚžŚ© ڑڕ." @@ -26551,8 +26537,8 @@ msgstr "Ś”ŚĄŚš ڧڕڑڄ ŚžŚŠŚ•ŚšŚŁ" msgid "Remove authenticator app" msgstr "Ś”ŚĄŚšŚȘ ŚŚ€ŚœŚ™Ś§ŚŠŚ™Ś™ŚȘ ŚŚ™ŚžŚ•ŚȘ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Ś”ŚĄŚš ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ" @@ -26561,8 +26547,8 @@ msgstr "Ś”ŚĄŚš ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ" msgid "Remove background" msgstr "Ś”ŚĄŚš ŚšŚ§Śą" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Ś”ŚĄŚš Ś‘ŚŚ Śš" @@ -26625,10 +26611,10 @@ msgstr "Ś‘Ś˜Śœ Ś”Ś™Ś©ŚŚšŚ•ŚȘ Ś‘Ś—ŚœŚ•ŚŸ ŚąŚœŚ™Ś•ŚŸ" msgid "Remove from URL-only GIF favorites" msgstr "Ś”ŚĄŚšŚ” ŚžŚ§Ś•Ś‘ŚŠŚ™ GIF ŚžŚ•ŚąŚ“Ś€Ś™Ś ŚœŚ€Ś™ Ś›ŚȘڕڑŚȘ URL Ś‘ŚœŚ‘Ś“" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Ś”ŚĄŚš ŚŚ™Ś™Ś§Ś•ŚŸ" @@ -27331,7 +27317,7 @@ msgstr "Ś Ś©ŚœŚ— کڕڑ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ŚŚ™Ś€Ś•ŚĄ" @@ -28074,7 +28060,7 @@ msgstr "ŚšŚ•ŚžŚ Ś™ŚȘ" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ŚĄŚ•Ś‘Ś‘ ŚąŚ Ś›Ś™Ś•Ś•ŚŸ Ś”Ś©ŚąŚ•ŚŸ" @@ -28153,8 +28139,8 @@ msgstr "ŚšŚ•Ś•Ś™Ś”" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Ś‘Ś§ŚšŚ•ŚȘ ŚžŚ§Ś•Ś“Ś“ کڙŚȘŚ•ŚŁ ŚžŚĄŚš" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "کڙŚȘŚ•ŚŁ ŚžŚĄŚš Ś”ŚĄŚȘŚ™Ś™Ś" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Ś”ŚŠŚ’ ŚȘŚ’ ŚŚ“Ś•Ś ŚąŚœ ŚĄŚžŚœ Ś”ŚŚ€ŚœŚ™Ś§ŚŠŚ™Ś” ڛکڙک ڜښ Ś”Ś•Ś“ŚąŚ•ŚȘ کڜڐ Ś Ś§ŚšŚŚ•" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Ś”ŚŠŚ’ ŚŠŚ‘Śą ڔړڒکڔ Ś‘ŚœŚ‘Ś“, ŚȘŚ•Śš Ś”ŚȘŚąŚœŚžŚ•ŚȘ ŚžŚ”Ś€ŚšŚ•Ś€Ś™Śœ Ś”Ś’ŚœŚ•Ś‘ŚœŚ™ کڜښ" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Ś”ŚŠŚ’ŚȘ ŚŚ™ŚžŚ•Ś’'Ś™ ŚžŚ•ŚȘŚŚžŚ™Ś ڐڙکڙŚȘ Ś‘Ś”Ś©ŚœŚžŚ” ŚŚ•Ś˜Ś•ŚžŚ˜Ś™ŚȘ کڜ Ś‘Ś™Ś˜Ś•Ś™Ś™Ś" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Ś”ŚŠŚ’ ŚŚ•Ś•Ś˜ŚŚš Ś‘ŚšŚ™ŚšŚȘ ŚžŚ—Ś“Śœ, ŚȘŚ•Śš Ś”ŚȘŚąŚœŚžŚ•ŚȘ ŚžŚ”Ś€ŚšŚ•Ś€Ś™Śœ Ś”Ś’ŚœŚ•Ś‘ŚœŚ™ کڜښ" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Ś”ŚŠŚ’ŚȘ ڗڙڕڕڙ Ś”Ś•Ś“ŚąŚ•ŚȘ کڜڐ Ś Ś§ŚšŚŚ• Ś‘ŚąŚšŚ•ŚŠŚ™Ś ŚžŚ•Ś©ŚȘŚ§Ś™Ś" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Ś”ŚŠŚ’ ڐŚȘ ŚȘŚžŚ•Ś ŚȘ Ś”Ś€ŚšŚ•Ś€Ś™Śœ Ś”Ś’ŚœŚ•Ś‘ŚœŚ™ŚȘ کڜښ Ś‘Ś§Ś”Ś™ŚœŚ” Ś–Ś•" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Ś”ŚŠŚ’ ڐŚȘ Ś‘ŚŚ Śš Ś”Ś€ŚšŚ•Ś€Ś™Śœ Ś”Ś’ŚœŚ•Ś‘ŚœŚ™ کڜښ Ś‘Ś§Ś”Ś™ŚœŚ” Ś–Ś•" @@ -30720,7 +30706,7 @@ msgstr "Ś“ŚœŚ’" msgid "Skip \"Mark all as read\" confirmation" msgstr "Ś“ŚœŚ’ ŚąŚœ ŚŚ™Ś©Ś•Śš \"ŚĄŚžŚŸ Ś”Ś›Śœ Ś›Ś Ś§ŚšŚ\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Ś“ŚœŚ’ ŚąŚœ Ś—Ś™ŚȘŚ•Śš" @@ -32346,7 +32332,7 @@ msgstr "Ś”Ś—ŚœŚŁ ŚœŚ€ŚšŚ™ŚĄŚ” ڠڕڗڔ" msgid "Switch to dense layout" msgstr "Ś”Ś—ŚœŚŁ ŚœŚ€ŚšŚ™ŚĄŚ” Ś“Ś—Ś•ŚĄŚ”" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Ś”Ś—ŚœŚŁ ڜڧڜژ Ś™Ś©Ś™Śš" @@ -32734,7 +32720,7 @@ msgstr "ŚžŚ©Ś™ŚžŚ•ŚȘ" msgid "Teleporting you to another voice region..." msgstr "ŚžŚąŚ‘Ś™Śš ڐڕŚȘښ ŚœŚŚ–Ś•Śš Ś§Ś•ŚœŚ™ ŚŚ—Śš..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ŚȘڑڠڙŚȘ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Ś”ŚȘڀڧڙړ Ś”ŚąŚ Ś™Ś§ ڐŚȘ Ś”Ś”ŚšŚ©ŚŚ•ŚȘ {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "ŚžŚ§Ś•Śš کڙŚȘŚ•ŚŁ Ś”ŚžŚĄŚš Ś”Ś€ŚĄŚ™Ś§ ŚœŚ©ŚœŚ•Ś— ڕڙړڐڕ, Ś•ŚœŚ›ŚŸ کڙŚȘŚ•ŚŁ Ś”ŚžŚĄŚš کڜښ Ś”Ś•Ś€ŚĄŚ§." @@ -33453,6 +33439,11 @@ msgstr "ڜڐ Ś Ś™ŚȘڟ ŚœŚ—ŚĄŚ•Ś Ś—Ś©Ś‘Ś•ŚŸ Ś–Ś”." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "ڜڐ Ś Ś™ŚȘڟ ŚœŚ‘Ś˜Śœ Ś€ŚąŚ•ŚœŚ” Ś–Ś•. Ś›Śœ ڔڠŚȘŚ•Ś Ś™Ś Ś”ŚžŚ©Ś•Ś™Ś›Ś™Ś, Ś›Ś•ŚœŚœ ŚžŚ©ŚȘŚžŚ© Ś”Ś‘Ś•Ś˜, Ś™Ś™ŚžŚ—Ś§Ś• ŚœŚŠŚžŚ™ŚȘŚ•ŚȘ." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ś”ŚŚ Ś™ŚžŚŠŚ™Ś” ڔږڕ ŚŚšŚ•Ś›Ś” ŚžŚ“Ś™ ڐڕ Ś’Ś“Ś•ŚœŚ” ŚžŚ“Ś™ ŚœŚ—Ś™ŚȘŚ•Śš. Ś ŚĄŚ” ڧڕڑڄ Ś§ŚŠŚš ڐڕ ڧژڟ ڙڕŚȘŚš." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ś”Ś‘Ś•Ś˜ ڔږڔ ڐڙڠڕ ŚŠŚ™Ś‘Ś•ŚšŚ™ Ś•ŚœŚ Ś Ś™ŚȘڟ ŚœŚ”Ś•ŚĄŚ™ŚŁ ڐڕ msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ś”Ś‘Ś•Ś˜ ڔږڔ ŚžŚ‘Ś§Ś© Ś”ŚšŚ©ŚŚȘ ŚžŚ Ś”Śœ ŚžŚąŚšŚ›ŚȘ. Ś”ŚąŚ Ś§ ڐڕŚȘŚ” ŚšŚ§ ŚŚ ڐŚȘŚ” ŚĄŚ•ŚžŚš ŚœŚ—ŚœŚ•Ś˜Ś™ŚŸ ŚąŚœ Ś”ŚžŚ€ŚȘŚ—. ڑڧک ŚžŚžŚ Ś• ŚœŚŠŚžŚŠŚ ڐŚȘ Ś”Ś”ŚšŚ©ŚŚ•ŚȘ Ś‘ŚžŚ§Ś•Ś ږڐŚȘ. ŚĄŚ’Ś•Śš ڐŚȘ Ś”Ś“ŚŁ ڔږڔ ŚŚ ŚŚ™Ś Śš Ś‘Ś˜Ś•Ś—." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ś”Ś“Ś€Ś“Ś€ŚŸ ڔږڔ ڜڐ Ś™Ś›Ś•Śœ ŚœŚ—ŚȘŚ•Śš Ś§Ś‘ŚŠŚ™ {avifFormatLabel} ŚžŚ•Ś Ś€Ś©Ś™Ś. Ś”ŚąŚœŚ” ڧڕڑڄ GIF ڐڕ WebP Ś‘ŚžŚ§Ś•Ś ږڐŚȘ." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "ŚžŚĄŚ•ŚŁ Ś”Ś“Ś€Ś“Ś€ŚŸ ڔږڔ ڔڕڐ Ś›ŚœŚ™ ŚœŚžŚ€ŚȘŚ—Ś™Ś." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ś‘Ś“Ś€Ś“Ś€ŚŸ کڜښ WebAssembly ڛڑڕڙ, ŚœŚ›ŚŸ ڜڐ Ś Ś™ŚȘڟ ŚœŚ—ŚȘŚ•Śš ŚȘŚžŚ•Ś Ś•ŚȘ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ś”Ś§Ś‘Ś•ŚŠŚ” ڔږڕ ŚžŚœŚŚ”. Ś”ŚĄŚš ŚžŚ™Ś©Ś”Ś• ŚœŚ€Ś Ś™ Ś”Ś•ŚĄŚ€ŚȘ ڐڠ msgid "This handoff code has expired. Generate a new one to continue." msgstr "ŚȘŚ•Ś§ŚŁ ڧڕړ Ś”Ś”ŚąŚ‘ŚšŚ” ڔږڔ ڀڒ. ڙک ŚœŚ™ŚŠŚ•Śš ڧڕړ ڗړک ڛړڙ ŚœŚ”ŚžŚ©Ś™Śš." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚ§ŚšŚ•Ś ڐŚȘ Ś”ŚȘŚžŚ•Ś Ś”. ڙڙŚȘŚ›ŚŸ کڔڙڐ Ś€Ś’Ś•ŚžŚ”." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Ś”ŚąŚœŚŚ”" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Ś”ŚąŚœŚ” ŚȘŚžŚ•Ś ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•ŚȘŚŚžŚȘ ڐڙکڙŚȘ ŚœŚ§Ś”Ś™ŚœŚ” Ś–Ś•" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Ś”ŚąŚœŚ” Ś‘ŚŚ Śš ŚžŚ•ŚȘŚŚ ڐڙکڙŚȘ ŚœŚ§Ś”Ś™ŚœŚ” Ś–Ś•" @@ -36155,10 +36163,10 @@ msgstr "Ś”ŚąŚœŚ” Ś§Ś‘ŚŠŚ™Ś Ś•ŚžŚ“Ś™Ś” Ś‘Ś”Ś•Ś“ŚąŚ•ŚȘ." msgid "Upload files and media in this channel." msgstr "Ś”ŚąŚœŚ” Ś§Ś‘ŚŠŚ™Ś Ś•ŚžŚ“Ś™Ś” Ś‘ŚąŚšŚ•Ś„ Ś–Ś”." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Ś”ŚąŚœŚŚȘ ŚŚ™Ś™Ś§Ś•ŚŸ" @@ -36401,8 +36409,8 @@ msgstr "Ś©Ś™ŚžŚ•Ś© Ś‘ŚąŚšŚ›ŚȘ ڠڕکڐ Ś€Ś—Ś (ŚžŚ©Ś˜Ś—Ś™Ś Ś©Ś—Ś•ŚšŚ™Ś ŚœŚ—Śœ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Ś©Ś™ŚžŚ•Ś© Ś‘ŚȘŚžŚ•Ś Ś” ŚžŚ•ŚȘŚŚžŚȘ ڐڙکڙŚȘ" @@ -36462,8 +36470,8 @@ msgstr "ڔکŚȘŚžŚ© Ś‘ŚžŚĄŚ Ś Ś™Ś ڐڕ Ś”Ś–ŚŸ ŚžŚ™ŚœŚ•ŚȘ ŚžŚ€ŚȘŚ— ڛړڙ ŚœŚžŚŠ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Ś©Ś™ŚžŚ•Ś© Ś‘Ś€ŚšŚ•Ś€Ś™Śœ Ś’ŚœŚ•Ś‘ŚœŚ™" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ŚžŚ©ŚȘŚȘŚ€Ś™Ś ڑکڙڗڔ Ś”Ś§Ś•ŚœŚ™ŚȘ" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ŚąŚ™Ś‘Ś•Ś“ Ś§Ś•ŚœŚ™" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Ś•Ś™ŚĄŚ§Ś•Ś ŚĄŚ™ŚŸ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "ŚąŚ {PREMIUM_PRODUCT_NAME}, ŚȘŚ•Ś›Śœ ŚœŚ”Ś©ŚȘŚžŚ© Ś‘ŚȘŚžŚ•Ś Ś•ŚȘ Ś€ŚšŚ•Ś€Ś™Śœ ŚžŚ•Ś Ś€Ś©Ś•ŚȘ ({ANIMATED_AVATAR_FORMATS}) Ś•Ś‘Ś‘ŚŚ ŚšŚ™Ś ŚœŚ€ŚšŚ•Ś€Ś™Śœ, ŚœŚ”ŚȘŚŚ™Ś ڐڙکڙŚȘ ڐŚȘ Ś”ŚȘŚ’Ś™ŚȘ کڜښ Ś•ŚœŚ€ŚȘڕڗ Ś”Ś˜Ś‘Ś•ŚȘ ŚšŚ‘Ś•ŚȘ Ś Ś•ŚĄŚ€Ś•ŚȘ کڜ {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Ś“ŚšŚ•Ś©Ś” ڜښ Ś”Ś”ŚšŚ©ŚŚ” \"{permissionLabel}\" ڛړڙ ŚœŚ”Ś©ŚȘŚžŚ© msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Ś“ŚšŚ•Ś©Ś” ڜښ Ś”Ś”ŚšŚ©ŚŚ” \"{permissionLabel}\" ڛړڙ ŚœŚ”Ś©ŚȘŚžŚ© Ś‘ŚžŚ“Ś‘Ś§Ś•ŚȘ ŚžŚ§Ś”Ś™ŚœŚ•ŚȘ ŚŚ—ŚšŚ•ŚȘ Ś›ŚŚŸ." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ŚąŚœŚ™Śš ڜŚȘŚ‘Ś•Śą ڐŚȘ Ś”Ś—Ś©Ś‘Ś•ŚŸ کڜښ ŚœŚ€Ś Ś™ Ś©ŚȘŚ•Ś›Śœ ŚœŚ™ŚŠŚ•Śš Ś§Ś”Ś™ŚœŚ”." @@ -39356,8 +39364,8 @@ msgstr "ŚąŚœŚ™Śš ڜŚȘŚ‘Ś•Śą ڐŚȘ Ś”Ś—Ś©Ś‘Ś•ŚŸ کڜښ ڛړڙ ŚœŚ©ŚœŚ•Ś— Ś”Ś•Ś“Śą msgid "You need to verify a phone number to send messages in this community." msgstr "ŚąŚœŚ™Śš ŚœŚŚžŚȘ ŚžŚĄŚ€Śš Ś˜ŚœŚ€Ś•ŚŸ ڛړڙ ŚœŚ©ŚœŚ•Ś— Ś”Ś•Ś“ŚąŚ•ŚȘ Ś‘Ś§Ś”Ś™ŚœŚ” Ś–Ś•." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ڙک ŚœŚŚžŚȘ ڐŚȘ Ś›ŚȘڕڑŚȘ Ś”ŚŚ™ŚžŚ™Ś™Śœ کڜښ ŚœŚ€Ś Ś™ Ś©ŚȘŚ•Ś›Śœ ŚœŚ™ŚŠŚ•Śš Ś§Ś”Ś™ŚœŚ”." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "ڔڐڙڛڕŚȘ Ś©Ś©ŚžŚšŚȘ کڜ {savedResolution} Ś‘- {savedFrameRate} FPS Ś“Ś•ŚšŚ©ŚȘ {premiumProductName}, ŚœŚ›ŚŸ ڔکڙŚȘŚ•Ś€Ś™Ś ŚžŚ©ŚȘŚžŚ©Ś™Ś Ś‘- {resolution} Ś‘- {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ڜڐ Ś Ś™ŚȘڟ ڔڙڔ ŚœŚ€ŚšŚĄŚ ڐŚȘ کڙŚȘŚ•ŚŁ Ś”ŚžŚĄŚš کڜښ ڑڧڕړڧ ڕڙړڐڕ ŚȘŚ•ŚŚ, Ś•ŚœŚ›ŚŸ ڔڕڐ Ś”Ś•Ś€ŚĄŚ§. Ś ŚĄŚ” ڜکŚȘŚŁ کڕڑ." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Ś›ŚȘڕڑŚȘ Ś”-URL Ś”ŚžŚ•ŚȘŚŚžŚȘ ڐڙکڙŚȘ کڜښ Ś”Ś•Ś’Ś“ŚšŚ” ڜ-{inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "ŚžŚ§Ś•Ś“Ś“ ڔڕڕڙړڐڕ کڜښ Ś”Ś€ŚĄŚ™Ś§ ŚœŚ§Ś•Ś“Ś“ Ś€ŚšŚ™Ś™ŚžŚ™Ś, Ś•ŚœŚ›ŚŸ کڙŚȘŚ•ŚŁ Ś”ŚžŚĄŚš کڜښ Ś”Ś•Ś€ŚĄŚ§. Ś ŚĄŚ” ڜکŚȘŚŁ کڕڑ." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Ś–Ś•Ś" diff --git a/fluxer_app/src/features/i18n/locales/hi/messages.po b/fluxer_app/src/features/i18n/locales/hi/messages.po index 1be4283f3..62cf8e51b 100644 --- a/fluxer_app/src/features/i18n/locales/hi/messages.po +++ b/fluxer_app/src/features/i18n/locales/hi/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, à€œà€Čà„à€Š à€† à€°à€čà€Ÿ à€čà„ˆ" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} à€•à„‡ à€†à€Żà€Ÿà€ź à€‡à€ž à€à€žà„‡à€Ÿ à€žà„‡ à€źà„‡à€Č à€šà€čà„€à€‚ à€–à€Ÿà€€à„‡à„€ à€•à„‹à€ˆ à€…à€Čà€— à€‡à€źà„‡à€œ à€šà„à€šà„‡à€‚ à€Żà€Ÿ à€à€žà„€ à€žà„à€„à€żà€° à€‡à€źà„‡à€œ à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚ à€œà€żà€žà„‡ à€†à€Ș à€•à„à€°à„‰à€Ș à€•à€° à€žà€•à„‡à€‚à„€" - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} à€«à€Œà€Ÿà€‡à€Č à€Źà€čà„à€€ à€Źà€Ąà€Œà„€ à€čà„ˆà„€ {maxSizeLabel} à€žà„‡ à€›à„‹à€Ÿà„€ à€«à€Œà€Ÿà€‡à€Č à€šà„à€šà„‡à€‚à„€" #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} à€‡à€źà„‡à€œ à€•à„‹ à€à€šà€żà€źà„‡à€Ÿ à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€€à€Ÿà„€ à€žà„à€„à€żà€° à€‡à€źà„‡à€œ à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à„‡à€‚à„€" @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "à€—à€€à€żà€”à€żà€§à€ż à€¶à„‡à€Żà€°à€żà€‚à€—" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "à€—à€€à€żà€”à€żà€§à€ż à€„à„à€°à„‡à€¶à„‹à€Čà„à€Ą" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention} à€”à€° {hereMention} à€•à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡ msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "{PRODUCT_NAME} à€•à„‹ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME} à€źà„‡à€‚ à€…à€Șà€šà„‡ à€•à„ˆà€źà€°à„‡ à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€°à€šà„‡ à€•à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡à€‚à„€" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "{PRODUCT_NAME} à€•à„‹ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME} à€źà„‡à€‚ à€…à€Șà€šà„‡ à€źà€Ÿà€‡à€•à„à€°à„‹à€«à€Œà„‹à€š à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€°à€šà„‡ à€•à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡à€‚à„€" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "{PRODUCT_NAME} à€•à„‹ à€…à€Șà€šà„‡ à€źà€Ÿà€‡à€•à„à€°à„‹à€«à€Œà„‹à€š à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à€šà„‡ à€•à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡à€‚à„€ à€…à€Șà€šà„‡ à€Źà„à€°à€Ÿà€‰à€œà€Œà€° à€•à„‡ à€à€Ąà„à€°à„‡à€ž à€Źà€Ÿà€° à€Żà€Ÿ à€žà„‡à€Ÿà€żà€‚à€—à„à€ž à€źà„‡à€‚ à€œà€Ÿà€à€š à€•à€°à„‡à€‚à„€" @@ -3673,7 +3668,7 @@ msgstr "à€œà€żà€š à€žà€Šà€žà„à€Żà„‹à€‚ à€•à„‡ à€Șà€Ÿà€ž {readMessageHistoryPerm msgid "Allow mentions for this role" msgstr "à€‡à€ž à€°à„‹à€Č à€•à„‡ à€Čà€żà€ à€źà„‡à€‚à€¶à€š à€•à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡à€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "à€źà€Ÿà€‡à€•à„à€°à„‹à€«à€Œà„‹à€š à€•à€Ÿ à€à€•à„à€žà„‡à€ž à€Šà„‡à€‚" @@ -3942,25 +3937,21 @@ msgstr "à€”à€° {remainingCount} à€…à€šà„à€Ż" msgid "Animate on interaction" msgstr "à€‡à€‚à€Ÿà€°à„ˆà€•à„à€¶à€š à€Șà€° à€à€šà€żà€źà„‡à€Ÿ à€•à€°à„‡à€‚" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą {AVIF_FORMAT_LABEL} à€«à€Œà€Ÿà€‡à€Čà„‡à€‚ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà€‚à„€ à€‡à€žà€•à„‡ à€Źà€œà€Ÿà€Ż à€à€• à€žà„à€„à€żà€° {AVIF_FORMAT_LABEL} à€«à€Œà€Ÿà€‡à€Č à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚à„€" - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą {avifFormatLabel} à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° ({ANIMATED_AVATAR_FORMATS}) à€”à€żà€¶à„‡à€· à€°à„‚à€Ș à€žà„‡ {PREMIUM_PRODUCT_NAME} à€žà€Źà„à€žà€•à„à€°à€Ÿà€‡à€Źà€° à€•à„‡ à€Čà€żà€ à€‰à€Șà€Čà€Źà„à€§ à€čà„ˆà€‚à„€" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° ({ANIMATED_AVATAR_FORMATS}) à€‡à€ž à€‡à€‚à€žà„à€Ÿà„‡à€‚à€ž à€Șà€° à€‰à€Șà€Čà€Źà„à€§ à€šà€čà„€à€‚ à€čà„ˆà€‚à„€ à€‡à€žà€•à„‡ à€Źà€œà€Ÿà€Ż à€à€• à€žà„à€„à€żà€° à€‡à€źà„‡à€œ à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚à„€" #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° ({animatedAvatarFormats}) à€•à„‡ à€Čà€żà€ {premiumProductName} à€•à„€ à€†à€”à€¶à„à€Żà€•à€€à€Ÿ à€čà„‹à€€à„€ à€čà„ˆà„€" @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° à€”à€° à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€°" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° à€‰à€Șà€Čà€Źà„à€§ à€šà€čà„€à€‚ à€čà„ˆà€‚" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€°à„‹à€‚ à€•à„‡ à€Čà€żà€ {premiumProductName} à€•à„€ à€†à€”à€¶à„à€Żà€•à€€à€Ÿ à€čà„ˆ" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€‡à€źà„‡à€œ à€•à€Ÿ à€Șà„à€°à„€à€”à„à€Żà„‚" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "à€‡à€ž à€à€žà„‡à€Ÿ à€•à„‡ à€Čà€żà€ à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€‡à€źà„‡à€œ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà€‚à„€" @@ -4947,7 +4938,7 @@ msgstr "à€­à€Ÿà€·à€Ÿ à€…à€Șà€šà„‡ à€†à€Ș à€Șà€čà€šà€Ÿà€šà„‡à€‚" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "à€—à€€à€żà€”à€żà€§à€ż à€„à„à€°à„‡à€¶à„‹à€Čà„à€Ą à€…à€Șà€šà„‡ à€†à€Ș à€žà„‡à€Ÿ à€•à€°à„‡à€‚" @@ -5127,15 +5118,15 @@ msgstr "à€Ąà„‡à€žà„à€•à€Ÿà„‰à€Ș à€à€Ș à€źà„‡à€‚ à€‰à€Șà€Čà€Źà„à€§ à€čà„ˆà„€" #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "à€…à€”à€€à€Ÿà€°" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "à€…à€”à€€à€Ÿà€° à€«à€Œà€Ÿà€‡à€Č à€Źà€čà„à€€ à€Źà€Ąà€Œà„€ à€čà„ˆà„€ {imageMaxSizeLabel} à€žà„‡ à€›à„‹à€Ÿà„€ à€«à€Œà€Ÿà€‡à€Č à€šà„à€šà„‡à€‚à„€" @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "à€…à€”à€€à€Ÿà€° à€Źà€čà„à€€ à€Źà€Ąà€Œà€Ÿ à€čà„ˆà„€ {imageMaxSizeLabel} à€žà„‡ à€›à„‹à€Ÿà€Ÿ à€šà„à€šà„‡à€‚à„€" #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "à€…à€”à€€à€Ÿà€° à€źà„‹à€Ą à€šà„à€šà„‡à€‚" @@ -5187,11 +5178,11 @@ msgstr "à€…à€­à„€ à€Šà„‚à€° à€čà„‚à€" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "à€Źà„ˆà€š à€•à€żà€ à€—à€ à€Żà„‚à€œà€Œà€°" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "à€Źà„ˆà€šà€°" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "à€Źà„ˆà€šà€° à€«à€Œà€Ÿà€‡à€Č à€Źà€čà„à€€ à€Źà€Ąà€Œà„€ à€čà„ˆà„€ {imageMaxSizeLabel} à€žà„‡ à€›à„‹à€Ÿà„€ à€«à€Œà€Ÿà€‡à€Č à€šà„à€šà„‡à€‚à„€" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "à€Źà„ˆà€šà€° à€źà„‹à€Ą à€šà„à€šà„‡à€‚" @@ -6107,8 +6098,8 @@ msgstr "à€Šà„‹à€žà„à€€à„‹à€‚ à€•à„‡ à€žà€Ÿà€„ à€¶à„‡à€Żà€° à€•à€°à€šà„‡ à€•à„‡ msgid "Buy gift" msgstr "à€‰à€Șà€čà€Ÿà€° à€–à€°à„€à€Šà„‡à€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "à€à€• à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Źà€šà€Ÿà€•à€°, à€†à€Ș <0>{PRODUCT_NAME} à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Šà€żà€¶à€Ÿà€šà€żà€°à„à€Šà„‡à€¶à„‹à€‚ à€•à€Ÿ à€Șà€Ÿà€Čà€š à€•à€°à€šà„‡ à€”à€° à€‰à€šà„à€čà„‡à€‚ à€Źà€šà€Ÿà€ à€°à€–à€šà„‡ à€•à„‡ à€Čà€żà€ à€žà€čà€źà€€ à€čà„ˆà€‚à„€" @@ -6361,7 +6352,7 @@ msgstr "à€Żà€čà€Ÿà€‚ à€«à€Œà€Ÿà€‡à€Čà„‡à€‚ à€…à€Șà€Čà„‹à€Ą à€šà€čà„€à€‚ à€•à„€ #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "à€•à„‡à€‚à€Šà„à€°à€żà€€" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "à€…à€”à€€à€Ÿà€° à€Źà€Šà€Čà„‡à€‚" @@ -6627,9 +6618,9 @@ msgstr "à€Źà„ˆà€•à€—à„à€°à€Ÿà€‰à€‚à€Ą à€Źà€Šà€Čà„‡à€‚" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "à€Źà„ˆà€šà€° à€Źà€Šà€Čà„‡à€‚" @@ -6668,13 +6659,13 @@ msgstr "à€—à„à€°à„à€Ș à€•à€Ÿ à€‰à€Șà€šà€Ÿà€ź à€Źà€Šà€Čà„‡à€‚" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "à€†à€‡à€•à„‰à€š à€Źà€Šà€Čà„‡à€‚" @@ -7669,8 +7660,8 @@ msgstr "à€‰à€Șà€čà€Ÿà€° à€•à„à€Čà„‡à€ź à€•à€°à„‡à€‚" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "à€…à€Șà€šà€Ÿ à€…à€•à€Ÿà€‰à€‚à€Ÿ à€•à„à€Čà„‡à€ź à€•à€°à„‡à€‚" @@ -8518,8 +8509,8 @@ msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€žà„‡ à€Čà„‹à€—à„‹à€‚ à€•à€Ÿ à€à€• à€žà€Ÿ msgid "Community filter" msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€«à€Œà€żà€Čà„à€Ÿà€°" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€†à€‡à€•à„‰à€š" @@ -8763,6 +8754,11 @@ msgstr "à€•à€‚à€Șà„‹à€œà€° à€Źà€Ÿà€š" msgid "Composer focus" msgstr "à€•à€‚à€Șà„‹à€œà€° à€«à€Œà„‹à€•à€ž" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "à€žà€‚à€Șà„€à€Ąà€Œà€żà€€ à€čà„‹ à€°à€čà€Ÿ à€čà„ˆ" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "à€•à„ˆà€źà€°à€Ÿ à€Żà€Ÿ à€”à€°à„à€šà„à€…à€Č à€•à„ˆà€Șà„à€šà€° à€Ąà€ż msgid "Connect a display, then try again." msgstr "à€à€• à€Ąà€żà€žà„à€Șà„à€Čà„‡ à€•à€šà„‡à€•à„à€Ÿ à€•à€°à„‡à€‚, à€«à€żà€° à€Šà„‹à€Źà€Ÿà€°à€Ÿ à€Șà„à€°à€Żà€Ÿà€ž à€•à€°à„‡à€‚à„€" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "à€źà€Ÿà€‡à€•à„à€°à„‹à€«à€Œà„‹à€š à€•à€šà„‡à€•à„à€Ÿ à€•à€°à„‡à€‚ à€”à€° à€«à€żà€° à€žà„‡ à€Șà„à€°à€Żà€Ÿà€ž à€•à€°à„‡à€‚à„€" @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "à€Żà€č à€žà„à€Ÿà€żà€•à€° à€šà€čà„€à€‚ à€Źà€šà€Ÿà€Żà€Ÿ à€œà€Ÿ à€žà€•à€Ÿ" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "à€‡à€źà„‡à€œ à€•à„à€°à„‰à€Ș à€šà€čà„€à€‚ à€•à„€ à€œà€Ÿ à€žà€•à„€" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "à€”à„‰à€‡à€ž à€—à€€à€żà€”à€żà€§à€ż à€¶à„‡à€Żà€°à€żà€‚à€— à€…à€­à„€ à€…à€Șà€Ąà„‡à€Ÿ à€šà€čà„€à€‚ à€•à„€ à€œà€Ÿ à€žà€•à„€" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "à€…à€”à€€à€Ÿà€° à€…à€Șà€Čà„‹à€Ą à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€Ÿ" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "à€Źà„ˆà€šà€° à€…à€Șà€Čà„‹à€Ą à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€Ÿ" @@ -10230,7 +10226,7 @@ msgstr "à€Źà€šà€Ÿà€à€ à€”à€° à€¶à„‡à€Żà€° à€•à€°à„‡à€‚" msgid "Create a community" msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Źà€šà€Ÿà€à€" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "à€…à€Șà€šà„‡ à€”à€° à€Šà„‹à€žà„à€€à„‹à€‚ à€•à„‡ à€šà„ˆà€Ÿ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€à€• à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Źà€šà€Ÿà€à€à„€" @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "à€‡à€šà€”à€Ÿà€‡à€Ÿ à€Źà„ˆà€•à€—à„à€°à€Ÿà€‰à€‚à€Ą à€•à„à€°à„‰à€Ș à€•à€°à„‡à€‚" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "à€•à„à€°à„‰à€Ș à€•à€Ÿ à€Șà„‚à€°à„à€”à€Ÿà€”à€Čà„‹à€•à€š" @@ -10500,30 +10496,15 @@ msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€•à„à€°à„‰à€Ș à€•à€°à„‡à€‚" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "à€•à„à€°à„‰à€Ș à€•à„€ à€—à€ˆ à€‡à€źà„‡à€œ à€Źà€čà„à€€ à€Źà€Ąà€Œà„€ à€čà„ˆà„€ à€•à„‹à€ˆ à€›à„‹à€Ÿà€Ÿ à€čà€żà€žà„à€žà€Ÿ à€Żà€Ÿ à€›à„‹à€Ÿà„€ à€«à€Œà€Ÿà€‡à€Č à€šà„à€šà„‡à€‚ (à€…à€§à€żà€•à€€à€ź {maxSizeLabel})à„€" -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą {formatLabel} à€«à€Œà€Ÿà€‡à€Čà„‹à€‚ à€•à„‹ à€•à„à€°à„‰à€Ș à€•à€°à€šà€Ÿ à€…à€­à„€ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà„€ à€źà„‚à€Č à€‡à€źà„‡à€œ à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€" - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą {formatLabel} à€«à€Œà€Ÿà€‡à€Čà„‹à€‚ à€•à„‹ à€•à„à€°à„‰à€Ș à€•à€°à€šà€Ÿ à€…à€­à„€ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà„€ à€źà„‚à€Č à€…à€Șà€Čà„‹à€Ą à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€" - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€«à€Œà€Ÿà€‡à€Čà„‹à€‚ à€•à„‹ à€•à„à€°à„‰à€Ș à€•à€°à€šà€Ÿ à€…à€­à„€ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà„€ à€źà„‚à€Č à€‡à€źà„‡à€œ à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€" - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€«à€Œà€Ÿà€‡à€Čà„‹à€‚ à€•à„‹ à€•à„à€°à„‰à€Ș à€•à€°à€šà€Ÿ à€…à€­à„€ à€žà€źà€°à„à€„à€żà€€ à€šà€čà„€à€‚ à€čà„ˆà„€ à€źà„‚à€Č à€…à€Șà€Čà„‹à€Ą à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€" +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "{percent}% à€•à„à€°à„‰à€Ș à€čà„‹ à€°à€čà€Ÿ à€čà„ˆ" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "à€…à€•à€Ÿà€‰à€‚à€Ÿ à€šà€čà„€à€‚ à€čà„ˆ?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "à€š à€Šà€żà€–à€Ÿà€à€" @@ -16560,8 +16541,8 @@ msgstr "à€—à„à€°à„à€Ș DM à€…à€”à€€à€Ÿà€° à€°à„‡à€—à„à€Čà€° à€…à€”à€€à€Ÿà€° msgid "Group DMs" msgstr "à€—à„à€°à„à€Ș DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "à€—à„à€°à„à€Ș à€†à€‡à€•à„‰à€š" @@ -16624,8 +16605,8 @@ msgstr "à€—à„à€°à„à€Ș à€žà„‡à€Ÿà€żà€‚à€—à„à€ž" msgid "Group typing states" msgstr "à€—à„à€°à„à€Ș à€Ÿà€Ÿà€‡à€Șà€żà€‚à€— à€žà„à€Ÿà„‡à€Ÿà€ž" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "à€—à„à€°à„à€Ș à€…à€Șà€Ąà„‡à€Ÿ à€•à€żà€Żà€Ÿ à€—à€Żà€Ÿ" @@ -16803,7 +16784,7 @@ msgstr "à€Šà€żà€Č" msgid "Hebrew" msgstr "à€čà€żà€Źà„à€°à„‚" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "à€Šà€à€šà€Ÿà€ˆ" @@ -17510,7 +17491,7 @@ msgstr "à€‡à€źà„‡à€œ à€•à„à€Čà€żà€Șà€Źà„‹à€°à„à€Ą à€Șà€° à€•à„‰à€Șà„€ à€•à„€ #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "à€‡à€źà„‡à€œ à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€Ÿ" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "à€Šà€żà€–à€Ÿà€”à€Ÿ à€”à€° à€…à€šà„à€­à€”" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "à€Čà€—à€€à€Ÿ à€čà„ˆ à€†à€Ș {0} à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€° à€°à€čà„‡ à€čà„ˆà€‚à„€ {PRODUCT_NAME} à€•à„€ à€Șà„à€°à„‹à€žà„‡à€žà€żà€‚à€— à€•à„‹ à€‡à€žà€•à„‡ à€Šà€Șà€° à€°à€–à€šà„‡ à€žà„‡ à€Șà€‚à€Șà€żà€‚à€— à€Żà€Ÿ à€Ąà€żà€žà„à€Ÿà„‰à€°à„à€¶à€š à€čà„‹ à€žà€•à€€à€Ÿ à€čà„ˆà„€ à€Ąà€Ÿà€Żà€°à„‡à€•à„à€Ÿ à€‡à€šà€Șà„à€Ÿ à€†à€Șà€•à„‡ à€‘à€Ąà€żà€Żà„‹ à€•à„‹ à€Źà€żà€šà€Ÿ à€•à€żà€žà„€ à€Źà€Šà€Čà€Ÿà€” à€•à„‡ à€Șà€Ÿà€ž à€•à€°à€€à€Ÿ à€čà„ˆà„€" @@ -22577,7 +22558,7 @@ msgstr "à€•à„‹à€ˆ à€źà€żà€Čà€Ÿà€š à€šà€čà„€à€‚ à€źà€żà€Čà€Ÿ" msgid "No mentions yet" msgstr "à€…à€­à„€ à€€à€• à€•à„‹à€ˆ à€źà„‡à€‚à€¶à€š à€šà€čà„€à€‚ à€čà„ˆ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "à€•à„‹à€ˆ à€źà€Ÿà€‡à€•à„à€°à„‹à€«à€Œà„‹à€š à€šà€čà„€à€‚ à€źà€żà€Čà€Ÿ" @@ -23806,7 +23787,7 @@ msgstr "à€žà€żà€žà„à€Ÿà€ź DM à€–à„‹à€Čà„‡à€‚" msgid "Open system picker" msgstr "à€žà€żà€žà„à€Ÿà€ź à€Șà€żà€•à€° à€–à„‹à€Čà„‡à€‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "à€Ÿà„‡à€źà„à€Șà€Čà„‡à€Ÿ JSON à€–à„‹à€Čà„‡à€‚" @@ -23820,7 +23801,7 @@ msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€•à„‡ à€Čà€żà€ à€Źà„ˆà€š à€Ąà€Ÿà€Ż msgid "Open the context menu" msgstr "à€•à„‰à€šà„à€Ÿà„‡à€•à„à€žà„à€Ÿ à€źà„‡à€šà„à€Żà„‚ à€–à„‹à€Čà„‡à€‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "à€šà„€à€šà„‡ à€Šà€żà€ à€—à€ à€Čà€żà€‚à€• à€•à„‹ à€…à€Șà€šà„‡ à€Źà„à€°à€Ÿà€‰à€œà€Œà€° à€źà„‡à€‚ à€–à„‹à€Čà„‡à€‚, à€«à€żà€° à€Șà„‚à€°à„‡ JSON à€°à€żà€žà„à€Șà„‰à€šà„à€ž à€•à„‹ à€•à„‰à€Șà„€ à€•à€°à€•à„‡ à€Źà„‰à€•à„à€ž à€źà„‡à€‚ à€Șà„‡à€žà„à€Ÿ à€•à€°à„‡à€‚à„€" @@ -24331,7 +24312,7 @@ msgstr "à€Șà€żà€›à€Čà„‡ 7 à€Šà€żà€š" msgid "Paste" msgstr "à€Șà„‡à€žà„à€Ÿ à€•à€°à„‡à€‚" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "{theOtherPlatform} à€Ÿà„‡à€źà„à€Șà€Čà„‡à€Ÿ à€Żà„‚à€†à€°à€à€Č à€Șà„‡à€žà„à€Ÿ à€•à€°à„‡à€‚ à€”à€° à€‰à€žà€•à„€ à€žà€‚à€°à€šà€šà€Ÿ à€•à€żà€žà„€ à€šà€ˆ à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€źà„‡à€‚ à€‡à€‚à€Șà„‹à€°à„à€Ÿ à€•à€°à„‡à€‚à„€" @@ -25191,6 +25172,11 @@ msgstr "à€Șà„à€°à„€à€źà€żà€Żà€ź à€Șà„à€°à€•à€Ÿà€°" msgid "Premium until date" msgstr "à€‡à€ž à€€à€Ÿà€°à„€à€– à€€à€• à€Șà„à€°à„€à€źà€żà€Żà€ź" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "à€€à„ˆà€Żà€Ÿà€° à€čà„‹ à€°à€čà€Ÿ à€čà„ˆ" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č" msgid "Profile badge" msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€œ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€à€• {PREMIUM_PRODUCT_NAME} à€žà„à€”à€żà€§à€Ÿ à€čà„ˆà„€ à€…à€Șà€šà„€ à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€źà„‡à€‚ à€Źà„ˆà€šà€° à€œà„‹à€Ąà€Œà€šà„‡ à€•à„‡ à€Čà€żà€ {PREMIUM_PRODUCT_NAME} à€Șà„à€°à€Ÿà€Șà„à€€ à€•à€°à„‡à€‚à„€" #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "à€‡à€ž à€‡à€‚à€žà„à€Ÿà„‡à€‚à€ž à€Șà€° à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€žà€•à„à€·à€ź à€šà€čà„€à€‚ à€čà„ˆà€‚à„€" #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€•à„‡ à€Čà€żà€ {premiumProductName} à€œà€Œà€°à„‚à€°à„€ à€čà„ˆ" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€•à„‡ à€Čà€żà€ {premiumProductName} à€œà€Œà€°à„‚à€°à„€ à€čà„ˆà„€" @@ -25838,7 +25824,7 @@ msgstr "à€Șà„à€¶-à€Ÿà„‚-à€Ÿà„‰à€•" msgid "Push-to-talk (limited)" msgstr "à€Șà„à€¶-à€Ÿà„‚-à€Ÿà„‰à€• (à€žà„€à€źà€żà€€)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "à€žà„€à€§à€Ÿ à€‡à€šà€Șà„à€Ÿ à€źà„‹à€Ą à€źà„‡à€‚ à€Șà„à€¶-à€Ÿà„‚-à€Ÿà„‰à€• à€•à„‹ à€…à€šà€Šà„‡à€–à€Ÿ à€•à€żà€Żà€Ÿ à€œà€Ÿà€€à€Ÿ à€čà„ˆà„€ à€‡à€žà„‡ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€«à€Œà„‹à€•à€žà„à€Ą à€”à„‰à€‡à€ž à€Żà€Ÿ à€•à€žà„à€Ÿà€ź à€Șà€° à€žà„à€”à€żà€š à€•à€°à„‡à€‚à„€" @@ -26551,8 +26537,8 @@ msgstr "à€…à€Ÿà„ˆà€šà€źà„‡à€‚à€Ÿ à€čà€Ÿà€Ÿà€à€" msgid "Remove authenticator app" msgstr "à€‘à€„à„‡à€‚à€Ÿà€żà€•à„‡à€Ÿà€° à€à€Ș à€čà€Ÿà€Ÿà€à€" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "à€…à€”à€€à€Ÿà€° à€čà€Ÿà€Ÿà€à€" @@ -26561,8 +26547,8 @@ msgstr "à€…à€”à€€à€Ÿà€° à€čà€Ÿà€Ÿà€à€" msgid "Remove background" msgstr "à€Źà„ˆà€•à€—à„à€°à€Ÿà€‰à€‚à€Ą à€čà€Ÿà€Ÿà€à€" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "à€Źà„ˆà€šà€° à€čà€Ÿà€Ÿà€à€" @@ -26625,10 +26611,10 @@ msgstr "à€žà€Źà€žà„‡ à€Šà€Șà€° à€°à€–à€šà€Ÿ à€Źà€‚à€Š à€•à€°à„‡à€‚" msgid "Remove from URL-only GIF favorites" msgstr "à€žà€żà€°à„à€«à€Œ URL à€”à€Ÿà€Čà„‡ à€Șà€žà€‚à€Šà„€à€Šà€Ÿ GIF à€žà„‡ à€čà€Ÿà€Ÿà€à€" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "à€†à€‡à€•à„‰à€š à€čà€Ÿà€Ÿà€à€" @@ -27331,7 +27317,7 @@ msgstr "à€«à€żà€° à€žà„‡ à€­à„‡à€œà€Ÿ à€—à€Żà€Ÿ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "à€°à„€à€žà„‡à€Ÿ à€•à€°à„‡à€‚" @@ -28074,7 +28060,7 @@ msgstr "à€°à„‹à€źà€Ÿà€šà€żà€Żà€Ÿà€ˆ" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "à€˜à€Ąà€Œà„€ à€•à„€ à€Šà€żà€¶à€Ÿ à€źà„‡à€‚ à€˜à„à€źà€Ÿà€à€" @@ -28153,8 +28139,8 @@ msgstr "à€žà„ˆà€šà„à€°à„‡à€¶à€š" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€° à€à€šà„à€•à„‹à€Ąà€° à€•à€‚à€Ÿà„à€°à„‹à€Č" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€° à€žà€źà€Ÿà€Șà„à€€ à€čà„‹ à€—à€Żà€Ÿ" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "à€œà€Ź à€†à€Șà€•à„‡ à€Șà€Ÿà€ž à€…à€Șà€ à€żà€€ à€źà„ˆà€žà„‡à€œ à€čà„‹à€‚, à€€à„‹ à€à€Ș à€†à€‡à€•à„‰à€š à€Șà€° à€Čà€Ÿà€Č à€Źà„ˆà€œ à€Šà€żà€–à€Ÿà€à€" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "à€•à„‡à€”à€Č à€à€•à„à€žà„‡à€‚à€Ÿ à€°à€‚à€— à€Šà€żà€–à€Ÿà€à€‚, à€…à€Șà€šà„€ à€—à„à€Čà„‹à€Źà€Č à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€•à„‹ à€…à€šà€Šà„‡à€–à€Ÿ à€•à€°à„‡à€‚" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "à€à€•à„à€žà€Șà„à€°à„‡à€¶à€š à€‘à€Ÿà„‹-à€•à€źà„à€Șà„à€Čà„€à€Ÿ à€źà„‡à€‚ à€•à€žà„à€Ÿà€ź à€‡à€źà„‹à€œà„€ à€Šà€żà€–à€Ÿà€à€‚" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "à€Ąà€żà€«à€Œà„‰à€Čà„à€Ÿ à€…à€”à€€à€Ÿà€° à€Šà€żà€–à€Ÿà€à€‚, à€…à€Șà€šà„€ à€—à„à€Čà„‹à€Źà€Č à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€•à„‹ à€…à€šà€Šà„‡à€–à€Ÿ à€•à€°à„‡à€‚" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "à€źà„à€Żà„‚à€Ÿ à€•à€żà€ à€—à€ à€šà„ˆà€šà€Čà„‹à€‚ à€Șà€° à€š à€Șà€ąà€Œà„‡ à€—à€ à€‡à€‚à€Ąà€żà€•à„‡à€Ÿà€° à€Šà€żà€–à€Ÿà€à€‚" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€źà„‡à€‚ à€…à€Șà€šà€Ÿ à€—à„à€Čà„‹à€Źà€Č à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€…à€”à€€à€Ÿà€° à€Šà€żà€–à€Ÿà€à€‚" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€źà„‡à€‚ à€…à€Șà€šà€Ÿ à€—à„à€Čà„‹à€Źà€Č à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€Šà€żà€–à€Ÿà€à€‚" @@ -30720,7 +30706,7 @@ msgstr "à€›à„‹à€Ąà€Œà„‡à€‚" msgid "Skip \"Mark all as read\" confirmation" msgstr "\"à€žà€­à„€ à€•à„‹ à€Șà€ąà€Œà€Ÿ à€—à€Żà€Ÿ à€źà€Ÿà€°à„à€• à€•à€°à„‡à€‚\" à€•à„€ à€Șà„à€·à„à€Ÿà€ż à€›à„‹à€Ąà€Œà„‡à€‚" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "à€•à„à€°à„‰à€Ș à€•à€°à€šà€Ÿ à€›à„‹à€Ąà€Œà„‡à€‚" @@ -32346,7 +32332,7 @@ msgstr "à€†à€°à€Ÿà€źà€Šà€Ÿà€Żà€• à€Čà„‡à€†à€‰à€Ÿ à€Șà€° à€žà„à€”à€żà€š à€•à€° msgid "Switch to dense layout" msgstr "à€žà€˜à€š à€Čà„‡à€†à€‰à€Ÿ à€Șà€° à€žà„à€”à€żà€š à€•à€°à„‡à€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "à€žà„€à€§à„‡ à€‡à€šà€Șà„à€Ÿ à€Șà€° à€žà„à€”à€żà€š à€•à€°à„‡à€‚" @@ -32734,7 +32720,7 @@ msgstr "à€Ÿà€Ÿà€žà„à€•" msgid "Teleporting you to another voice region..." msgstr "à€Šà„‚à€žà€°à„‡ à€”à„‰à€‡à€ž à€°à„€à€œà€š à€źà„‡à€‚ à€Ÿà„‡à€Čà„€à€Șà„‹à€°à„à€Ÿ à€•à€° à€°à€čà„‡ à€čà„ˆà€‚..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "à€Ÿà„‡à€źà„à€Șà€Čà„‡à€Ÿ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "à€°à„‹à€Č à€šà„‡ {permissions} à€Șà„à€°à€Šà€Ÿà€š à€•à„€à€‚" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€° à€žà„à€°à„‹à€€ à€šà„‡ à€”à„€à€Ąà€żà€Żà„‹ à€­à„‡à€œà€šà€Ÿ à€Źà€‚à€Š à€•à€° à€Šà€żà€Żà€Ÿ à€čà„ˆ, à€‡à€žà€Čà€żà€ à€†à€Șà€•à€Ÿ à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€° à€°à„‹à€• à€Šà€żà€Żà€Ÿ à€—à€Żà€Ÿà„€" @@ -33453,6 +33439,11 @@ msgstr "à€‡à€ž à€…à€•à€Ÿà€‰à€‚à€Ÿ à€•à„‹ à€Źà„à€Čà„‰à€• à€šà€čà„€à€‚ à€•à€żà€Ż msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "à€Żà€č à€•à€Ÿà€°à„à€°à€”à€Ÿà€ˆ à€Șà„‚à€°à„à€”à€”à€€ à€šà€čà„€à€‚ à€•à„€ à€œà€Ÿ à€žà€•à€€à„€à„€ à€Źà„‰à€Ÿ à€Żà„‚à€œà€Œà€° à€žà€čà€żà€€ à€žà€­à„€ à€žà€‚à€Źà€‚à€§à€żà€€ à€Ąà„‡à€Ÿà€Ÿ à€žà„à€„à€Ÿà€Żà„€ à€°à„‚à€Ș à€žà„‡ à€čà€Ÿà€Ÿ à€Šà€żà€Żà€Ÿ à€œà€Ÿà€à€—à€Ÿà„€" +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "à€Żà€č à€à€šà„€à€źà„‡à€¶à€š à€•à„à€°à„‰à€Ș à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€Źà€čà„à€€ à€Čà€‚à€Źà€Ÿ à€Żà€Ÿ à€Źà€čà„à€€ à€Źà€Ąà€Œà€Ÿ à€čà„ˆà„€ à€à€• à€›à„‹à€Ÿà„€ à€Żà€Ÿ à€čà€Čà„à€•à„€ à€«à€Œà€Ÿà€‡à€Č à€†à€œà€Œà€źà€Ÿà€à€à„€" + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "à€Żà€č à€Źà„‰à€Ÿ à€žà€Ÿà€°à„à€”à€œà€šà€żà€• à€šà€čà„€à€‚ à€čà„ˆ à€”à€° msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "à€Żà€č à€Źà„‰à€Ÿ à€à€Ąà€źà€żà€šà€żà€žà„à€Ÿà„à€°à„‡à€Ÿà€° à€•à„€ à€…à€šà„à€źà€€à€ż à€•à€Ÿ à€…à€šà„à€°à„‹à€§ à€•à€°à€€à€Ÿ à€čà„ˆà„€ à€‡à€žà„‡ à€€à€­à„€ à€…à€šà„à€źà€€à€ż à€Šà„‡à€‚ à€œà€Ź à€†à€Ș à€Ąà„‡à€”à€Čà€Șà€° à€Șà€° à€Șà„‚à€°à„€ à€€à€°à€č à€­à€°à„‹à€žà€Ÿ à€•à€°à€€à„‡ à€čà„‹à€‚à„€ à€‡à€žà€•à„‡ à€Źà€œà€Ÿà€Ż à€‰à€šà€žà„‡ à€•à€ź à€…à€šà„à€źà€€à€żà€Żà„‹à€‚ à€•à€Ÿ à€…à€šà„à€°à„‹à€§ à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€•à€čà„‡à€‚à„€ à€Żà€Šà€ż à€…à€šà€żà€¶à„à€šà€żà€€ à€čà„ˆà€‚ à€€à„‹ à€‡à€ž à€Șà„‡à€œ à€•à„‹ à€Źà€‚à€Š à€•à€° à€Šà„‡à€‚à„€" +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "à€Żà€č à€Źà„à€°à€Ÿà€‰à€œà€Œà€° à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą {avifFormatLabel} à€«à€Œà€Ÿà€‡à€Čà„‹à€‚ à€•à„‹ à€•à„à€°à„‰à€Ș à€šà€čà„€à€‚ à€•à€° à€žà€•à€€à€Ÿ à€čà„ˆà„€ à€‡à€žà€•à„‡ à€Źà€œà€Ÿà€Ż GIF à€Żà€Ÿ WebP à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚à„€" + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "à€Żà€č à€Źà„à€°à€Ÿà€‰à€œà€Œà€° à€•à€‚à€žà„‹à€Č à€à€• à€Ąà„‡à€”à€Čà€Șà€° à€Ÿà„‚à€Č à€čà„ˆà„€" +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "à€‡à€ž à€Źà„à€°à€Ÿà€‰à€œà€Œà€° à€źà„‡à€‚ à€”à„‡à€Źà€…à€žà„‡à€‚à€Źà€Čà„€ à€Źà€‚à€Š à€čà„ˆ, à€‡à€žà€Čà€żà€ à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€‡à€źà„‡à€œ à€•à„‹ à€•à„à€°à„‰à€Ș à€šà€čà„€à€‚ à€•à€żà€Żà€Ÿ à€œà€Ÿ à€žà€•à€€à€Ÿ à€čà„ˆà„€" + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "à€Żà€č à€—à„à€°à„à€Ș à€­à€°à€Ÿ à€čà„à€† à€čà„ˆà„€ à€”à€° à€Čà„‹à€—à„‹ msgid "This handoff code has expired. Generate a new one to continue." msgstr "à€Żà€č à€čà„ˆà€‚à€Ąà€‘à€«à€Œ à€•à„‹à€Ą à€žà€źà€Ÿà€Șà„à€€ à€čà„‹ à€—à€Żà€Ÿ à€čà„ˆà„€ à€œà€Ÿà€°à„€ à€°à€–à€šà„‡ à€•à„‡ à€Čà€żà€ à€à€• à€šà€Żà€Ÿ à€•à„‹à€Ą à€œà€šà€°à„‡à€Ÿ à€•à€°à„‡à€‚à„€" +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "à€Żà€č à€‡à€źà„‡à€œ à€Șà€ąà€Œà„€ à€šà€čà„€à€‚ à€œà€Ÿ à€žà€•à„€à„€ à€Żà€č à€–à€°à€Ÿà€Ź à€čà„‹ à€žà€•à€€à„€ à€čà„ˆà„€" + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€•à„‡ à€Čà€żà€ à€à€• à€•à€žà„à€Ÿà€ź à€…à€”à€€à€Ÿà€° à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€•à„‡ à€Čà€żà€ à€à€• à€•à€žà„à€Ÿà€ź à€Źà„ˆà€šà€° à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚" @@ -36155,10 +36163,10 @@ msgstr "à€źà„ˆà€žà„‡à€œ à€źà„‡à€‚ à€«à€Œà€Ÿà€‡à€Č à€”à€° à€źà„€à€Ąà€żà€Żà€Ÿ à€… msgid "Upload files and media in this channel." msgstr "à€‡à€ž à€šà„ˆà€šà€Č à€źà„‡à€‚ à€«à€Œà€Ÿà€‡à€Čà„‡à€‚ à€”à€° à€źà„€à€Ąà€żà€Żà€Ÿ à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚à„€" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "à€†à€‡à€•à„‰à€š à€…à€Șà€Čà„‹à€Ą à€•à€°à„‡à€‚" @@ -36401,8 +36409,8 @@ msgstr "à€•à„‹à€Č à€„à„€à€ź à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à„‡à€‚ (à€Șà„‚à€°à„€ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "à€•à€žà„à€Ÿà€ź à€‡à€źà„‡à€œ à€•à€Ÿ à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à„‡à€‚" @@ -36462,8 +36470,8 @@ msgstr "à€źà„ˆà€žà„‡à€œ à€ąà„‚à€‚à€ąà€šà„‡ à€•à„‡ à€Čà€żà€ à€«à€Œà€żà€Čà„à€Ÿ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "à€—à„à€Čà„‹à€Źà€Č à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€•à€Ÿ à€‰à€Șà€Żà„‹à€— à€•à€°à„‡à€‚" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "à€”à„‰à€‡à€ž à€Șà„à€°à€€à€żà€­à€Ÿà€—à„€" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "à€”à„‰à€‡à€ž à€Șà„à€°à„‹à€žà„‡à€žà€żà€‚à€—" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "à€”à€żà€žà„à€•à„‰à€šà„à€žà€żà€š" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "{PREMIUM_PRODUCT_NAME} à€•à„‡ à€žà€Ÿà€„ à€†à€Ș à€à€šà€żà€źà„‡à€Ÿà„‡à€Ą à€…à€”à€€à€Ÿà€° ({ANIMATED_AVATAR_FORMATS}) à€”à€° à€Șà„à€°à„‹à€«à€Œà€Ÿà€‡à€Č à€Źà„ˆà€šà€° à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚, à€…à€Șà€šà€Ÿ à€Ÿà„ˆà€— à€•à€žà„à€Ÿà€źà€Ÿà€‡à€œà€Œ à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚ à€”à€° {PREMIUM_PRODUCT_NAME} à€•à„‡ à€•à€ˆ à€Šà„‚à€žà€°à„‡ à€Șà€°à„à€• à€…à€šà€Čà„‰à€• à€•à€° à€žà€•à€€à„‡ à€čà„ˆà€‚à„€" @@ -39334,8 +39342,8 @@ msgstr "à€Żà€čà€Ÿà€‚ à€…à€šà„à€Ż à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€žà„‡ à€‡à€źà„‹ msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "à€Żà€čà€Ÿà€‚ à€…à€šà„à€Ż à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€žà„‡ à€žà„à€Ÿà€żà€•à€° à€‡à€žà„à€€à„‡à€źà€Ÿà€Č à€•à€°à€šà„‡ à€•à„‡ à€Čà€żà€ à€†à€Șà€•à„‹ \"{permissionLabel}\" à€…à€šà„à€źà€€à€ż à€šà€Ÿà€čà€żà€à„€" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Źà€šà€Ÿà€šà„‡ à€žà„‡ à€Șà€čà€Čà„‡ à€†à€Șà€•à„‹ à€…à€Șà€šà€Ÿ à€…à€•à€Ÿà€‰à€‚à€Ÿ à€•à„à€Čà„‡à€ź à€•à€°à€šà€Ÿ à€čà„‹à€—à€Ÿà„€" @@ -39356,8 +39364,8 @@ msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€źà„‡à€‚ à€źà„ˆà€žà„‡à€œ à€­à„‡à€œ msgid "You need to verify a phone number to send messages in this community." msgstr "à€‡à€ž à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€źà„‡à€‚ à€źà„ˆà€žà„‡à€œ à€­à„‡à€œà€šà„‡ à€•à„‡ à€Čà€żà€ à€†à€Șà€•à„‹ à€«à€Œà„‹à€š à€šà€‚à€Źà€° à€”à„‡à€°à€żà€«à€Œà€Ÿà€ˆ à€•à€°à€šà€Ÿ à€čà„‹à€—à€Ÿà„€" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "à€•à€źà„à€Żà„à€šà€żà€Ÿà„€ à€Źà€šà€Ÿà€šà„‡ à€žà„‡ à€Șà€čà€Čà„‡ à€†à€Șà€•à„‹ à€…à€Șà€šà€Ÿ à€ˆà€źà„‡à€Č à€Șà€€à€Ÿ à€”à„‡à€°à€żà€«à€Œà€Ÿà€ˆ à€•à€°à€šà€Ÿ à€čà„‹à€—à€Ÿà„€" @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "à€†à€Șà€•à€Ÿ à€žà€čà„‡à€œà€Ÿ à€—à€Żà€Ÿ {savedResolution} {savedFrameRate} FPS à€Șà€° {premiumProductName} à€•à„€ à€†à€”à€¶à„à€Żà€•à€€à€Ÿ à€čà„ˆ, à€‡à€žà€Čà€żà€ à€¶à„‡à€Żà€° {resolution} {frameRate} FPS à€Șà€° à€‰à€Șà€Żà„‹à€— à€•à€°à€€à„‡ à€čà„ˆà€‚à„€" #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "à€†à€Șà€•à€Ÿ à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€° à€•à€żà€žà„€ à€•à€źà„à€Șà„ˆà€Ÿà€żà€Źà€Č à€”à„€à€Ąà€żà€Żà„‹ à€•à„‹à€Ąà„‡à€• à€•à„‡ à€žà€Ÿà€„ à€Șà€Źà„à€Čà€żà€¶ à€šà€čà„€à€‚ à€čà„‹ à€žà€•à€Ÿ, à€‡à€žà€Čà€żà€ à€‡à€žà„‡ à€°à„‹à€• à€Šà€żà€Żà€Ÿ à€—à€Żà€Ÿà„€ à€«à€żà€° à€žà„‡ à€¶à„‡à€Żà€° à€•à€°à€šà„‡ à€•à„€ à€•à„‹à€¶à€żà€¶ à€•à€°à„‡à€‚à„€" @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "à€†à€Șà€•à€Ÿ à€”à„ˆà€šà€żà€Ÿà„€ à€Żà„‚à€†à€°à€à€Č {inviteEndpoint}/{vanitySlug} à€Șà€° à€žà„‡à€Ÿ à€•à€° à€Šà€żà€Żà€Ÿ à€—à€Żà€Ÿ à€čà„ˆ" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "à€†à€Șà€•à„‡ à€”à„€à€Ąà€żà€Żà„‹ à€à€šà„à€•à„‹à€Ąà€° à€šà„‡ à€«à€Œà„à€°à„‡à€ź à€à€šà„à€•à„‹à€Ą à€•à€°à€šà€Ÿ à€Źà€‚à€Š à€•à€° à€Šà€żà€Żà€Ÿ, à€‡à€žà€Čà€żà€ à€†à€Șà€•à„€ à€žà„à€•à„à€°à„€à€š à€¶à„‡à€Żà€°à€żà€‚à€— à€°à„‹à€• à€Šà„€ à€—à€ˆà„€ à€«à€żà€° à€žà„‡ à€¶à„‡à€Żà€° à€•à€°à€šà„‡ à€•à„€ à€•à„‹à€¶à€żà€¶ à€•à€°à„‡à€‚à„€" @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "à€œà€Œà„‚à€ź" diff --git a/fluxer_app/src/features/i18n/locales/hr/messages.po b/fluxer_app/src/features/i18n/locales/hr/messages.po index 31141ac5d..7c5181f98 100644 --- a/fluxer_app/src/features/i18n/locales/hr/messages.po +++ b/fluxer_app/src/features/i18n/locales/hr/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, uskoro" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Dimenzije za {label} ne odgovaraju ovom resursu. Odaberite drugu sliku ili prenesite statičnu sliku koju moĆŸete obrezati." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Datoteka za {label} je prevelika. Odaberite datoteku manju od {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Slike za {label} ne mogu biti animirane. Koristite statičnu sliku." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Dijeljenje aktivnosti" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Prag aktivnosti" @@ -3566,11 +3561,11 @@ msgstr "Dopusti {everyoneMention} i {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Dopustite aplikaciji {PRODUCT_NAME} pristup vaĆĄoj kameri u {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Dopustite aplikaciji {PRODUCT_NAME} pristup mikrofonu u {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Dopustite aplikaciji {PRODUCT_NAME} pristup mikrofonu. Provjerite adresnu traku ili postavke preglednika." @@ -3673,7 +3668,7 @@ msgstr "Dopusti članovima bez dopuĆĄtenja {readMessageHistoryPermissionLabel} d msgid "Allow mentions for this role" msgstr "Dopusti spominjanje za ovu ulogu" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Dopusti mikrofon" @@ -3942,25 +3937,21 @@ msgstr "i joĆĄ {remainingCount}" msgid "Animate on interaction" msgstr "Animiraj pri interakciji" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animirane {AVIF_FORMAT_LABEL} datoteke nisu podrĆŸane. Umjesto toga prenesite statičnu {AVIF_FORMAT_LABEL} datoteku." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animirani {avifFormatLabel} nije podrĆŸan" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animirani avatari ({ANIMATED_AVATAR_FORMATS}) dostupni su samo pretplatnicima na {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animirani avatari ({ANIMATED_AVATAR_FORMATS}) nisu dostupni na ovoj instanci. Umjesto toga prenesite statičnu sliku." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animirani avatari ({animatedAvatarFormats}) zahtijevaju {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animirani avatari i naslovne slike profila" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animirani avatari nisu dostupni" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animirani avatari zahtijevaju {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Pregled animirane slike" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animirane slike nisu podrĆŸane za ovaj resurs." @@ -4947,7 +4938,7 @@ msgstr "Automatsko prepoznavanje jezika" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Automatsko postavljanje praga aktivnosti" @@ -5127,15 +5118,15 @@ msgstr "Dostupno u aplikaciji za stolna računala." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Datoteka avatara je prevelika. Odaberite datoteku manju od {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar je prevelik. Odaberite manji od {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Odabir načina avatara" @@ -5187,11 +5178,11 @@ msgstr "Trenutno odsutan" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Zabranjeni korisnici" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Naslovna slika" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Datoteka naslovne slike je prevelika. Odaberite datoteku manju od {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Odabir načina naslovne slike" @@ -6107,8 +6098,8 @@ msgstr "Kupite poklon {premiumProductName} na kartici {premiumProductName} i pod msgid "Buy gift" msgstr "Kupi poklon" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Stvaranjem zajednice pristajete slijediti i podrĆŸavati <0>smjernice zajednice {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Ovdje nije moguće učitati datoteke" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrirano" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Promijeni avatar" @@ -6627,9 +6618,9 @@ msgstr "Promijeni pozadinu" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Promijeni naslovnu sliku" @@ -6668,13 +6659,13 @@ msgstr "Promijeni nadimak u grupi" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Promijeni ikonu" @@ -7669,8 +7660,8 @@ msgstr "Preuzmi poklon" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Preuzmite svoj račun" @@ -8518,8 +8509,8 @@ msgstr "Zajednica olakĆĄava grupne napade ili ciljano zlostavljanje." msgid "Community filter" msgstr "Filtar zajednice" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ikona zajednice" @@ -8763,6 +8754,11 @@ msgstr "Gumbi za sastavljanje poruka" msgid "Composer focus" msgstr "Fokusiranje sastavljača" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimiranje" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "PoveĆŸite kameru ili virtualni uređaj za snimanje, pa pokuĆĄajte ponovn msgid "Connect a display, then try again." msgstr "PoveĆŸite zaslon, a zatim pokuĆĄajte ponovno." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "PoveĆŸite mikrofon i pokuĆĄajte ponovno." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nije moguće stvoriti ovu naljepnicu" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Nije moguće obrezati sliku" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Trenutačno nije moguće aĆŸurirati dijeljenje glasovne aktivnosti" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nije moguće učitati avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nije moguće učitati naslovnu sliku" @@ -10230,7 +10226,7 @@ msgstr "Stvori i podijeli" msgid "Create a community" msgstr "Stvori zajednicu" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Stvorite zajednicu za dopisivanje s prijateljima." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "ObreĆŸi pozadinu pozivnice" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Pretpregled obrezivanja" @@ -10500,30 +10496,15 @@ msgstr "ObreĆŸi naslovnu sliku profila" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Obrezana slika je prevelika. Odaberite manje područje ili manju datoteku (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Obrezivanje animiranih datoteka formata {formatLabel} joĆĄ nije podrĆŸano. Koristit će se izvorna slika." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Obrezivanje animiranih datoteka formata {formatLabel} joĆĄ nije podrĆŸano. Koristit će se izvorna datoteka." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Obrezivanje animiranih datoteka joĆĄ nije podrĆŸano. Koristit će se izvorna slika." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Obrezivanje animiranih datoteka joĆĄ nije podrĆŸano. Koristit će se izvorna datoteka." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Obrezivanje {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Nemate račun?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Ne prikazuj" @@ -16560,8 +16541,8 @@ msgstr "Avatari grupnih izravnih poruka koriste iste maske statusa kao i obični msgid "Group DMs" msgstr "Grupne izravne poruke" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ikona grupe" @@ -16624,8 +16605,8 @@ msgstr "Postavke grupe" msgid "Group typing states" msgstr "Status tipkanja u grupi" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupa aĆŸurirana" @@ -16803,7 +16784,7 @@ msgstr "Srce" msgid "Hebrew" msgstr "Hebrejski" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Visina" @@ -17510,7 +17491,7 @@ msgstr "Slika kopirana u međuspremnik" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Slika se ne moĆŸe koristiti" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Izgled i dojam" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Čini se da koristite {0}. Dodatna obrada u {PRODUCT_NAME}u povrh toga moĆŸe uzrokovati pumpanje ili izobličenje zvuka. Izravan unos propuĆĄta vaĆĄ zvuk netaknutim." @@ -22577,7 +22558,7 @@ msgstr "Nema rezultata" msgid "No mentions yet" msgstr "JoĆĄ nema spominjanja" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nije pronađen mikrofon" @@ -23806,7 +23787,7 @@ msgstr "Otvori izravnu poruku sustava" msgid "Open system picker" msgstr "Otvori sistemski birač" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Otvori JSON predloĆĄka" @@ -23820,7 +23801,7 @@ msgstr "Otvorite dijaloĆĄki okvir za zabranu u ovoj zajednici." msgid "Open the context menu" msgstr "Otvori kontekstni izbornik" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Otvorite donju poveznicu u pregledniku, zatim kopirajte cijeli JSON odgovor i zalijepite ga u okvir." @@ -24331,7 +24312,7 @@ msgstr "Zadnjih 7 dana" msgid "Paste" msgstr "Zalijepi" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Zalijepite URL predloĆĄka s platforme {theOtherPlatform} kako biste uvezli njegovu strukturu u novu zajednicu." @@ -25191,6 +25172,11 @@ msgstr "Vrsta pretplate" msgid "Premium until date" msgstr "Premium do datuma" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Priprema" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Značka profila" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Naslovne slike profila dostupne su uz {PREMIUM_PRODUCT_NAME}. Nabavite {PREMIUM_PRODUCT_NAME} kako biste dodali naslovnu sliku svom profilu." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Naslovne slike profila nisu omogućene na ovoj instanci." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Naslovne slike profila zahtijevaju {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Naslovne slike profila zahtijevaju {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Pritisni za govor" msgid "Push-to-talk (limited)" msgstr "Pritisni za govor (ograničeno)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Pritisni za govor zanemaruje se u izravnom unosu. Prebacite se na fokusirani glas ili prilagođeno da biste ga koristili." @@ -26551,8 +26537,8 @@ msgstr "Ukloni privitak" msgid "Remove authenticator app" msgstr "Ukloni aplikaciju za provjeru autentičnosti" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Ukloni avatar" @@ -26561,8 +26547,8 @@ msgstr "Ukloni avatar" msgid "Remove background" msgstr "Ukloni pozadinu" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Ukloni naslovnu sliku" @@ -26625,10 +26611,10 @@ msgstr "Ukloni s vrha" msgid "Remove from URL-only GIF favorites" msgstr "Ukloni iz favorita GIF-ova pohranjenih putem URL-a" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Ukloni ikonu" @@ -27331,7 +27317,7 @@ msgstr "Ponovno poslano" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "PoniĆĄti" @@ -28074,7 +28060,7 @@ msgstr "Rumunjski" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Zakreni u smjeru kazaljke na satu" @@ -28153,8 +28139,8 @@ msgstr "Zasićenost" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Kontrole za enkoder dijeljenja zaslona" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Dijeljenje zaslona zavrĆĄeno" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "PrikaĆŸi crvenu značku na ikoni aplikacije kada imate nepročitane poruke" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "PrikaĆŸi samo boju naglaska, zanemarujući vaĆĄ globalni profil" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "PrikaĆŸi prilagođene emojije u automatskom dovrĆĄavanju izraza" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "PrikaĆŸi zadani avatar, zanemarujući vaĆĄ globalni profil" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "PrikaĆŸi indikator nepročitanih poruka na utiĆĄanim kanalima" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "PrikaĆŸi avatar svog globalnog profila u ovoj zajednici" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "PrikaĆŸi naslovnu sliku svog globalnog profila u ovoj zajednici" @@ -30720,7 +30706,7 @@ msgstr "Preskoči" msgid "Skip \"Mark all as read\" confirmation" msgstr "Preskoči potvrdu za \"Označi sve kao pročitano\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Preskoči obrezivanje" @@ -32346,7 +32332,7 @@ msgstr "Prebaci na ugodan izgled" msgid "Switch to dense layout" msgstr "Prebaci na zgusnuti izgled" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Prebaci na izravan unos" @@ -32734,7 +32720,7 @@ msgstr "Zadaci" msgid "Teleporting you to another voice region..." msgstr "Prebacujemo vas u drugu glasovnu regiju..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "PredloĆŸak" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Uloga je dodijelila {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Izvor dijeljenja zaslona prestao je slati video, pa je dijeljenje zaslona zaustavljeno." @@ -33453,6 +33439,11 @@ msgstr "Ovaj se račun ne moĆŸe blokirati." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Ova se radnja ne moĆŸe poniĆĄtiti. Svi povezani podaci, uključujući korisnika bota, bit će trajno izbrisani." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ova animacija je predugačka ili prevelika za obrezivanje. Isprobajte kraću ili manju datoteku." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ovaj bot nije javan i drugi ga korisnici ne mogu dodati." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ovaj bot traĆŸi administratorsko dopuĆĄtenje. Dajte mu ga samo ako u potpunosti vjerujete razvojnom programeru. Umjesto toga zamolite ga da zatraĆŸi manje dopuĆĄtenja. Zatvorite ovu stranicu ako niste sigurni." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ovaj preglednik ne moĆŸe obrezivati animirane {avifFormatLabel} datoteke. Umjesto toga, učitajte GIF ili WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Ova je konzola preglednika alat za razvojne programere." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ovaj preglednik ima isključen WebAssembly, stoga se animirane slike ne mogu obrezivati." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ova je grupa puna. Uklonite nekoga prije dodavanja novih osoba." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ovaj je kod za prijenos istekao. Generirajte novi za nastavak." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Ovu sliku nije moguće pročitati. MoĆŸda je oĆĄtećena." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Učitaj" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Učitajte prilagođeni avatar za ovu zajednicu" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Učitajte prilagođenu naslovnu sliku za ovu zajednicu" @@ -36155,10 +36163,10 @@ msgstr "Prenesite datoteke i medijske sadrĆŸaje u porukama." msgid "Upload files and media in this channel." msgstr "Prenesite datoteke i medije u ovaj kanal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Učitaj ikonu" @@ -36401,8 +36409,8 @@ msgstr "Koristi ugljenu temu (potpuno crne povrĆĄine)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Koristi prilagođenu sliku" @@ -36462,8 +36470,8 @@ msgstr "Upotrijebite filtre ili unesite ključne riječi za pronalazak poruka" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Koristi globalni profil" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Sudionici glasovnog poziva" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Obrada glasa" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Uz {PREMIUM_PRODUCT_NAME} moĆŸete koristiti animirane avatare ({ANIMATED_AVATAR_FORMATS}) i profilne bannere, prilagoditi svoju oznaku i otključati mnoge druge pogodnosti {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Potrebno vam je dopuĆĄtenje \"{permissionLabel}\" da biste ovdje koristi msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Potrebno vam je dopuĆĄtenje \"{permissionLabel}\" da biste ovdje koristili naljepnice iz drugih zajednica." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Morate preuzeti svoj račun prije nego ĆĄto moĆŸete stvoriti zajednicu." @@ -39356,8 +39364,8 @@ msgstr "Morate preuzeti svoj račun da biste slali poruke u ovoj zajednici." msgid "You need to verify a phone number to send messages in this community." msgstr "Morate potvrditi telefonski broj da biste slali poruke u ovoj zajednici." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Morate potvrditi svoju adresu e-poĆĄte prije nego ĆĄto moĆŸete stvoriti zajednicu." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Tvoja spremljena kvaliteta od {savedResolution} pri {savedFrameRate} FPS zahtijeva {premiumProductName}, stoga dijeljenje koristi {resolution} pri {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "VaĆĄe dijeljenje zaslona nije se moglo objaviti s kompatibilnim video kodekom pa je zaustavljeno. PokuĆĄajte ponovno dijeliti." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "VaĆĄ prilagođeni URL postavljen je na {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "VaĆĄ video enkoder prestao je kodirati sličice, stoga je dijeljenje zaslona zaustavljeno. PokuĆĄajte ponovno dijeliti." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zumiranje" diff --git a/fluxer_app/src/features/i18n/locales/hu/messages.po b/fluxer_app/src/features/i18n/locales/hu/messages.po index 00408d44d..2cb6916ac 100644 --- a/fluxer_app/src/features/i18n/locales/hu/messages.po +++ b/fluxer_app/src/features/i18n/locales/hu/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, hamarosan" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "A(z) {label} mĂ©retei nem egyeznek ezzel az elemmel. VĂĄlassz mĂĄsik kĂ©pet, vagy tölts fel egy körbevĂĄghatĂł statikus kĂ©pet." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "A(z) {label} fĂĄjl tĂșl nagy. VĂĄlassz egy {maxSizeLabel} mĂ©retnĂ©l kisebb fĂĄjlt." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "A(z) {label} kĂ©pek nem lehetnek animĂĄltak. HasznĂĄlj statikus kĂ©pet." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "TevĂ©kenysĂ©gmegosztĂĄs" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "TevĂ©kenysĂ©gi kĂŒszöb" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention} Ă©s {hereMention} engedĂ©lyezĂ©se" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "EngedĂ©lyezd a(z) {PRODUCT_NAME} szĂĄmĂĄra a kamera hasznĂĄlatĂĄt itt: {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "EngedĂ©lyezd a(z) {PRODUCT_NAME} szĂĄmĂĄra a mikrofonod elĂ©rĂ©sĂ©t a(z) {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME} Ăștvonalon." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "EngedĂ©lyezd, hogy a(z) {PRODUCT_NAME} hozzĂĄfĂ©rjen a mikrofonodhoz. EllenƑrizd a böngĂ©szƑd cĂ­msorĂĄt vagy beĂĄllĂ­tĂĄsait." @@ -3673,7 +3668,7 @@ msgstr "EngedĂ©lyezd a {readMessageHistoryPermissionLabel} jogosultsĂĄggal nem r msgid "Allow mentions for this role" msgstr "EmlĂ­tĂ©sek engedĂ©lyezĂ©se ehhez a szerepkörhöz" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Mikrofon engedĂ©lyezĂ©se" @@ -3942,25 +3937,21 @@ msgstr "Ă©s mĂ©g {remainingCount} tovĂĄbbi" msgid "Animate on interaction" msgstr "AnimĂĄlĂĄs interakciĂłkor" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Az animĂĄlt {AVIF_FORMAT_LABEL} fĂĄjlok nem tĂĄmogatottak. Helyette tölts fel egy statikus {AVIF_FORMAT_LABEL} fĂĄjlt." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Az animĂĄlt {avifFormatLabel} nem tĂĄmogatott" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Az animĂĄlt profilkĂ©pek ({ANIMATED_AVATAR_FORMATS}) kizĂĄrĂłlag a(z) {PREMIUM_PRODUCT_NAME} elƑfizetƑi szĂĄmĂĄra Ă©rhetƑk el." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Az animĂĄlt profilkĂ©pek ({ANIMATED_AVATAR_FORMATS}) nem Ă©rhetƑk el ezen a pĂ©ldĂĄnyon. Helyette tölts fel egy statikus kĂ©pet." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Az animĂĄlt profilkĂ©pekhez ({animatedAvatarFormats}) {premiumProductName} szĂŒksĂ©ges." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "AnimĂĄlt profilkĂ©pek Ă©s borĂ­tĂłkĂ©pek" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Az animĂĄlt profilkĂ©pek nem Ă©rhetƑk el" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Az animĂĄlt profilkĂ©pekhez {premiumProductName} szĂŒksĂ©ges" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "AnimĂĄlt kĂ©p elƑnĂ©zete" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Az animĂĄlt kĂ©pek nem tĂĄmogatottak ehhez az elemhez." @@ -4947,7 +4938,7 @@ msgstr "Nyelv automatikus Ă©szlelĂ©se" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "TevĂ©kenysĂ©gi kĂŒszöb automatikus beĂĄllĂ­tĂĄsa" @@ -5127,15 +5118,15 @@ msgstr "ElĂ©rhetƑ az asztali alkalmazĂĄsban." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "ProfilkĂ©p" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "A profilkĂ©pfĂĄjl tĂșl nagy. VĂĄlassz {imageMaxSizeLabel} mĂ©retnĂ©l kisebb fĂĄjlt." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "A profilkĂ©p tĂșl nagy – vĂĄlassz {imageMaxSizeLabel} mĂ©retnĂ©l kisebbet." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "ProfilkĂ©pmĂłd kivĂĄlasztĂĄsa" @@ -5187,11 +5178,11 @@ msgstr "Jelenleg tĂĄvol" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Kitiltott felhasznĂĄlĂłk" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "BorĂ­tĂłkĂ©p" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "A borĂ­tĂłkĂ©pfĂĄjl tĂșl nagy. VĂĄlassz {imageMaxSizeLabel} mĂ©retnĂ©l kisebb fĂĄjlt." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "BorĂ­tĂłkĂ©pmĂłd kivĂĄlasztĂĄsa" @@ -6107,8 +6098,8 @@ msgstr "VĂĄsĂĄrolj {premiumProductName} ajĂĄndĂ©kot a(z) {premiumProductName} la msgid "Buy gift" msgstr "AjĂĄndĂ©k vĂĄsĂĄrlĂĄsa" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "KözössĂ©g lĂ©trehozĂĄsĂĄval vĂĄllalod a(z) <0>{PRODUCT_NAME} közössĂ©gi irĂĄnyelvek betartĂĄsĂĄt Ă©s betartatĂĄsĂĄt." @@ -6361,7 +6352,7 @@ msgstr "Ide nem tölthetsz fel fĂĄjlokat" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "KözĂ©pre igazĂ­tva" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ProfilkĂ©p mĂłdosĂ­tĂĄsa" @@ -6627,9 +6618,9 @@ msgstr "HĂĄttĂ©r mĂłdosĂ­tĂĄsa" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "BorĂ­tĂłkĂ©p mĂłdosĂ­tĂĄsa" @@ -6668,13 +6659,13 @@ msgstr "Csoportbeli becenĂ©v mĂłdosĂ­tĂĄsa" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Ikon mĂłdosĂ­tĂĄsa" @@ -7669,8 +7660,8 @@ msgstr "AjĂĄndĂ©k bevĂĄltĂĄsa" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Fejezd be a fiĂłkod regisztrĂĄciĂłjĂĄt" @@ -8518,8 +8509,8 @@ msgstr "A közössĂ©g megkönnyĂ­ti a tömeges tĂĄmadĂĄsokat vagy a cĂ©lzott zak msgid "Community filter" msgstr "KözössĂ©gi szƱrƑ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "KözössĂ©g ikonja" @@ -8763,6 +8754,11 @@ msgstr "ÜzenetĂ­rĂĄsi gombok" msgid "Composer focus" msgstr "ÜzenetmezƑ fĂłkusza" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "TömörĂ­tĂ©s" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Csatlakoztass egy kamerĂĄt vagy virtuĂĄlis rögzĂ­tƑeszközt, majd prĂł msgid "Connect a display, then try again." msgstr "Csatlakoztass egy kijelzƑt, majd prĂłbĂĄld Ășjra." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Csatlakoztass egy mikrofont, Ă©s prĂłbĂĄld Ășjra." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nem sikerĂŒlt lĂ©trehozni a matricĂĄt" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Nem sikerĂŒlt körbevĂĄgni a kĂ©pet" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Nem sikerĂŒlt frissĂ­teni a hangtevĂ©kenysĂ©g megosztĂĄsĂĄt" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nem sikerĂŒlt feltölteni a profilkĂ©pet" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nem sikerĂŒlt feltölteni a borĂ­tĂłkĂ©pet" @@ -10230,7 +10226,7 @@ msgstr "LĂ©trehozĂĄs Ă©s megosztĂĄs" msgid "Create a community" msgstr "KözössĂ©g lĂ©trehozĂĄsa" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Hozz lĂ©tre egy közössĂ©get, ahol az ismerƑseiddel cseveghetsz." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "MeghĂ­vĂł hĂĄtterĂ©nek körbevĂĄgĂĄsa" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "VĂĄgĂĄs elƑnĂ©zete" @@ -10500,30 +10496,15 @@ msgstr "Profil borĂ­tĂłkĂ©pĂ©nek körbevĂĄgĂĄsa" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "A körbevĂĄgott kĂ©p tĂșl nagy. VĂĄlassz kisebb terĂŒletet vagy kisebb fĂĄjlt (max. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Az animĂĄlt {formatLabel} fĂĄjlok körbevĂĄgĂĄsa mĂ©g nem tĂĄmogatott. Az eredeti kĂ©pet hasznĂĄljuk." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Az animĂĄlt {formatLabel} fĂĄjlok körbevĂĄgĂĄsa mĂ©g nem tĂĄmogatott. Az eredeti feltöltött fĂĄjlt hasznĂĄljuk." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Az animĂĄlt fĂĄjlok körbevĂĄgĂĄsa mĂ©g nem tĂĄmogatott. Az eredeti kĂ©pet hasznĂĄljuk." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Az animĂĄlt fĂĄjlok körbevĂĄgĂĄsa mĂ©g nem tĂĄmogatott. Az eredeti feltöltött fĂĄjlt hasznĂĄljuk." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "KivĂĄgĂĄs {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Nincs mĂ©g fiĂłkod?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Ne mutasd" @@ -16560,8 +16541,8 @@ msgstr "A csoportos beszĂ©lgetĂ©sek profilkĂ©pei ugyanazokat az ĂĄllapotmaszkoka msgid "Group DMs" msgstr "Csoportos beszĂ©lgetĂ©sek" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Csoport ikonja" @@ -16624,8 +16605,8 @@ msgstr "CsoportbeĂĄllĂ­tĂĄsok" msgid "Group typing states" msgstr "Csoportos gĂ©pelĂ©si ĂĄllapotok" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Csoport frissĂ­tve" @@ -16803,7 +16784,7 @@ msgstr "SzĂ­v" msgid "Hebrew" msgstr "HĂ©ber" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "MagassĂĄg" @@ -17510,7 +17491,7 @@ msgstr "KĂ©p a vĂĄgĂłlapra mĂĄsolva" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "A kĂ©p nem hasznĂĄlhatĂł" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "MegjelenĂ©s Ă©s Ă©rzet" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Úgy tƱnik, ezt hasznĂĄlod: {0}. Ha erre a(z) {PRODUCT_NAME} hangfeldolgozĂĄsa is rĂĄkerĂŒl, az hangerƑ-ingadozĂĄst vagy torzĂ­tĂĄst okozhat. A közvetlen bemenet vĂĄltoztatĂĄs nĂ©lkĂŒl tovĂĄbbĂ­tja a hangodat." @@ -22577,7 +22558,7 @@ msgstr "Nincs talĂĄlat" msgid "No mentions yet" msgstr "MĂ©g nincsenek emlĂ­tĂ©sek" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nem talĂĄlhatĂł mikrofon" @@ -23806,7 +23787,7 @@ msgstr "Rendszerrel folytatott közvetlen beszĂ©lgetĂ©s megnyitĂĄsa" msgid "Open system picker" msgstr "Rendszer vĂĄlasztĂłablakĂĄnak megnyitĂĄsa" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Sablon JSON-jĂĄnak megnyitĂĄsa" @@ -23820,7 +23801,7 @@ msgstr "A közössĂ©g kitiltĂĄsi pĂĄrbeszĂ©dablakĂĄnak megnyitĂĄsa." msgid "Open the context menu" msgstr "A helyi menĂŒ megnyitĂĄsa" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Nyisd meg az alĂĄbbi linket a böngĂ©szƑdben, majd mĂĄsold ki a teljes JSON-vĂĄlaszt, Ă©s illeszd be a mezƑbe." @@ -24331,7 +24312,7 @@ msgstr "ElmĂșlt 7 nap" msgid "Paste" msgstr "BeillesztĂ©s" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Illeszd be a(z) {theOtherPlatform} egyik sablonjĂĄnak URL-jĂ©t, hogy a szerkezetĂ©t Ășj közössĂ©gbe importĂĄld." @@ -25191,6 +25172,11 @@ msgstr "PrĂ©mium tĂ­pus" msgid "Premium until date" msgstr "PrĂ©mium eddig Ă©rvĂ©nyes" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ElƑkĂ©szĂ­tĂ©s" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "ProfiljelvĂ©ny" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "ProfilborĂ­tĂłkĂ©pet a(z) {PREMIUM_PRODUCT_NAME} csomaggal hasznĂĄlhatsz. VĂĄlts a(z) {PREMIUM_PRODUCT_NAME} csomagra, hogy borĂ­tĂłkĂ©pet adj a profilodhoz." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Ezen a pĂ©ldĂĄnyon nincsenek engedĂ©lyezve a profilborĂ­tĂłkĂ©pek." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "A profilborĂ­tĂłkĂ©pekhez {premiumProductName} szĂŒksĂ©ges" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "A profilborĂ­tĂłkĂ©pekhez {premiumProductName} szĂŒksĂ©ges." @@ -25838,7 +25824,7 @@ msgstr "AdĂĄsgomb" msgid "Push-to-talk (limited)" msgstr "AdĂĄsgomb (korlĂĄtozott)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Közvetlen bemenet hasznĂĄlatakor az adĂĄsgomb nem mƱködik. A hasznĂĄlatĂĄhoz vĂĄlts BeszĂ©dkiemelĂ©s vagy EgyĂ©ni mĂłdra." @@ -26551,8 +26537,8 @@ msgstr "MellĂ©klet eltĂĄvolĂ­tĂĄsa" msgid "Remove authenticator app" msgstr "HitelesĂ­tƑ alkalmazĂĄs eltĂĄvolĂ­tĂĄsa" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ProfilkĂ©p eltĂĄvolĂ­tĂĄsa" @@ -26561,8 +26547,8 @@ msgstr "ProfilkĂ©p eltĂĄvolĂ­tĂĄsa" msgid "Remove background" msgstr "HĂĄttĂ©r eltĂĄvolĂ­tĂĄsa" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "BorĂ­tĂłkĂ©p eltĂĄvolĂ­tĂĄsa" @@ -26625,10 +26611,10 @@ msgstr "Mindig felĂŒl beĂĄllĂ­tĂĄs kikapcsolĂĄsa" msgid "Remove from URL-only GIF favorites" msgstr "EltĂĄvolĂ­tĂĄs az URL-en alapulĂł GIF-kedvencek közĂŒl" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Ikon eltĂĄvolĂ­tĂĄsa" @@ -27331,7 +27317,7 @@ msgstr "ÚjrakĂŒldve" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "VisszaĂĄllĂ­tĂĄs" @@ -28074,7 +28060,7 @@ msgstr "RomĂĄn" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ForgatĂĄs az ĂłramutatĂł jĂĄrĂĄsĂĄval megegyezƑ irĂĄnyba" @@ -28153,8 +28139,8 @@ msgstr "TelĂ­tettsĂ©g" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "KĂ©pernyƑmegosztĂĄs-kĂłdolĂł beĂĄllĂ­tĂĄsai" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "A kĂ©pernyƑmegosztĂĄs befejezƑdött" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Piros jelvĂ©ny megjelenĂ­tĂ©se az alkalmazĂĄs ikonjĂĄn, ha olvasatlan ĂŒzeneteid vannak" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Csak a kiemelƑszĂ­n megjelenĂ­tĂ©se, a globĂĄlis profilod figyelmen kĂ­vĂŒl hagyĂĄsĂĄval" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "EgyĂ©ni emojik megjelenĂ­tĂ©se az automatikus kiegĂ©szĂ­tĂ©sben" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "AlapĂ©rtelmezett profilkĂ©p megjelenĂ­tĂ©se, a globĂĄlis profilod figyelmen kĂ­vĂŒl hagyĂĄsĂĄval" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Olvasatlan jelzĂ©se nĂ©mĂ­tott csatornĂĄkon" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "A globĂĄlis profilkĂ©ped megjelenĂ­tĂ©se ebben a közössĂ©gben" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "GlobĂĄlis profilborĂ­tĂłkĂ©ped megjelenĂ­tĂ©se ebben a közössĂ©gben" @@ -30720,7 +30706,7 @@ msgstr "KihagyĂĄs" msgid "Skip \"Mark all as read\" confirmation" msgstr "„Összes megjelölĂ©se olvasottkĂ©nt” megerƑsĂ­tĂ©s kihagyĂĄsa" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "KörbevĂĄgĂĄs kihagyĂĄsa" @@ -32346,7 +32332,7 @@ msgstr "ÁtvĂĄltĂĄs kĂ©nyelmes elrendezĂ©sre" msgid "Switch to dense layout" msgstr "VĂĄltĂĄs sƱrƱ elrendezĂ©sre" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "VĂĄltĂĄs közvetlen bemenetre" @@ -32734,7 +32720,7 @@ msgstr "Feladatok" msgid "Teleporting you to another voice region..." msgstr "ÁthelyezĂ©s egy mĂĄsik hangrĂ©giĂłba
" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Sablon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "A szerepkör a következƑket biztosĂ­totta: {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "A kĂ©pernyƑmegosztĂĄs forrĂĄsa nem kĂŒldött tovĂĄbb videĂłt, ezĂ©rt a kĂ©pernyƑmegosztĂĄsod leĂĄllt." @@ -33453,6 +33439,11 @@ msgstr "Ez a fiĂłk nem tilthatĂł le." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Ez a mƱvelet nem vonhatĂł vissza. Minden kapcsolĂłdĂł adat, beleĂ©rtve a bot felhasznĂĄlĂłt is, vĂ©glegesen törlƑdik." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ez az animĂĄciĂł tĂșl hosszĂș vagy tĂșl nagy a vĂĄgĂĄshoz. PrĂłbĂĄlkozz rövidebb vagy kisebb fĂĄjllal." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ez a bot nem nyilvĂĄnos, Ă©s mĂĄs felhasznĂĄlĂłk nem adhatjĂĄk hozzĂĄ." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ez a bot rendszergazdai jogosultsĂĄgot kĂ©r. Csak akkor add meg, ha teljesen megbĂ­zol a fejlesztƑben. KĂ©rd meg, hogy kevesebb jogosultsĂĄgot kĂ©rjen. Ha bizonytalan vagy, zĂĄrd be ezt az oldalt." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ez a böngĂ©szƑ nem tud animĂĄlt {avifFormatLabel} fĂĄjlokat vĂĄgni. Tölts fel inkĂĄbb GIF vagy WebP fĂĄjlt." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Ez a böngĂ©szƑkonzol egy fejlesztƑi eszköz." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "A böngĂ©szƑben ki van kapcsolva a WebAssembly, ezĂ©rt az animĂĄlt kĂ©pek nem vĂĄghatĂłk le." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ez a csoport megtelt. TĂĄvolĂ­ts el valakit, mielƑtt tovĂĄbbi szemĂ©lye msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ez az ĂĄtadĂĄsi kĂłd lejĂĄrt. A folytatĂĄshoz hozz lĂ©tre Ășjat." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "A kĂ©p nem olvashatĂł be. Lehet, hogy sĂ©rĂŒlt." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "FeltöltĂ©s" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "EgyĂ©ni profilkĂ©p feltöltĂ©se ehhez a közössĂ©ghez" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Egyedi borĂ­tĂłkĂ©p feltöltĂ©se ehhez a közössĂ©ghez" @@ -36155,10 +36163,10 @@ msgstr "FĂĄjlok Ă©s mĂ©dia feltöltĂ©se ĂŒzenetekben." msgid "Upload files and media in this channel." msgstr "FĂĄjlok Ă©s mĂ©dia feltöltĂ©se ebben a csatornĂĄban." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Ikon feltöltĂ©se" @@ -36401,8 +36409,8 @@ msgstr "SzĂ©n tĂ©ma hasznĂĄlata (koromfekete felĂŒletek)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "EgyĂ©ni kĂ©p hasznĂĄlata" @@ -36462,8 +36470,8 @@ msgstr "HasznĂĄlj szƱrƑket, vagy Ă­rj be kulcsszavakat az ĂŒzenetek keresĂ©sĂ© #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "GlobĂĄlis profil hasznĂĄlata" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "HanghĂ­vĂĄs rĂ©sztvevƑi" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "HangfeldolgozĂĄs" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "A(z) {PREMIUM_PRODUCT_NAME} csomaggal animĂĄlt profilkĂ©peket ({ANIMATED_AVATAR_FORMATS}) Ă©s profilborĂ­tĂłkĂ©peket hasznĂĄlhatsz, testre szabhatod a cĂ­mkĂ©det, Ă©s a(z) {PREMIUM_PRODUCT_NAME} szĂĄmos tovĂĄbbi elƑnyĂ©t is Ă©lvezheted." @@ -39334,8 +39342,8 @@ msgstr "MĂĄs közössĂ©gek emojijainak itteni hasznĂĄlatĂĄhoz a(z) „{permissio msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "MĂĄs közössĂ©gek matricĂĄinak itteni hasznĂĄlatĂĄhoz a(z) „{permissionLabel}” jogosultsĂĄgra van szĂŒksĂ©ged." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "KözössĂ©g lĂ©trehozĂĄsa elƑtt be kell fejezned a fiĂłkod regisztrĂĄciĂłjĂĄt." @@ -39356,8 +39364,8 @@ msgstr "Ahhoz, hogy ebben a közössĂ©gben ĂŒzeneteket kĂŒldhess, be kell fejezn msgid "You need to verify a phone number to send messages in this community." msgstr "TelefonszĂĄmot kell igazolnod, hogy ĂŒzeneteket kĂŒldhess ebben a közössĂ©gben." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "KözössĂ©g lĂ©trehozĂĄsa elƑtt meg kell erƑsĂ­tened az e-mail-cĂ­medet." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "A mentett {savedResolution} {savedFrameRate} FPS minƑsĂ©ghez {premiumProductName} szĂŒksĂ©ges, ezĂ©rt a megosztĂĄsok {resolution} minƑsĂ©gben, {frameRate} FPS sebessĂ©ggel törtĂ©nnek." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "A kĂ©pernyƑmegosztĂĄsodat nem sikerĂŒlt kompatibilis videokodekkel közzĂ©tenni, ezĂ©rt leĂĄllt. PrĂłbĂĄld meg Ășjra megosztani." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Az egyĂ©ni meghĂ­vĂłlinked beĂĄllĂ­tva: {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "A videokĂłdolĂłd nem kĂłdolt több kĂ©pkockĂĄt, ezĂ©rt a kĂ©pernyƑmegosztĂĄsod leĂĄllt. PrĂłbĂĄld meg Ășjra megosztani." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "NagyĂ­tĂĄs" diff --git a/fluxer_app/src/features/i18n/locales/id/messages.po b/fluxer_app/src/features/i18n/locales/id/messages.po index 9ddd17bc8..b09ce8b58 100644 --- a/fluxer_app/src/features/i18n/locales/id/messages.po +++ b/fluxer_app/src/features/i18n/locales/id/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, segera hadir" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Dimensi {label} tidak cocok dengan aset ini. Pilih gambar lain atau unggah gambar statis yang bisa kamu pangkas." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Ukuran file {label} terlalu besar. Pilih file yang lebih kecil dari {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Gambar {label} tidak dapat dianimasikan. Gunakan gambar statis." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Berbagi aktivitas" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Ambang aktivitas" @@ -3566,11 +3561,11 @@ msgstr "Izinkan {everyoneMention} dan {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Izinkan {PRODUCT_NAME} mengakses kameramu di {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Izinkan {PRODUCT_NAME} mengakses mikrofonmu di {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Izinkan {PRODUCT_NAME} mengakses mikrofonmu. Periksa bilah alamat atau pengaturan browsermu." @@ -3673,7 +3668,7 @@ msgstr "Izinkan anggota tanpa izin {readMessageHistoryPermissionLabel} untuk mel msgid "Allow mentions for this role" msgstr "Izinkan sebutan untuk peran ini" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Izinkan mikrofon" @@ -3942,25 +3937,21 @@ msgstr "dan {remainingCount} lainnya" msgid "Animate on interaction" msgstr "Animasikan saat interaksi" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "File {AVIF_FORMAT_LABEL} animasi tidak didukung. Unggah file {AVIF_FORMAT_LABEL} statis sebagai gantinya." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "{avifFormatLabel} animasi tidak didukung" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Avatar animasi ({ANIMATED_AVATAR_FORMATS}) hanya tersedia untuk pelanggan {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Avatar animasi ({ANIMATED_AVATAR_FORMATS}) tidak tersedia di instance ini. Unggah gambar statis sebagai gantinya." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Avatar animasi ({animatedAvatarFormats}) memerlukan {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatar & banner profil animasi" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatar animasi tidak tersedia" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Avatar animasi memerlukan {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Pratinjau gambar animasi" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Gambar animasi tidak didukung untuk aset ini." @@ -4947,7 +4938,7 @@ msgstr "Deteksi bahasa otomatis" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Ambang aktivitas otomatis" @@ -5127,15 +5118,15 @@ msgstr "Tersedia di aplikasi desktop." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Ukuran file avatar terlalu besar. Pilih file yang lebih kecil dari {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar terlalu besar. Pilih yang ukurannya di bawah {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Pilih mode avatar" @@ -5187,11 +5178,11 @@ msgstr "Sedang tidak di tempat" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Pengguna yang diblokir" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Ukuran file banner terlalu besar. Pilih file yang lebih kecil dari {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Pilihan mode banner" @@ -6107,8 +6098,8 @@ msgstr "Beli hadiah {premiumProductName} dari tab {premiumProductName} untuk dib msgid "Buy gift" msgstr "Beli hadiah" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Dengan membuat komunitas, kamu setuju untuk mengikuti dan menjunjung tinggi <0>panduan komunitas {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Tidak bisa mengunggah file di sini" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Tengah" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Ganti avatar" @@ -6627,9 +6618,9 @@ msgstr "Ganti latar belakang" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Ganti banner" @@ -6668,13 +6659,13 @@ msgstr "Ubah nama panggilan grup" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Ubah ikon" @@ -7669,8 +7660,8 @@ msgstr "Klaim hadiah" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Klaim akunmu" @@ -8518,8 +8509,8 @@ msgstr "Komunitas ini memfasilitasi perundungan beramai-ramai atau pelecehan yan msgid "Community filter" msgstr "Filter komunitas" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ikon komunitas" @@ -8763,6 +8754,11 @@ msgstr "Tombol kotak pesan" msgid "Composer focus" msgstr "Fokus kotak pesan" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Mengompres" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Hubungkan kamera atau perangkat perekam virtual, lalu coba lagi." msgid "Connect a display, then try again." msgstr "Sambungkan layar, lalu coba lagi." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Sambungkan mikrofon dan coba lagi." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Tidak dapat membuat stiker ini" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Tidak dapat memotong gambar" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Tidak dapat memperbarui berbagi aktivitas suara sekarang" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Tidak dapat mengunggah avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Tidak dapat mengunggah banner" @@ -10230,7 +10226,7 @@ msgstr "Buat & bagikan" msgid "Create a community" msgstr "Buat komunitas" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Buat komunitas tempat kamu dan teman-temanmu bisa mengobrol." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Pangkas latar belakang undangan" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Pratinjau pangkasan" @@ -10500,30 +10496,15 @@ msgstr "Pangkas banner profil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Gambar yang dipotong terlalu besar. Pilih area yang lebih kecil atau file yang lebih kecil (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Pemotongan file {formatLabel} animasi belum didukung. Gambar asli akan digunakan." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Pemotongan file {formatLabel} animasi belum didukung. Unggahan asli akan digunakan." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Pemotongan file animasi belum didukung. Gambar asli akan digunakan." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Pemotongan file animasi belum didukung. Unggahan asli akan digunakan." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Memotong {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Belum punya akun?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Jangan tampilkan" @@ -16560,8 +16541,8 @@ msgstr "Avatar DM grup menggunakan topeng status yang sama dengan avatar biasa, msgid "Group DMs" msgstr "DM grup" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ikon grup" @@ -16624,8 +16605,8 @@ msgstr "Pengaturan grup" msgid "Group typing states" msgstr "Status mengetik grup" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grup diperbarui" @@ -16803,7 +16784,7 @@ msgstr "Hati" msgid "Hebrew" msgstr "Ibrani" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Tinggi" @@ -17510,7 +17491,7 @@ msgstr "Gambar disalin ke papan klip" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Gambar tidak dapat digunakan" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Tampilan dan nuansa" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Sepertinya kamu menggunakan {0}. Menumpuk pemrosesan {PRODUCT_NAME} di atasnya dapat menyebabkan pumping atau distorsi. Input langsung meneruskan audiomu tanpa perubahan." @@ -22577,7 +22558,7 @@ msgstr "Tidak ada yang cocok" msgid "No mentions yet" msgstr "Belum ada sebutan" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Tidak ada mikrofon yang ditemukan" @@ -23806,7 +23787,7 @@ msgstr "Buka DM sistem" msgid "Open system picker" msgstr "Buka pemilih sistem" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Buka JSON template" @@ -23820,7 +23801,7 @@ msgstr "Buka dialog blokir untuk komunitas ini." msgid "Open the context menu" msgstr "Buka menu konteks" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Buka tautan di bawah di browsermu, lalu salin seluruh respons JSON dan tempelkan ke kolom." @@ -24331,7 +24312,7 @@ msgstr "7 hari terakhir" msgid "Paste" msgstr "Tempel" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Tempel URL template {theOtherPlatform} untuk mengimpor strukturnya ke komunitas baru." @@ -25191,6 +25172,11 @@ msgstr "Jenis premium" msgid "Premium until date" msgstr "Premium hingga tanggal" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Mempersiapkan" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Lencana profil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Banner profil adalah fitur {PREMIUM_PRODUCT_NAME}. Dapatkan {PREMIUM_PRODUCT_NAME} untuk menambahkan banner ke profilmu." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Banner profil tidak diaktifkan di instance ini." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Banner profil memerlukan {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Banner profil memerlukan {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (terbatas)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk diabaikan dalam input langsung. Beralih ke suara terfokus atau kustom untuk menggunakannya." @@ -26551,8 +26537,8 @@ msgstr "Hapus lampiran" msgid "Remove authenticator app" msgstr "Hapus aplikasi autentikator" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Hapus avatar" @@ -26561,8 +26547,8 @@ msgstr "Hapus avatar" msgid "Remove background" msgstr "Hapus latar belakang" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Hapus banner" @@ -26625,10 +26611,10 @@ msgstr "Jangan tetap di atas" msgid "Remove from URL-only GIF favorites" msgstr "Hapus dari GIF favorit khusus URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Hapus ikon" @@ -27331,7 +27317,7 @@ msgstr "Dikirim ulang" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Setel ulang" @@ -28074,7 +28060,7 @@ msgstr "Rumania" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Putar searah jarum jam" @@ -28153,8 +28139,8 @@ msgstr "Saturasi" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Kontrol encoder berbagi layar" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Berbagi layar berakhir" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Tampilkan lencana merah di ikon aplikasi saat ada pesan yang belum dibaca" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Tampilkan warna aksen saja, abaikan profil globalmu" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Tampilkan emoji kustom di pelengkapan otomatis ekspresi" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Tampilkan avatar default, abaikan profil globalmu" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Tampilkan indikator belum dibaca di saluran yang dibisukan" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Tampilkan avatar profil globalmu di komunitas ini" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Tampilkan banner profil globalmu di komunitas ini" @@ -30720,7 +30706,7 @@ msgstr "Lewati" msgid "Skip \"Mark all as read\" confirmation" msgstr "Lewati konfirmasi \"Tandai semua sudah dibaca\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Lewati pemotongan" @@ -32346,7 +32332,7 @@ msgstr "Beralih ke tata letak nyaman" msgid "Switch to dense layout" msgstr "Beralih ke tata letak rapat" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Beralih ke input langsung" @@ -32734,7 +32720,7 @@ msgstr "Tugas" msgid "Teleporting you to another voice region..." msgstr "Memindahkanmu ke wilayah suara lain..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Template" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Peran tersebut memberikan {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Sumber berbagi layar berhenti mengirim video, jadi berbagi layarmu dihentikan." @@ -33453,6 +33439,11 @@ msgstr "Akun ini tidak dapat diblokir." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Tindakan ini tidak dapat dibatalkan. Semua data terkait, termasuk pengguna bot, akan dihapus secara permanen." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Animasi ini terlalu panjang atau terlalu besar untuk dipotong. Coba file yang lebih pendek atau lebih kecil." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Bot ini tidak publik dan tidak dapat ditambahkan oleh pengguna lain." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Bot ini meminta izin administrator. Berikan izin hanya jika kamu sepenuhnya memercayai pengembangnya. Minta mereka untuk meminta lebih sedikit izin. Tutup halaman ini jika tidak yakin." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Peramban ini tidak dapat memotong file {avifFormatLabel} animasi. Unggah GIF atau WebP sebagai gantinya." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Konsol browser ini adalah alat pengembang." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Peramban ini mematikan WebAssembly, sehingga gambar animasi tidak dapat dipotong." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Grup ini penuh. Keluarkan seseorang sebelum menambahkan orang lain." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Kode serah terima ini sudah kedaluwarsa. Buat yang baru untuk melanjutkan." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Gambar ini tidak dapat dibaca. Mungkin rusak." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Unggah" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Unggah avatar khusus untuk komunitas ini" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Unggah banner khusus untuk komunitas ini" @@ -36155,10 +36163,10 @@ msgstr "Unggah file dan media dalam pesan." msgid "Upload files and media in this channel." msgstr "Unggah file dan media di saluran ini." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Unggah ikon" @@ -36401,8 +36409,8 @@ msgstr "Gunakan tema batu bara (permukaan hitam pekat)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Gunakan gambar khusus" @@ -36462,8 +36470,8 @@ msgstr "Gunakan filter atau masukkan kata kunci untuk menemukan pesan" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Gunakan profil global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Peserta obrolan suara" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Pemrosesan suara" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Dengan {PREMIUM_PRODUCT_NAME}, kamu bisa memakai avatar animasi ({ANIMATED_AVATAR_FORMATS}) dan banner profil, menyesuaikan tag-mu, dan membuka banyak keuntungan {PREMIUM_PRODUCT_NAME} lainnya." @@ -39334,8 +39342,8 @@ msgstr "Kamu memerlukan izin \"{permissionLabel}\" untuk menggunakan emoji dari msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Kamu memerlukan izin \"{permissionLabel}\" untuk menggunakan stiker dari komunitas lain di sini." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Kamu perlu mengklaim akunmu sebelum bisa membuat komunitas." @@ -39356,8 +39364,8 @@ msgstr "Kamu perlu mengklaim akunmu untuk mengirim pesan di komunitas ini." msgid "You need to verify a phone number to send messages in this community." msgstr "Kamu perlu memverifikasi nomor telepon untuk mengirim pesan di komunitas ini." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Kamu perlu memverifikasi alamat emailmu sebelum bisa membuat komunitas." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Kualitas {savedResolution} yang tersimpan pada {savedFrameRate} FPS memerlukan {premiumProductName}, jadi berbagi menggunakan {resolution} pada {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Berbagi layarmu tidak dapat dipublikasikan dengan codec video yang kompatibel, jadi dihentikan. Coba bagikan lagi." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "URL kustommu telah diatur ke {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Encoder videomu berhenti mengenkode frame, jadi berbagi layarmu dihentikan. Coba bagikan lagi." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/it/messages.po b/fluxer_app/src/features/i18n/locales/it/messages.po index ed0e30251..a6706b6e5 100644 --- a/fluxer_app/src/features/i18n/locales/it/messages.po +++ b/fluxer_app/src/features/i18n/locales/it/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, presto disponibile" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Le dimensioni di {label} non corrispondono a questa risorsa. Scegli un’altra immagine o carica un’immagine statica che puoi ritagliare." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Il file {label} Ăš troppo grande. Scegli un file piĂč piccolo di {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Le immagini {label} non possono essere animate. Usa un'immagine statica." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Condivisione attivitĂ " #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Soglia attivitĂ " @@ -3566,11 +3561,11 @@ msgstr "Consenti {everyoneMention} e {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Consenti a {PRODUCT_NAME} di accedere alla tua fotocamera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Consenti a {PRODUCT_NAME} di accedere al microfono in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Consenti a {PRODUCT_NAME} di accedere al microfono. Controlla la barra degli indirizzi o le impostazioni del browser." @@ -3673,7 +3668,7 @@ msgstr "Consenti ai membri senza il permesso {readMessageHistoryPermissionLabel} msgid "Allow mentions for this role" msgstr "Consenti menzioni per questo ruolo" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Consenti accesso al microfono" @@ -3942,25 +3937,21 @@ msgstr "e altri {remainingCount}" msgid "Animate on interaction" msgstr "Anima all'interazione" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "I file {AVIF_FORMAT_LABEL} animati non sono supportati. Carica invece un file {AVIF_FORMAT_LABEL} statico." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "{avifFormatLabel} animato non supportato" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Gli avatar animati ({ANIMATED_AVATAR_FORMATS}) sono disponibili esclusivamente per gli abbonati a {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Gli avatar animati ({ANIMATED_AVATAR_FORMATS}) non sono disponibili su questa istanza. Carica invece un'immagine statica." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Gli avatar animati ({animatedAvatarFormats}) richiedono {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatar animati e banner del profilo" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatar animati non disponibili" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Gli avatar animati richiedono {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Anteprima immagine animata" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Le immagini animate non sono supportate per questa risorsa." @@ -4947,7 +4938,7 @@ msgstr "Rileva lingua automaticamente" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Soglia attivitĂ  automatica" @@ -5127,15 +5118,15 @@ msgstr "Disponibile nell'app desktop." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Il file dell'avatar Ăš troppo grande. Scegli un file piĂč piccolo di {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "L'avatar Ăš troppo grande: scegline uno inferiore a {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Selezione modalitĂ  avatar" @@ -5187,11 +5178,11 @@ msgstr "Assente in questo momento" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Utenti bannati" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Il file del banner Ăš troppo grande. Scegli un file piĂč piccolo di {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Selezione modalitĂ  banner" @@ -6107,8 +6098,8 @@ msgstr "Acquista un regalo {premiumProductName} dalla scheda {premiumProductName msgid "Buy gift" msgstr "Acquista regalo" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Creando una community, accetti di seguire e far rispettare le <0>linee guida della community di {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Impossibile caricare file qui" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrato" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Cambia avatar" @@ -6627,9 +6618,9 @@ msgstr "Cambia sfondo" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Cambia banner" @@ -6668,13 +6659,13 @@ msgstr "Cambia soprannome del gruppo" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Cambia icona" @@ -7669,8 +7660,8 @@ msgstr "Riscatta regalo" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Completa la registrazione del tuo account" @@ -8518,8 +8509,8 @@ msgstr "La community facilita attacchi di gruppo o abusi mirati." msgid "Community filter" msgstr "Filtro community" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Icona della community" @@ -8763,6 +8754,11 @@ msgstr "Pulsanti della barra di scrittura" msgid "Composer focus" msgstr "Focus del campo di composizione" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Compressione" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Collega una fotocamera o un dispositivo di acquisizione virtuale, quindi msgid "Connect a display, then try again." msgstr "Collega un display, poi riprova." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Connetti un microfono e riprova." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Impossibile creare questo sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Impossibile ritagliare l'immagine" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Impossibile aggiornare la condivisione dell'attivitĂ  vocale in questo momento" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Impossibile caricare l'avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Impossibile caricare il banner" @@ -10230,7 +10226,7 @@ msgstr "Crea e condividi" msgid "Create a community" msgstr "Crea una community" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Crea una community per chattare con i tuoi amici." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Ritaglia sfondo invito" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Anteprima ritaglio" @@ -10500,30 +10496,15 @@ msgstr "Ritaglia banner del profilo" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "L'immagine ritagliata Ăš troppo grande. Scegli un'area piĂč piccola o un file piĂč piccolo (max {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Il ritaglio dei file {formatLabel} animati non Ăš ancora supportato. VerrĂ  usata l'immagine originale." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Il ritaglio dei file {formatLabel} animati non Ăš ancora supportato. VerrĂ  usato il file originale." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Il ritaglio dei file animati non Ăš ancora supportato. VerrĂ  usata l'immagine originale." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Il ritaglio di file animati non Ăš ancora supportato. VerrĂ  usato il file originale." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Ritagliando il {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Non hai un account?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Non mostrare" @@ -16560,8 +16541,8 @@ msgstr "Gli avatar dei DM di gruppo usano le stesse maschere di stato degli avat msgid "Group DMs" msgstr "DM di gruppo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Icona gruppo" @@ -16624,8 +16605,8 @@ msgstr "Impostazioni gruppo" msgid "Group typing states" msgstr "Stati di digitazione del gruppo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Gruppo aggiornato" @@ -16803,7 +16784,7 @@ msgstr "Cuore" msgid "Hebrew" msgstr "Ebraico" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Altezza" @@ -17510,7 +17491,7 @@ msgstr "Immagine copiata negli appunti" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Immagine non utilizzabile" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Aspetto" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Sembra che tu stia usando {0}. L'elaborazione di {PRODUCT_NAME} in aggiunta puĂČ causare pumping o distorsione. L'input diretto lascia il tuo audio inalterato." @@ -22577,7 +22558,7 @@ msgstr "Nessun risultato" msgid "No mentions yet" msgstr "Nessuna menzione ancora" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nessun microfono trovato" @@ -23806,7 +23787,7 @@ msgstr "Apri DM di sistema" msgid "Open system picker" msgstr "Apri selettore di sistema" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Apri il JSON del modello" @@ -23820,7 +23801,7 @@ msgstr "Apri la finestra di dialogo del ban per questa community." msgid "Open the context menu" msgstr "Apri il menu contestuale" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Apri il link qui sotto nel tuo browser, poi copia l'intera risposta JSON e incollala nella casella." @@ -24331,7 +24312,7 @@ msgstr "Ultimi 7 giorni" msgid "Paste" msgstr "Incolla" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Incolla l’URL di un modello di {theOtherPlatform} per importarne la struttura in una nuova community." @@ -25191,6 +25172,11 @@ msgstr "Tipo di Premium" msgid "Premium until date" msgstr "Premium fino al" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparazione" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profilo" msgid "Profile badge" msgstr "Badge del profilo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "I banner del profilo sono una funzionalitĂ  di {PREMIUM_PRODUCT_NAME}. Ottieni {PREMIUM_PRODUCT_NAME} per aggiungere un banner al tuo profilo." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "I banner del profilo non sono abilitati su questa istanza." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "I banner del profilo richiedono {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "I banner del profilo richiedono {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Premi per parlare (limitato)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Il push-to-talk viene ignorato in modalitĂ  \"Input diretto\". Passa a \"Voce isolata\" o \"Personalizzato\" per usarlo." @@ -26551,8 +26537,8 @@ msgstr "Rimuovi allegato" msgid "Remove authenticator app" msgstr "Rimuovi app di autenticazione" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Rimuovi immagine del profilo" @@ -26561,8 +26547,8 @@ msgstr "Rimuovi immagine del profilo" msgid "Remove background" msgstr "Rimuovi sfondo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Rimuovi banner" @@ -26625,10 +26611,10 @@ msgstr "Disattiva sempre in primo piano" msgid "Remove from URL-only GIF favorites" msgstr "Rimuovi dalle GIF preferite salvate solo tramite URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Rimuovi icona" @@ -27331,7 +27317,7 @@ msgstr "Inviato di nuovo" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Reimposta" @@ -28074,7 +28060,7 @@ msgstr "Rumeno" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Ruota in senso orario" @@ -28153,8 +28139,8 @@ msgstr "Saturazione" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Controlli dell'encoder per la condivisione dello schermo" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Condivisione schermo terminata" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Mostra un badge rosso sull'icona dell'app quando hai messaggi non letti" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Mostra solo il colore accento, ignorando il tuo profilo globale" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Mostra emoji personalizzate nel completamento automatico delle espressioni" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Mostra l'avatar predefinito, ignorando il tuo profilo globale" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Mostra indicatore messaggi non letti nei canali silenziati" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Mostra il tuo avatar del profilo globale in questa community" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Mostra il banner del tuo profilo globale in questa community" @@ -30720,7 +30706,7 @@ msgstr "Salta" msgid "Skip \"Mark all as read\" confirmation" msgstr "Salta la conferma di \"Segna tutti come letti\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Salta ritaglio" @@ -32346,7 +32332,7 @@ msgstr "Passa al layout ampio" msgid "Switch to dense layout" msgstr "Passa al layout compatto" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Passa all'input diretto" @@ -32734,7 +32720,7 @@ msgstr "AttivitĂ " msgid "Teleporting you to another voice region..." msgstr "Teletrasporto in corso in un'altra regione vocale..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Modello" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Il ruolo concedeva {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "La sorgente della condivisione dello schermo ha smesso di inviare video, quindi la condivisione dello schermo Ăš stata interrotta." @@ -33453,6 +33439,11 @@ msgstr "Questo account non puĂČ essere bloccato." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Questa azione non puĂČ essere annullata. Tutti i dati associati, incluso l'utente bot, verranno eliminati definitivamente." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Questa animazione Ăš troppo lunga o troppo grande per essere ritagliata. Prova un file piĂč corto o piĂč piccolo." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Questo bot non Ăš pubblico e non puĂČ essere aggiunto da altri utenti." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Questo bot richiede i permessi di amministratore. Concedili solo se ti fidi completamente dello sviluppatore. Chiedigli invece di richiedere meno permessi. Chiudi questa pagina se non sei sicuro." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Questo browser non puĂČ ritagliare file animati {avifFormatLabel}. Carica invece una GIF o WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Questa console del browser Ăš uno strumento per sviluppatori." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Il tuo browser ha disattivato WebAssembly, quindi le immagini animate non possono essere ritagliate." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Questo gruppo Ăš al completo. Rimuovi qualcuno prima di aggiungere altre msgid "This handoff code has expired. Generate a new one to continue." msgstr "Questo codice di trasferimento Ăš scaduto. Generane uno nuovo per continuare." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Impossibile leggere questa immagine. Potrebbe essere danneggiata." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Carica" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Carica un avatar personalizzato per questa community" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Carica un banner personalizzato per questa community" @@ -36155,10 +36163,10 @@ msgstr "Carica file e media nei messaggi." msgid "Upload files and media in this channel." msgstr "Carica file e contenuti multimediali in questo canale." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Carica icona" @@ -36401,8 +36409,8 @@ msgstr "Usa tema carbone (superfici nero pece)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Usa immagine personalizzata" @@ -36462,8 +36470,8 @@ msgstr "Usa i filtri o inserisci le parole chiave per trovare i messaggi" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Usa profilo globale" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Partecipanti alla chat vocale" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Elaborazione voce" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Con {PREMIUM_PRODUCT_NAME}, puoi utilizzare avatar animati ({ANIMATED_AVATAR_FORMATS}), banner del profilo, personalizzare il tuo tag e sbloccare molti altri vantaggi {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Per usare le emoji di altre community qui, ti serve l'autorizzazione \"{ msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Per usare gli sticker di altre community qui, ti serve il permesso \"{permissionLabel}\"." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Devi completare la registrazione del tuo account prima di poter creare una community." @@ -39356,8 +39364,8 @@ msgstr "Devi completare la registrazione del tuo account per inviare messaggi in msgid "You need to verify a phone number to send messages in this community." msgstr "Devi verificare un numero di telefono per inviare messaggi in questa community." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Devi verificare il tuo indirizzo email prima di poter creare una community." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "La tua impostazione salvata {savedResolution} a {savedFrameRate} FPS richiede {premiumProductName}, quindi le condivisioni usano {resolution} a {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "La condivisione dello schermo non Ăš stata pubblicata con un codec video compatibile, quindi Ăš stata interrotta. Riprova a condividere." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "L'URL personalizzato Ăš stato impostato su {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Il tuo codificatore video ha smesso di codificare i frame, quindi la condivisione dello schermo Ăš stata interrotta. Riprova a condividere." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/ja/messages.po b/fluxer_app/src/features/i18n/locales/ja/messages.po index 0577000be..5bc14ce37 100644 --- a/fluxer_app/src/features/i18n/locales/ja/messages.po +++ b/fluxer_app/src/features/i18n/locales/ja/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}ă€èż‘æ—„ć…Źé–‹" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "「{label}ă€ăźćŻžæł•ăŒă“ăźă‚ąă‚»ăƒƒăƒˆăšäž€è‡Žă—ăŸă›ă‚“ă€‚ćˆ„ăźç”»ćƒă‚’éžæŠžă™ă‚‹ă‹ă€ćˆ‡ă‚ŠæŠœăćŻèƒœăȘé™æ­ąç”»ćƒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŠăă ă•ă„ă€‚" - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "「{label}ă€ăźăƒ•ă‚Ąă‚€ăƒ«ă‚”ă‚€ă‚șăŒć€§ăă™ăŽăŸă™ă€‚{maxSizeLabel}ă‚ˆă‚Šć°ă•ă„ăƒ•ă‚Ąă‚€ăƒ«ă‚’éžæŠžă—ăŠăă ă•ă„ă€‚" #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "「{label}ă€ăźç”»ćƒăŻă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă«ă§ăăŸă›ă‚“ă€‚é™æ­ąç”»ćƒă‚’äœżç”šă—ăŠăă ă•ă„ă€‚" @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "ă‚ąă‚Żăƒ†ă‚Łăƒ“ăƒ†ă‚Łăźć…±æœ‰" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "ă‚ąă‚Żăƒ†ă‚Łăƒ“ăƒ†ă‚Łă—ăă„ć€€" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention}ず{hereMention}ă‚’èš±ćŻă™ă‚‹" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "{MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME} で、{PRODUCT_NAME}ăŒă‚«ăƒĄăƒ©ă«ă‚ąă‚Żă‚»ă‚čă™ă‚‹ă“ăšă‚’èš±ćŻă—ăŠăă ă•ă„ă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "{PRODUCT_NAME}ăŒăƒžă‚€ă‚Żă«ă‚ąă‚Żă‚»ă‚čă§ăă‚‹ă‚ˆă†ă«ă™ă‚‹ă«ăŻă€{MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}ă§èš­ćźšă—ăŠăă ă•ă„ă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "{PRODUCT_NAME}ăŒăƒžă‚€ă‚Żă«ă‚ąă‚Żă‚»ă‚čă™ă‚‹ă“ăšă‚’èš±ćŻă—ăŠăă ă•ă„ă€‚ăƒ–ăƒ©ă‚Šă‚¶ăźă‚ąăƒ‰ăƒŹă‚čăƒăƒŒăŸăŸăŻèš­ćźšă‚’çąșèȘă—ăŠăă ă•ă„ă€‚" @@ -3673,7 +3668,7 @@ msgstr "「{readMessageHistoryPermissionLabel}ă€æš©é™ăŒăȘă„ăƒĄăƒłăƒăƒŒăŒ msgid "Allow mentions for this role" msgstr "ă“ăźăƒ­ăƒŒăƒ«ăžăźăƒĄăƒłă‚·ăƒ§ăƒłă‚’èš±ćŻ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ăƒžă‚€ă‚Żă‚’èš±ćŻ" @@ -3942,25 +3937,21 @@ msgstr "他{remainingCount}ä»¶" msgid "Animate on interaction" msgstr "æ“äœœæ™‚ă«ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒł" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒł{AVIF_FORMAT_LABEL}ăƒ•ă‚Ąă‚€ăƒ«ăŻă‚”ăƒăƒŒăƒˆă•ă‚ŒăŠă„ăŸă›ă‚“ă€‚ä»Łă‚ă‚Šă«é™æ­ą{AVIF_FORMAT_LABEL}ăƒ•ă‚Ąă‚€ăƒ«ă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŠăă ă•ă„ă€‚" - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒł{avifFormatLabel}ăŻă‚”ăƒăƒŒăƒˆă•ă‚ŒăŠă„ăŸă›ă‚“" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒ({ANIMATED_AVATAR_FORMATS})は{PREMIUM_PRODUCT_NAME}ăźćŠ ć…„è€…ăźăżăŒćˆ©ç”šă§ăăŸă™ă€‚" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "ă“ăźă‚€ăƒłă‚čタンă‚čă§ăŻă€ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ăŻćˆ©ç”šă§ăăŸă›ă‚“ă€‚ä»Łă‚ă‚Šă«é™æ­ąç”»ćƒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŠăă ă•ă„ă€‚" #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒ({animatedAvatarFormats})には、{premiumProductName}ăŒćż…èŠă§ă™ă€‚" @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒăšăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒ" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒăŻćˆ©ç”šă§ăăŸă›ă‚“" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒă«ăŻ{premiumProductName}ăŒćż…èŠă§ă™" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłç”»ćƒăźăƒ—ăƒŹăƒ“ăƒ„ăƒŒ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ă“ăźă‚ąă‚»ăƒƒăƒˆă§ăŻă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłç”»ćƒăŻă‚”ăƒăƒŒăƒˆă•ă‚ŒăŠă„ăŸă›ă‚“ă€‚" @@ -4947,7 +4938,7 @@ msgstr "蚀èȘžă‚’è‡Șć‹•æ€œć‡ș" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "ă‚ąă‚Żăƒ†ă‚Łăƒ“ăƒ†ă‚Łă—ăă„ć€€ă‚’è‡Șć‹•èš­ćźš" @@ -5127,15 +5118,15 @@ msgstr "デă‚čクトップケプăƒȘă§ćˆ©ç”šă§ăăŸă™ă€‚" #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "ă‚ąăƒă‚żăƒŒ" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ă‚ąăƒă‚żăƒŒăƒ•ă‚Ąă‚€ăƒ«ăŒć€§ăă™ăŽăŸă™ă€‚{imageMaxSizeLabel}ă‚ˆă‚Šć°ă•ă„ăƒ•ă‚Ąă‚€ăƒ«ă‚’éžæŠžă—ăŠăă ă•ă„ă€‚" @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "ă‚ąăƒă‚żăƒŒăŒć€§ăă™ăŽăŸă™ă€‚{imageMaxSizeLabel}ä»„äž‹ăźç”»ćƒă‚’éžæŠžă—ăŠăă ă•ă„ă€‚" #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "ă‚ąăƒă‚żăƒŒăƒąăƒŒăƒ‰éžæŠž" @@ -5187,11 +5178,11 @@ msgstr "çŸćœšé›ąćž­äž­" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "BANă—ăŸăƒŠăƒŒă‚¶ăƒŒ" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "ăƒăƒŠăƒŒ" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ăƒăƒŠăƒŒăƒ•ă‚Ąă‚€ăƒ«ăŒć€§ăă™ăŽăŸă™ă€‚{imageMaxSizeLabel}ă‚ˆă‚Šć°ă•ă„ăƒ•ă‚Ąă‚€ăƒ«ă‚’éžæŠžă—ăŠăă ă•ă„ă€‚" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "ăƒăƒŠăƒŒăƒąăƒŒăƒ‰éžæŠž" @@ -6107,8 +6098,8 @@ msgstr "{premiumProductName}タブから{premiumProductName}ă‚źăƒ•ăƒˆă‚’èłŒć…„ msgid "Buy gift" msgstr "ă‚źăƒ•ăƒˆă‚’èłŒć…„" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚’äœœæˆă™ă‚‹ăšă€<0>{PRODUCT_NAME}ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚Źă‚€ăƒ‰ăƒ©ă‚€ăƒłă«ćŸ“ă„ă€ă“ă‚Œă‚’ćźˆă‚‹ă“ăšă«ćŒæ„ă—ăŸă“ăšă«ăȘă‚ŠăŸă™ă€‚" @@ -6361,7 +6352,7 @@ msgstr "ă“ă“ă«ăƒ•ă‚Ąă‚€ăƒ«ă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă§ăăŸă›ă‚“" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "äž­ć€źæƒăˆ" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ă‚ąăƒă‚żăƒŒă‚’ć€‰æ›Ž" @@ -6627,9 +6618,9 @@ msgstr "èƒŒæ™Żă‚’ć€‰æ›Ž" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "ăƒăƒŠăƒŒă‚’ć€‰æ›Ž" @@ -6668,13 +6659,13 @@ msgstr "ă‚°ăƒ«ăƒŒăƒ—ăƒ‹ăƒƒă‚ŻăƒăƒŒăƒ ă‚’ć€‰æ›Ž" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "ă‚ąă‚€ă‚łăƒłă‚’ć€‰æ›Ž" @@ -7669,8 +7660,8 @@ msgstr "ゼフトを揗け揖る" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "ă‚ąă‚«ă‚Šăƒłăƒˆă‚’ç™»éŒČ" @@ -8518,8 +8509,8 @@ msgstr "é›†ć›Łæ”»æ’ƒă‚„æš™çš„ćž‹ć«ŒăŒă‚‰ă›ă‚’ćŠ©é•·ă—ăŠă„ă‚‹ă‚łăƒŸăƒ„ăƒ‹ăƒ† msgid "Community filter" msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łăƒ•ă‚Łăƒ«ă‚żăƒŒ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚ąă‚€ă‚łăƒł" @@ -8763,6 +8754,11 @@ msgstr "ć…„ćŠ›æŹ„ăƒœă‚żăƒł" msgid "Composer focus" msgstr "ć…„ćŠ›æŹ„ăźăƒ•ă‚©ăƒŒă‚«ă‚č" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "朧羼侭" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ă‚«ăƒĄăƒ©ăŸăŸăŻä»źæƒłă‚­ăƒŁăƒ—ăƒăƒŁăƒ‡ăƒă‚€ă‚čă‚’æŽ„ç¶šă—ăŠă‹ă‚‰ msgid "Connect a display, then try again." msgstr "ディă‚čăƒ—ăƒŹă‚€ă‚’æŽ„ç¶šă—ăŠă‹ă‚‰ă€ă‚‚ă†äž€ćșŠăŠè©Šă—ăă ă•ă„ă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ăƒžă‚€ă‚Żă‚’æŽ„ç¶šă—ăŠă€ă‚‚ă†äž€ćșŠăŠè©Šă—ăă ă•ă„ă€‚" @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ă‚čă‚żăƒłăƒ—ă‚’äœœæˆă§ăăŸă›ă‚“ă§ă—ăŸ" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ç”»ćƒăźćˆ‡ă‚ŠæŠœăă«ć€±æ•—ă—ăŸă—ăŸ" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "çŸćœšă€éŸłćŁ°ă‚ąă‚Żăƒ†ă‚Łăƒ“ăƒ†ă‚Łăźć…±æœ‰ă‚’æ›Žæ–°ă§ăăŸă›ă‚“ă§ă—ăŸ" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ă‚ąăƒă‚żăƒŒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă§ăăŸă›ă‚“ă§ă—ăŸ" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ăƒăƒŠăƒŒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă§ăăŸă›ă‚“ă§ă—ăŸ" @@ -10230,7 +10226,7 @@ msgstr "äœœæˆăƒ»ă‚·ă‚§ă‚ą" msgid "Create a community" msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚’äœœæˆ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ć‹é”ăšăƒăƒŁăƒƒăƒˆă™ă‚‹ăŸă‚ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚’äœœæˆă—ăŸă—ă‚‡ă†ă€‚" @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "æ‹›ćŸ…èƒŒæ™Żă‚’ćˆ‡ă‚ŠæŠœă" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ăƒ—ăƒŹăƒ“ăƒ„ăƒŒă‚’ćˆ‡ă‚ŠæŠœă" @@ -10500,30 +10496,15 @@ msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒă‚’ćˆ‡ă‚ŠæŠœă" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "ćˆ‡ă‚ŠæŠœă„ăŸç”»ćƒăŒć€§ăă™ăŽăŸă™ă€‚çŻ„ć›Čă‚’ç‹­ă‚ă‚‹ă‹ă€ć°ă•ă„ăƒ•ă‚Ąă‚€ăƒ«ă‚’éžæŠžă—ăŠăă ă•ă„ïŒˆæœ€ć€§{maxSizeLabel}ïŒ‰ă€‚" -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒł{formatLabel}ăƒ•ă‚Ąă‚€ăƒ«ăŻăŸă ćˆ‡ă‚ŠæŠœăă«ćŻŸćżœă—ăŠă„ăŸă›ă‚“ă€‚ć…ƒăźç”»ćƒăŒäœżç”šă•ă‚ŒăŸă™ă€‚" - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒł{formatLabel}ăƒ•ă‚Ąă‚€ăƒ«ăŻă€ăŸă ćˆ‡ă‚ŠæŠœăă«ćŻŸćżœă—ăŠă„ăŸă›ă‚“ă€‚ć…ƒăźăƒ•ă‚Ąă‚€ăƒ«ăŒäœżç”šă•ă‚ŒăŸă™ă€‚" - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłăƒ•ă‚Ąă‚€ăƒ«ăŻăŸă ćˆ‡ă‚ŠæŠœăă«ćŻŸćżœă—ăŠă„ăŸă›ă‚“ă€‚ć…ƒăźç”»ćƒăŒäœżç”šă•ă‚ŒăŸă™ă€‚" - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłăƒ•ă‚Ąă‚€ăƒ«ăŻăŸă ćˆ‡ă‚ŠæŠœăă«ćŻŸćżœă—ăŠă„ăŸă›ă‚“ă€‚ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŸć…ƒăźăƒ•ă‚Ąă‚€ăƒ«ăŒäœżç”šă•ă‚ŒăŸă™ă€‚" +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "{percent}%ă‚’ćˆ‡ă‚ŠæŠœăäž­" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ă‚ąă‚«ă‚Šăƒłăƒˆă‚’ăŠæŒăĄă§ăȘă„ă§ă™ă‹ïŒŸ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "èĄšç€șしăȘい" @@ -16560,8 +16541,8 @@ msgstr "ă‚°ăƒ«ăƒŒăƒ—DMăźă‚ąăƒă‚żăƒŒăŻă€é€šćžžăźă‚ąăƒă‚żăƒŒăšćŒă˜ă‚čテ msgid "Group DMs" msgstr "ă‚°ăƒ«ăƒŒăƒ—DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ă‚°ăƒ«ăƒŒăƒ—ă‚ąă‚€ă‚łăƒł" @@ -16624,8 +16605,8 @@ msgstr "ă‚°ăƒ«ăƒŒăƒ—èš­ćźš" msgid "Group typing states" msgstr "ă‚°ăƒ«ăƒŒăƒ—ăźć…„ćŠ›çŠ¶æł" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "ă‚°ăƒ«ăƒŒăƒ—ă‚’æ›Žæ–°ă—ăŸă—ăŸ" @@ -16803,7 +16784,7 @@ msgstr "ăƒăƒŒăƒˆ" msgid "Hebrew" msgstr "ăƒ˜ăƒ–ăƒ©ă‚€èȘž" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "é«˜ă•" @@ -17510,7 +17491,7 @@ msgstr "ç”»ćƒă‚’ă‚ŻăƒȘăƒƒăƒ—ăƒœăƒŒăƒ‰ă«ă‚łăƒ”ăƒŒă—ăŸă—ăŸ" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ç”»ćƒă‚’äœżç”šă§ăăŸă›ă‚“ă§ă—ăŸ" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "èŠ‹ăŸç›źăšæ“äœœæ„Ÿ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "{0}ă‚’ăŠäœżă„ăźă‚ˆă†ă§ă™ă€‚ăăźäžŠă«{PRODUCT_NAME}ぼ懩理を重ねるべ、ポンピングやæ­Șみがç™șç”Ÿă™ă‚‹ćŻèƒœæ€§ăŒă‚ă‚ŠăŸă™ă€‚ăƒ€ă‚€ăƒŹă‚Żăƒˆć…„ćŠ›ă§ăŻă€ă‚ȘăƒŒăƒ‡ă‚Łă‚ȘăŻăăźăŸăŸé€šéŽă—ăŸă™ă€‚" @@ -22577,7 +22558,7 @@ msgstr "äž€è‡Žă™ă‚‹é …ç›źăŻă‚ă‚ŠăŸă›ă‚“" msgid "No mentions yet" msgstr "ăƒĄăƒłă‚·ăƒ§ăƒłăŻăŸă ă‚ă‚ŠăŸă›ă‚“" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "ăƒžă‚€ă‚ŻăŒèŠ‹ă€ă‹ă‚ŠăŸă›ă‚“" @@ -23806,7 +23787,7 @@ msgstr "ă‚·ă‚čテムDMを開く" msgid "Open system picker" msgstr "ă‚·ă‚čăƒ†ăƒ ăƒ”ăƒƒă‚«ăƒŒă‚’é–‹ă" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "ăƒ†ăƒłăƒ—ăƒŹăƒŒăƒˆJSONを開く" @@ -23820,7 +23801,7 @@ msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚ŁăźBANăƒ€ă‚€ă‚ąăƒ­ă‚°ă‚’é–‹ăă€‚" msgid "Open the context menu" msgstr "コンテキă‚čăƒˆăƒĄăƒ‹ăƒ„ăƒŒă‚’é–‹ă" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "仄䞋たăƒȘăƒłă‚Żă‚’ăƒ–ăƒ©ă‚Šă‚¶ă§é–‹ăă€JSONハă‚čポンă‚čć…šäœ“ă‚’ă‚łăƒ”ăƒŒă—ăŠăƒœăƒƒă‚Żă‚čにèČŒă‚Šä»˜ă‘ăŠăă ă•ă„ă€‚" @@ -24331,7 +24312,7 @@ msgstr "過掻7æ—„é–“" msgid "Paste" msgstr "èČŒă‚Šä»˜ă‘" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "æ§‹é€ ă‚’æ–°ă—ă„ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă«ă‚€ăƒłăƒăƒŒăƒˆă™ă‚‹ă«ăŻă€{theOtherPlatform}ăźăƒ†ăƒłăƒ—ăƒŹăƒŒăƒˆURLをèČŒă‚Šä»˜ă‘ăŠăă ă•ă„ă€‚" @@ -25191,6 +25172,11 @@ msgstr "ăƒ—ăƒŹăƒŸă‚ąăƒ ă‚żă‚€ăƒ—" msgid "Premium until date" msgstr "ăƒ—ăƒŹăƒŸă‚ąăƒ æœ‰ćŠč期限" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "æș–悙䞭" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«" msgid "Profile badge" msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒƒă‚ž" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒăŻ{PREMIUM_PRODUCT_NAME}æ©Ÿèƒœă§ă™ă€‚{PREMIUM_PRODUCT_NAME}ă‚’ćˆ©ç”šă—ăŠă€ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă«ăƒăƒŠăƒŒă‚’èżœćŠ ă—ăŸă—ă‚‡ă†ă€‚" #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "ă“ăźă‚€ăƒłă‚čタンă‚čă§ăŻăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒăŻæœ‰ćŠčにăȘăŁăŠă„ăŸă›ă‚“ă€‚" #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒă«ăŻ{premiumProductName}ăŒćż…èŠă§ă™" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒă«ăŻ{premiumProductName}ăŒćż…èŠă§ă™ă€‚" @@ -25838,7 +25824,7 @@ msgstr "ăƒ—ăƒƒă‚·ăƒ„ăƒˆă‚„ăƒˆăƒŒă‚Ż" msgid "Push-to-talk (limited)" msgstr "ăƒ—ăƒƒă‚·ăƒ„ăƒˆă‚„ăƒˆăƒŒă‚ŻïŒˆćˆ¶é™ă‚ă‚ŠïŒ‰" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "ăƒ€ă‚€ăƒŹă‚Żăƒˆć…„ćŠ›ă§ăŻăƒ—ăƒƒă‚·ăƒ„ăƒˆă‚„ăƒˆăƒŒă‚ŻăŻç„ĄèŠ–ă•ă‚ŒăŸă™ă€‚äœżç”šă™ă‚‹ă«ăŻă€ŒéŸłćŁ°ă«ăƒ•ă‚©ăƒŒă‚«ă‚čă€ăŸăŸăŻă€Œă‚«ă‚čă‚żăƒ ă€ă«ćˆ‡ă‚Šæ›żăˆăŠăă ă•ă„ă€‚" @@ -26551,8 +26537,8 @@ msgstr "æ·»ä»˜ăƒ•ă‚Ąă‚€ăƒ«ă‚’ć‰Šé™€" msgid "Remove authenticator app" msgstr "èȘèšŒă‚ąăƒ—ăƒȘを扊陀" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ă‚ąăƒă‚żăƒŒă‚’ć‰Šé™€" @@ -26561,8 +26547,8 @@ msgstr "ă‚ąăƒă‚żăƒŒă‚’ć‰Šé™€" msgid "Remove background" msgstr "èƒŒæ™Żă‚’ć‰Šé™€" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "ăƒăƒŠăƒŒă‚’ć‰Šé™€" @@ -26625,10 +26611,10 @@ msgstr "æœ€ć‰éąèĄšç€șă‚’è§Łé™€" msgid "Remove from URL-only GIF favorites" msgstr "URLぼみで保歘されたGIFă‚’ăŠæ°—ă«ć…„ă‚Šă‹ă‚‰ć‰Šé™€" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ă‚ąă‚€ă‚łăƒłă‚’ć‰Šé™€" @@ -27331,7 +27317,7 @@ msgstr "ć†é€ă—ăŸă—ăŸ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ăƒȘă‚»ăƒƒăƒˆ" @@ -28074,7 +28060,7 @@ msgstr "ăƒ«ăƒŒăƒžăƒ‹ă‚ąèȘž" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "æ™‚èšˆć›žă‚Šă«ć›žè»ą" @@ -28153,8 +28139,8 @@ msgstr "ćœ©ćșŠ" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ç”»éąć…±æœ‰ă‚šăƒłă‚łăƒŒăƒ€ăƒŒèš­ćźš" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "ç”»éąć…±æœ‰ăŒç”‚äș†ă—ăŸă—ăŸ" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "æœȘèȘ­ăƒĄăƒƒă‚»ăƒŒă‚žăŒă‚ă‚‹ăšăă«ă‚ąăƒ—ăƒȘă‚ąă‚€ă‚łăƒłă«è”€ă„ăƒăƒƒă‚žă‚’èĄšç€ș" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "ă‚ąă‚Żă‚»ăƒłăƒˆă‚«ăƒ©ăƒŒăźăżă‚’èĄšç€șïŒˆă‚°ăƒ­ăƒŒăƒăƒ«ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă‚’ç„ĄèŠ–ïŒ‰" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "スクă‚čăƒ—ăƒŹăƒƒă‚·ăƒ§ăƒłăźć…„ćŠ›ć€™èŁœă«ă‚«ă‚čă‚żăƒ ç””æ–‡ć­—ă‚’èĄšç€ș" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "ăƒ‡ăƒ•ă‚©ăƒ«ăƒˆăźă‚ąăƒă‚żăƒŒă‚’èĄšç€șïŒˆă‚°ăƒ­ăƒŒăƒăƒ«ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă‚’ç„ĄèŠ–ïŒ‰" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "ăƒŸăƒ„ăƒŒăƒˆäž­ăźăƒăƒŁăƒłăƒăƒ«ă«æœȘèȘ­ăƒăƒƒă‚žă‚’èĄšç€ș" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă§ă‚°ăƒ­ăƒŒăƒăƒ«ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăźă‚ąăƒă‚żăƒŒă‚’èĄšç€ș" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă§ă‚°ăƒ­ăƒŒăƒăƒ«ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăźăƒăƒŠăƒŒă‚’èĄšç€ș" @@ -30720,7 +30706,7 @@ msgstr "ă‚čキップ" msgid "Skip \"Mark all as read\" confirmation" msgstr "「すăčăŠæ—ąèȘ­ă«ă™ă‚‹ă€ăźçąșèȘă‚’ă‚čキップ" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "トăƒȘミングをă‚čキップ" @@ -32346,7 +32332,7 @@ msgstr "ă‚†ăŁăŸă‚ŠèĄšç€șă«ćˆ‡ă‚Šæ›żăˆă‚‹" msgid "Switch to dense layout" msgstr "ă‚łăƒłăƒ‘ă‚ŻăƒˆèĄšç€șă«ćˆ‡ă‚Šæ›żăˆă‚‹" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ç›ŽæŽ„ć…„ćŠ›ă«ćˆ‡ă‚Šæ›żăˆă‚‹" @@ -32734,7 +32720,7 @@ msgstr "タă‚čク" msgid "Teleporting you to another voice region..." msgstr "ćˆ„ăźăƒœă‚€ă‚čăƒȘăƒŒă‚žăƒ§ăƒłă«è»ąé€ă—ăŠă„ăŸă™â€Š" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ăƒ†ăƒłăƒ—ăƒŹăƒŒăƒˆ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "ăƒ­ăƒŒăƒ«ăŻ{permissions}ă‚’ä»˜äžŽă—ăŠă„ăŸă—ăŸ" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "ç”»éąć…±æœ‰ăźă‚œăƒŒă‚čがビデă‚Șăźé€äżĄă‚’ćœæ­ąă—ăŸăŸă‚ă€ç”»éąć…±æœ‰ăŻćœæ­ąă•ă‚ŒăŸă—ăŸă€‚" @@ -33453,6 +33439,11 @@ msgstr "ă“ăźă‚ąă‚«ă‚Šăƒłăƒˆă‚’ăƒ–ăƒ­ăƒƒă‚Żă™ă‚‹ă“ăšăŻă§ăăŸă›ă‚“ă€‚" msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "ă“ăźæ“äœœăŻć…ƒă«æˆ»ă›ăŸă›ă‚“ă€‚ăƒœăƒƒăƒˆăƒŠăƒŒă‚¶ăƒŒă‚’ć«ă‚€ă™ăčăŠăźé–ąé€Łăƒ‡ăƒŒă‚żăŒćźŒć…šă«ć‰Šé™€ă•ă‚ŒăŸă™ă€‚" +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "ă“ăźă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłăŻé•·ă™ăŽă‚‹ă‹ă€ć€§ăă™ăŽă‚‹ăŸă‚ă€ăƒˆăƒȘăƒŸăƒłă‚°ă§ăăŸă›ă‚“ă€‚ă‚ˆă‚ŠçŸ­ăă€ăŸăŸăŻă‚ˆă‚Šć°ă•ă„ăƒ•ă‚Ąă‚€ăƒ«ă‚’ăŠè©Šă—ăă ă•ă„ă€‚" + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "ă“ăźăƒœăƒƒăƒˆăŻć…Źé–‹ă•ă‚ŒăŠă„ăŸă›ă‚“ă€‚ä»–ăźăƒŠăƒŒă‚¶ăƒŒăŒèżœ msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "ă“ăźăƒœăƒƒăƒˆăŻçźĄç†è€…æš©é™ă‚’èŠæ±‚ă—ăŠă„ăŸă™ă€‚é–‹ç™șè€…ă‚’ćźŒć…šă«äżĄé Œă§ăă‚‹ć Žćˆă«ăźăżèš±ćŻă—ăŠăă ă•ă„ă€‚ä»Łă‚ă‚Šă«ă€ă‚ˆă‚Šć°‘ăȘă„æš©é™ă‚’èŠæ±‚ă™ă‚‹ă‚ˆă†ă«äŸé Œă—ăŠăă ă•ă„ă€‚äžæ˜ŽăȘć ŽćˆăŻă“ăźăƒšăƒŒă‚žă‚’é–‰ă˜ăŠăă ă•ă„ă€‚" +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "ă“ăźăƒ–ăƒ©ă‚Šă‚¶ă§ăŻă€ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłăź{avifFormatLabel}ăƒ•ă‚Ąă‚€ăƒ«ă‚’ă‚Żăƒ­ăƒƒăƒ—ă§ăăŸă›ă‚“ă€‚ä»Łă‚ă‚Šă«GIFăŸăŸăŻWebPă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŠăă ă•ă„ă€‚" + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "ă“ăźăƒ–ăƒ©ă‚Šă‚¶ăźă‚łăƒłă‚œăƒŒăƒ«ăŻé–‹ç™șè€…ăƒ„ăƒŒăƒ«ă§ă™ă€‚" +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "ă“ăźăƒ–ăƒ©ă‚Šă‚¶ă§ăŻWebAssemblyが無ćŠčにăȘăŁăŠă„ă‚‹ăŸă‚ă€ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłç”»ćƒă‚’ćˆ‡ă‚ŠæŠœăă“ăšăŒă§ăăŸă›ă‚“ă€‚" + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "ă“ăźă‚°ăƒ«ăƒŒăƒ—ăŻæș€ć“Ąă§ă™ă€‚ăƒĄăƒłăƒăƒŒă‚’èżœćŠ ă™ă‚‹ć‰ă«ă€ msgid "This handoff code has expired. Generate a new one to continue." msgstr "ă“ăźćŒ•ăç¶™ăŽă‚łăƒŒăƒ‰ăŻæœ‰ćŠčæœŸé™ăŒćˆ‡ă‚ŒăŸă—ăŸă€‚æ–°ă—ă„ă‚łăƒŒăƒ‰ă‚’ç”Ÿæˆă—ăŠç¶šèĄŒă—ăŠăă ă•ă„ă€‚" +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "ă“ăźç”»ćƒă‚’èȘ­ăżèŸŒă‚ăŸă›ă‚“ă§ă—ăŸă€‚ç Žæă—ăŠă„ă‚‹ćŻèƒœæ€§ăŒă‚ă‚ŠăŸă™ă€‚" + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łăźă‚«ă‚čă‚żăƒ ă‚ąăƒă‚żăƒŒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łăźă‚«ă‚čă‚żăƒ ăƒăƒŠăƒŒă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰" @@ -36155,10 +36163,10 @@ msgstr "ăƒĄăƒƒă‚»ăƒŒă‚žă§ăƒ•ă‚Ąă‚€ăƒ«ă‚„ăƒĄăƒ‡ă‚Łă‚ąă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŸ msgid "Upload files and media in this channel." msgstr "ă“ăźăƒăƒŁăƒłăƒăƒ«ă«ăƒ•ă‚Ąă‚€ăƒ«ă‚„ăƒĄăƒ‡ă‚Łă‚ąă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰ă—ăŸă™ă€‚" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "ă‚ąă‚€ă‚łăƒłă‚’ă‚ąăƒƒăƒ—ăƒ­ăƒŒăƒ‰" @@ -36401,8 +36409,8 @@ msgstr "çŸłç‚­ăƒ†ăƒŒăƒžă‚’äœżç”šïŒˆćźŒć…šăȘ黒" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "ă‚«ă‚čă‚żăƒ ç”»ćƒă‚’äœżç”š" @@ -36462,8 +36470,8 @@ msgstr "ăƒ•ă‚Łăƒ«ă‚żăƒŒăŸăŸăŻă‚­ăƒŒăƒŻăƒŒăƒ‰ă§ăƒĄăƒƒă‚»ăƒŒă‚žă‚’æ€œçŽą" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "ă‚°ăƒ­ăƒŒăƒăƒ«ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ă‚’äœżç”š" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "é€šè©±ăźć‚ćŠ è€…" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "音棰懩理" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ォィă‚čă‚łăƒłă‚·ăƒłć·ž" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "{PREMIUM_PRODUCT_NAME}ă§ăŻă€ă‚ąăƒ‹ăƒĄăƒŒă‚·ăƒ§ăƒłă‚ąăƒă‚żăƒŒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ă‚„ăƒ—ăƒ­ăƒ•ă‚ŁăƒŒăƒ«ăƒăƒŠăƒŒă‚’äœżăŁăŸă‚Šă€ă‚żă‚°ă‚’ă‚«ă‚čă‚żăƒžă‚€ă‚șă—ăŸă‚Šă§ăă‚‹ă»ă‹ă€æ•°ć€šăăź{PREMIUM_PRODUCT_NAME}ç‰čć…žă‚’ćˆ©ç”šă§ăăŸă™ă€‚" @@ -39334,8 +39342,8 @@ msgstr "ä»–ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łăźç””æ–‡ć­—ă‚’ă“ă“ă§äœżç”šă™ă‚‹ă«ăŻă€ă€Œ msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "ä»–ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łăźă‚čă‚żăƒłăƒ—ă‚’ă“ă“ă§äœżç”šă™ă‚‹ă«ăŻă€ă€Œ{permissionLabel}ă€ăźæš©é™ăŒćż…èŠă§ă™ă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚’äœœæˆă™ă‚‹ć‰ă«ă€ă‚ąă‚«ă‚Šăƒłăƒˆăźç™»éŒČăŒćż…èŠă§ă™ă€‚" @@ -39356,8 +39364,8 @@ msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă§ăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€äżĄă™ă‚‹ă«ăŻă€ă‚ąă‚« msgid "You need to verify a phone number to send messages in this community." msgstr "ă“ăźă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă§ăƒĄăƒƒă‚»ăƒŒă‚žă‚’é€äżĄă™ă‚‹ă«ăŻă€é›»è©±ç•Șć·èȘèšŒăŒćż…èŠă§ă™ă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ă‚łăƒŸăƒ„ăƒ‹ăƒ†ă‚Łă‚’äœœæˆă™ă‚‹ć‰ă«ă€ăƒĄăƒŒăƒ«ă‚ąăƒ‰ăƒŹă‚čたçąșèȘăŒćż…èŠă§ă™ă€‚" @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "保歘された {savedResolution} ({savedFrameRate} FPS) は {premiumProductName} ăŒćż…èŠă§ă™ă€‚ăăźăŸă‚ă€ć…±æœ‰ăŻ {resolution} ({frameRate} FPS) ă§èĄŒă‚ă‚ŒăŸă™ă€‚" #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "äș’æ›æ€§ăźă‚ă‚‹ăƒ“ăƒ‡ă‚Șă‚łăƒŒăƒ‡ăƒƒă‚Żă§ç”»éąć…±æœ‰ă‚’ć…Źé–‹ă§ăăȘă‹ăŁăŸăŸă‚ă€ćœæ­ąă—ăŸă—ăŸă€‚ă‚‚ă†äž€ćșŠć…±æœ‰ă—ăŠăżăŠăă ă•ă„ă€‚" @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "ă‚«ă‚čタムURLを{inviteEndpoint}/{vanitySlug}ă«èš­ćźšă—ăŸă—ăŸ" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "ビデă‚Șă‚šăƒłă‚łăƒŒăƒ€ăƒŒăŒăƒ•ăƒŹăƒŒăƒ ăźă‚šăƒłă‚łăƒŒăƒ‰ă‚’ćœæ­ąă—ăŸăŸă‚ă€ç”»éąć…±æœ‰ăŒćœæ­ąă—ăŸă—ăŸă€‚ă‚‚ă†äž€ćșŠć…±æœ‰ă—ăŠăżăŠăă ă•ă„ă€‚" @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "ă‚șăƒŒăƒ " diff --git a/fluxer_app/src/features/i18n/locales/ko/messages.po b/fluxer_app/src/features/i18n/locales/ko/messages.po index 6dff71a5e..191977f27 100644 --- a/fluxer_app/src/features/i18n/locales/ko/messages.po +++ b/fluxer_app/src/features/i18n/locales/ko/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, 출시 예정" msgid "{kilobits} kbps" msgstr "{kilobits}kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label}의 íŹêž°ê°€ 읎 ì—ì…‹êłŒ 음ìč˜í•˜ì§€ 않슔니닀. 닀넞 ìŽëŻžì§€ë„Œ 선택하거나 자넌 수 있는 정지된 ìŽëŻžì§€ë„Œ ì—…ëĄœë“œí•˜ì„žìš”." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} 파음읎 너묮 큜니닀. {maxSizeLabel}볎닀 작은 파음을 선택하섞요." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} ìŽëŻžì§€ëŠ” 애니메읎션을 ì‚Źìš©í•  수 없슔니닀. 정지된 ìŽëŻžì§€ë„Œ ì‚Źìš©í•˜ì„žìš”." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "활동 êł”ìœ " #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "활동 ìž„êł„ê°’" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention} 및 {hereMention} 허용" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "{PRODUCT_NAME}읎(가) {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}에서 ìčŽë©”띌에 ì ‘ê·Œí•˜ë„ëĄ 허용하섞요." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "{PRODUCT_NAME}읎(가) ë§ˆìŽíŹì— ì ‘ê·Œí•˜ë„ëĄ 허용하렀멎 {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}에서 섀정핎 ìŁŒì„žìš”." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "{PRODUCT_NAME}에서 ë§ˆìŽíŹì— ì ‘ê·Œí•˜ë„ëĄ 허용핎 ìŁŒì„žìš”. 람띌우저 ìŁŒì†Œ 표시쀄 또는 섀정을 확읞하섞요." @@ -3673,7 +3668,7 @@ msgstr "{readMessageHistoryPermissionLabel} 권한읎 없는 ë©€ëČ„ê°€ íŠč정 msgid "Allow mentions for this role" msgstr "읎 역할에 대한 멘션 허용" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ë§ˆìŽíŹ 허용" @@ -3942,25 +3937,21 @@ msgstr "왞 {remainingCount}개" msgid "Animate on interaction" msgstr "상혞작용 시 애니메읎션 ìžŹìƒ" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "움직읎는 {AVIF_FORMAT_LABEL} 파음은 지원되지 않슔니닀. 대신 정적 {AVIF_FORMAT_LABEL} 파음을 ì—…ëĄœë“œí•˜ì„žìš”." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "움직읎는 {avifFormatLabel}은(는) 지원되지 않슔니닀" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "움직읎는 아바타({ANIMATED_AVATAR_FORMATS})는 {PREMIUM_PRODUCT_NAME} ê”Źë…ìžì—êȌ만 ì œêł”ë©ë‹ˆë‹€." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "읎 읞슀턎슀에서는 움직읎는 아바타({ANIMATED_AVATAR_FORMATS})넌 ì‚Źìš©í•  수 없슔니닀. 대신 정적 ìŽëŻžì§€ë„Œ ì—…ëĄœë“œí•˜ì„žìš”." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "움직읎는 아바타({animatedAvatarFormats})에는 {premiumProductName}읎(가) 필요합니닀." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "움직읎는 아바타 및 프로필 배너" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "움직읎는 아바타넌 ì‚Źìš©í•  수 없슔니닀" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "움직읎는 아바타에는 {premiumProductName}읎(가) 필요합니닀" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "움직읎는 ìŽëŻžì§€ ëŻžëŠŹëłŽêž°" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "읎 항ëȘ©ì—ëŠ” 움직읎는 ìŽëŻžì§€ë„Œ ì‚Źìš©í•  수 없슔니닀." @@ -4947,7 +4938,7 @@ msgstr "ì–žì–Ž 자동 감지" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "활동 ìž„êł„ê°’ 자동 섀정" @@ -5127,15 +5118,15 @@ msgstr "ë°ìŠ€íŹí†± 앱에서 ì‚Źìš© 가늄합니닀." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "아바타" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "아바타 파음읎 너묮 큜니닀. {imageMaxSizeLabel}볎닀 작은 파음을 선택하섞요." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "아바타가 너묮 큜니닀. {imageMaxSizeLabel} 읎낎의 ìŽëŻžì§€ë„Œ 선택핎 ìŁŒì„žìš”." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "아바타 ëȘšë“œ 선택" @@ -5187,11 +5178,11 @@ msgstr "지ꞈ은 ë¶€ìžŹì€‘" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "찚닚된 ì‚Źìš©ìž" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "배너" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "배너 파음읎 너묮 큜니닀. {imageMaxSizeLabel}볎닀 작은 파음을 선택하섞요." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "배너 ëȘšë“œ 선택" @@ -6107,8 +6098,8 @@ msgstr "ìčœê”Źì™€ êł”ìœ í•˜ë €ë©Ž {premiumProductName} 탭에서 {premiumProduct msgid "Buy gift" msgstr "ì„ ëŹŒ ê”Źë§€" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ì»€ëź€ë‹ˆí‹°ë„Œ 생성하멎 <0>{PRODUCT_NAME} ì»€ëź€ë‹ˆí‹° 가읎드띌읞을 ë”°ë„Žêł  쀀수하는 데 동의하는 êČƒìž…ë‹ˆë‹€." @@ -6361,7 +6352,7 @@ msgstr "ì—Źêž°ì— 파음을 ì˜ŹëŠŽ 수 없슔니닀" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "가욎데 ì •ë Ź" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "프로필 ì‚Źì§„ 변êČœ" @@ -6627,9 +6618,9 @@ msgstr "ë°°êČœ 변êČœ" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "배너 변êČœ" @@ -6668,13 +6659,13 @@ msgstr "ê·žëŁč 닉넀임 변êČœ" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "아읎윘 변êČœ" @@ -7669,8 +7660,8 @@ msgstr "ì„ ëŹŒ 받Ʞ" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "êł„ì • ë“±ëĄí•˜êž°" @@ -8518,8 +8509,8 @@ msgstr "집닚 êł”êČ© 또는 표적 학대넌 ìĄ°ìž„í•˜ëŠ” ì»€ëź€ë‹ˆí‹°ìž…ë‹ˆë‹€ msgid "Community filter" msgstr "ì»€ëź€ë‹ˆí‹° 필터" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ì»€ëź€ë‹ˆí‹° 아읎윘" @@ -8763,6 +8754,11 @@ msgstr "ìž…ë „ì°œ ëČ„íŠŒ" msgid "Composer focus" msgstr "ìž…ë „ì°œ 자동 활성화" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "압축 쀑" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ìčŽë©”띌 또는 가상 ìșĄìȘ 임ìč˜ë„Œ 연êȰ한 후 닀시 시도하 msgid "Connect a display, then try again." msgstr "디슀플레읎넌 연êȰ한 닀음 닀시 시도하섞요." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ë§ˆìŽíŹë„Œ 연êČ°í•˜êł  닀시 시도하섞요." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "슀티컀넌 만듀 수 없슔니닀" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ìŽëŻžì§€ë„Œ 자넌 수 없슔니닀" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "지ꞈ은 음성 활동 êł”ìœ ë„Œ 업데읎튞할 수 없슔니닀" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "아바타넌 ì—…ëĄœë“œí•  수 없슔니닀" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "배너넌 ì—…ëĄœë“œí•  수 없슔니닀" @@ -10230,7 +10226,7 @@ msgstr "ë§Œë“€êł  êł”ìœ í•˜êž°" msgid "Create a community" msgstr "ì»€ëź€ë‹ˆí‹° 만듀Ʞ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ìčœê”Źë“€êłŒ 채팅할 ì»€ëź€ë‹ˆí‹°ë„Œ 만드섞요." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "쎈대 ë°°êČœ 자넎Ʞ" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "자넎Ʞ ëŻžëŠŹëłŽêž°" @@ -10500,30 +10496,15 @@ msgstr "프로필 배너 자넎Ʞ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "자넞 ìŽëŻžì§€ê°€ 너묮 큜니닀. 더 작은 영역을 선택하거나 더 작은 파음을 선택하섞요(씜대 {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "움직읎는 {formatLabel} 파음은 아직 자넌 수 없슔니닀. ì›ëłž ìŽëŻžì§€ê°€ ì‚Źìš©ë©ë‹ˆë‹€." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "움직읎는 {formatLabel} 파음은 아직 자넌 수 없슔니닀. ì›ëłž 파음읎 ì‚Źìš©ë©ë‹ˆë‹€." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "움직읎는 파음은 아직 자넌 수 없슔니닀. ì›ëłž ìŽëŻžì§€ê°€ ì‚Źìš©ë©ë‹ˆë‹€." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "움직읎는 파음은 아직 자넌 수 없슔니닀. ì›ëłž 파음읎 ì‚Źìš©ë©ë‹ˆë‹€." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "{percent}% 잘띌낎는 쀑" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "êł„ì •ìŽ 없윌신가요?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "표시 안 핹" @@ -16560,8 +16541,8 @@ msgstr "ê·žëŁč DM 아바타는 음반 아바타와 동음한 상태 ë§ˆìŠ€íŹë„Œ msgid "Group DMs" msgstr "ê·žëŁč DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ê·žëŁč 아읎윘" @@ -16624,8 +16605,8 @@ msgstr "ê·žëŁč 섀정" msgid "Group typing states" msgstr "ê·žëŁč ìž…ë „ 쀑 상태" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "ê·žëŁč읎 업데읎튞되었슔니닀" @@ -16803,7 +16784,7 @@ msgstr "하튾" msgid "Hebrew" msgstr "ížˆëžŒëŠŹì–Ž" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "높읎" @@ -17510,7 +17491,7 @@ msgstr "ìŽëŻžì§€ê°€ íŽëŠœëłŽë“œì— ëł”ì‚Źë˜ì—ˆìŠ”ë‹ˆë‹€" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ìŽëŻžì§€ë„Œ ì‚Źìš©í•  수 없슔니닀" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "ëȘšì–‘ 및 느낌" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "{0}을(넌) ì‚Źìš© 쀑읎신 êȃ 같슔니닀. {PRODUCT_NAME}의 ìČ˜ëŠŹë„Œ 추가하멎 펌핑 또는 ì™œêłĄìŽ 발생할 수 있슔니닀. 직접 입렄은 였디였넌 ê·žëŒ€ëĄœ í†”êłŒì‹œí‚”ë‹ˆë‹€." @@ -22577,7 +22558,7 @@ msgstr "음ìč˜í•˜ëŠ” 항ëȘ© 없음" msgid "No mentions yet" msgstr "아직 멘션읎 없슔니닀" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "ë§ˆìŽíŹë„Œ 찟을 수 없슔니닀" @@ -23806,7 +23787,7 @@ msgstr "시슀템 DM ì—Žêž°" msgid "Open system picker" msgstr "시슀템 선택Ʞ ì—Žêž°" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "템플멿 JSON ì—Žêž°" @@ -23820,7 +23801,7 @@ msgstr "읎 ì»€ëź€ë‹ˆí‹°ì˜ 찚닚 대화 상자넌 엜니닀." msgid "Open the context menu" msgstr "ìƒí™©ëł„ 메뉎 ì—Žêž°" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "아래 ë§íŹë„Œ 람띌우저에서 연 닀음, 전ìČŽ JSON 응닔을 ëł”ì‚Źí•˜ì—Ź 상자에 ë¶™ì—Źë„ŁìœŒì„žìš”." @@ -24331,7 +24312,7 @@ msgstr "지난 7음" msgid "Paste" msgstr "ë¶™ì—Źë„Łêž°" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "새 ì»€ëź€ë‹ˆí‹°ëĄœ ê”ŹìĄ°ë„Œ 가젞였렀멎 {theOtherPlatform} 템플멿 URL을 ë¶™ì—Źë„ŁìœŒì„žìš”." @@ -25191,6 +25172,11 @@ msgstr "í”„ëŠŹëŻžì—„ 유형" msgid "Premium until date" msgstr "í”„ëŠŹëŻžì—„ ìą…ëŁŒìŒ" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "쀀ëč„ ì€‘" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "프로필" msgid "Profile badge" msgstr "프로필 배지" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "프로필 배너는 {PREMIUM_PRODUCT_NAME} Ʞ늄입니닀. í”„ëĄœí•„ì— 배너넌 추가하렀멎 {PREMIUM_PRODUCT_NAME}을(넌) ê”Źë…í•˜ì„žìš”." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "읎 읞슀턎슀에서는 프로필 배너넌 ì‚Źìš©í•  수 없슔니닀." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "프로필 배너는 {premiumProductName}읎(가) 필요합니닀" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "프로필 배너넌 ì‚Źìš©í•˜ë €ë©Ž {premiumProductName}읎(가) 필요합니닀." @@ -25838,7 +25824,7 @@ msgstr "ëˆŒëŸŹì„œ 말하Ʞ" msgid "Push-to-talk (limited)" msgstr "ëˆŒëŸŹì„œ 말하Ʞ (제한됚)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "ì›ëłž 입렄에서는 ëˆŒëŸŹì„œ 말하Ʞ가 ëŹŽì‹œë©ë‹ˆë‹€. ì‚Źìš©í•˜ë €ë©Ž 음성 íŹì»€ìŠ€ 또는 ì‚Źìš©ìž ì§€ì •ìœŒëĄœ 전환하섞요." @@ -26551,8 +26537,8 @@ msgstr "ìČšë¶€íŒŒìŒ 삭제" msgid "Remove authenticator app" msgstr "읞슝 앱 제거" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "아바타 삭제" @@ -26561,8 +26547,8 @@ msgstr "아바타 삭제" msgid "Remove background" msgstr "ë°°êČœ 제거" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "배너 삭제" @@ -26625,10 +26611,10 @@ msgstr "항상 위에 표시 핎제" msgid "Remove from URL-only GIF favorites" msgstr "URL 전용 GIF 슐êČšì°Ÿêž°ì—ì„œ 제거" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "아읎윘 삭제" @@ -27331,7 +27317,7 @@ msgstr "닀시 볮냄" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "쎈Ʞ화" @@ -28074,7 +28060,7 @@ msgstr "ëŁšë§ˆë‹ˆì•„ì–Ž" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ì‹œêł„ ë°©í–„ìœŒëĄœ 회전" @@ -28153,8 +28139,8 @@ msgstr "채도" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "화멎 êł”ìœ  읞윔더 ì»šíŠžëĄ€" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "화멎 êł”ìœ ê°€ ìą…ëŁŒë˜ì—ˆìŠ”ë‹ˆë‹€" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "읜지 않은 메시지가 있을 때 앱 아읎윘에 ëčšê°„색 배지 표시" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "êž€ëĄœëȌ í”„ëĄœí•„ì„ ëŹŽì‹œí•˜êł  ê°•ìĄ° 색상만 표시" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "표현 자동 완성에 맞춀 읎ëȘší‹°ìœ˜ 표시" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "낮 프로필 ì‚Źì§„ 대신 êž°ëłž 아바타 표시" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "음소거한 채널에 읜지 않은 메시지 표시" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "읎 ì»€ëź€ë‹ˆí‹°ì— êž€ëĄœëȌ 프로필 아바타 표시" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "읎 ì»€ëź€ë‹ˆí‹°ì— 낮 êž€ëĄœëȌ 프로필 배너 표시" @@ -30720,7 +30706,7 @@ msgstr "걎너뛰Ʞ" msgid "Skip \"Mark all as read\" confirmation" msgstr "\"ëȘšë‘ 읜음\" 확읞 걎너뛰Ʞ" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "자넎Ʞ 걎너뛰Ʞ" @@ -32346,7 +32332,7 @@ msgstr "펞안한 ë ˆìŽì•„ì›ƒìœŒëĄœ 전환" msgid "Switch to dense layout" msgstr "간êȰ한 ë ˆìŽì•„ì›ƒìœŒëĄœ 전환" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "직접 ìž…ë „ìœŒëĄœ 전환" @@ -32734,7 +32720,7 @@ msgstr "작업" msgid "Teleporting you to another voice region..." msgstr "닀넞 음성 ëŠŹì „ìœŒëĄœ 읎동 쀑..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "템플멿" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "역할읎 {permissions} 권한을 ë¶€ì—Źí–ˆìŠ”ë‹ˆë‹€" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "화멎 êł”ìœ  소슀가 더 읎상 ëč„디였넌 ëłŽë‚Žì§€ 않아 화멎 êł”ìœ ê°€ 쀑닚되었슔니닀." @@ -33453,6 +33439,11 @@ msgstr "읎 êł„ì •ì€ 찚닚할 수 없슔니닀." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "읎 작업은 되돌멮 수 없슔니닀. 뮇 ì‚Źìš©ìžë„Œ 포핹한 ëȘšë“  ꎀ렚 데읎터가 ì˜ê”Źì ìœŒëĄœ 삭제됩니닀." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "읎 애니메읎션은 너묮 Ꞟ거나 컀서 자넌 수 없슔니닀. 더 짧거나 작은 파음을 ì‚Źìš©í•Ž ëłŽì„žìš”." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "읎 뎇은 ëč„êł”개읎며 닀넞 ì‚Źìš©ìžê°€ 추가할 수 없슔니 msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "읎 뎇은 êŽ€ëŠŹìž 권한을 요ìČ­í•©ë‹ˆë‹€. 개발자넌 완전히 ì‹ ëą°í•˜ëŠ” êČœìš°ì—ë§Œ 허용하섞요. 대신 개발자에êȌ 더 적은 권한을 요ìȭ핮 ë‹ŹëŒêł  하섞요. 확싀하지 않윌멎 읎 페읎지넌 닫윌섞요." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "읎 람띌우저에서는 애니메읎션 {avifFormatLabel} 파음을 펞집할 수 없슔니닀. 대신 GIF 또는 WebP 파음을 ì—…ëĄœë“œí•˜ì„žìš”." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "읎 람띌우저 윘솔은 개발자 ë„ê”Źìž…ë‹ˆë‹€." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "읎 람띌우저에서는 WebAssembly가 êșŒì ž 있얎 애니메읎션 ìŽëŻžì§€ë„Œ 자넌 수 없슔니닀." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "읎 ê·žëŁč읎 가득 찌슔니닀. 닀넞 ì‚ŹëžŒì„ 추가하렀멎 뚌 msgid "This handoff code has expired. Generate a new one to continue." msgstr "읎 핞드였프 윔드가 ë§ŒëŁŒë˜ì—ˆìŠ”ë‹ˆë‹€. êł„ì†í•˜ë €ë©Ž 새 윔드넌 생성하섞요." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "읎 ìŽëŻžì§€ë„Œ 읜을 수 없슔니닀. 손상되었을 수 있슔니닀." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "ì—…ëĄœë“œ" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "읎 ì»€ëź€ë‹ˆí‹°ì—ì„œ ì‚Źìš©í•  아바타넌 ì—…ëĄœë“œí•˜ì„žìš”" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "읎 ì»€ëź€ë‹ˆí‹°ì—ì„œ ì‚Źìš©í•  배너넌 ì—…ëĄœë“œí•˜ì„žìš”" @@ -36155,10 +36163,10 @@ msgstr "메시지에 파음 및 ëŻžë””ì–Žë„Œ ì—…ëĄœë“œí•©ë‹ˆë‹€." msgid "Upload files and media in this channel." msgstr "읎 채널에 파음 및 ëŻžë””ì–Žë„Œ ì—…ëĄœë“œí•©ë‹ˆë‹€." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "아읎윘 ì—…ëĄœë“œ" @@ -36401,8 +36409,8 @@ msgstr "석탄 테마 ì‚Źìš© (완전한 êČ€ì • 화멎)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "맞춀 ìŽëŻžì§€ ì‚Źìš©" @@ -36462,8 +36470,8 @@ msgstr "필터넌 ì‚Źìš©í•˜ê±°ë‚˜ 킀워드넌 ìž…ë „í•˜ì—Ź 메시지넌 ì°Ÿì•„ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "êž€ëĄœëȌ 프로필 ì‚Źìš©" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "음성 ì°žì—Źìž" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "음성 ìȘ늏" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "위슀윘신" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "{PREMIUM_PRODUCT_NAME}을 ì‚Źìš©í•˜ë©Ž 애니메읎션 아바타({ANIMATED_AVATAR_FORMATS})와 프로필 배너넌 ì“°êł , 태귞넌 원하는 대로 ë°”êŸžêł , ê·ž 밖의 ì—ŹëŸŹ {PREMIUM_PRODUCT_NAME} 혜택을 읎용할 수 있슔니닀." @@ -39334,8 +39342,8 @@ msgstr "ì—Źêž°ì—ì„œ 닀넞 ì»€ëź€ë‹ˆí‹°ì˜ 읎ëȘší‹°ìœ˜ì„ ì‚Źìš©í•˜ë €ë©Ž \"{p msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "ì—Źêž°ì—ì„œ 닀넞 ì»€ëź€ë‹ˆí‹°ì˜ 슀티컀넌 ì‚Źìš©í•˜ë €ë©Ž \"{permissionLabel}\" 권한읎 필요합니닀." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "ì»€ëź€ë‹ˆí‹°ë„Œ 만듀렀멎 뚌저 êł„ì •ì„ ë“±ëĄí•Žì•Œ 합니닀." @@ -39356,8 +39364,8 @@ msgstr "읎 ì»€ëź€ë‹ˆí‹°ì—ì„œ 메시지넌 볎낎렀멎 êł„ì •ì„ ë“±ëĄí•Žì•Œ msgid "You need to verify a phone number to send messages in this community." msgstr "읎 ì»€ëź€ë‹ˆí‹°ì—ì„œ 메시지넌 볎낎렀멎 전화ëȈ혞 읞슝읎 필요합니닀." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "ì»€ëź€ë‹ˆí‹°ë„Œ 만듀렀멎 뚌저 읎메음 ìŁŒì†Œë„Œ 읞슝핎알 합니닀." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "저임된 {savedResolution} ({savedFrameRate} FPS)넌 ì‚Źìš©í•˜ë €ë©Ž {premiumProductName}읎 필요합니닀. 대신 {resolution} ({frameRate} FPS)ìœŒëĄœ êł”ìœ ë©ë‹ˆë‹€." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "혾환되는 ëč„디였 ìœ”ë±ìœŒëĄœ 화멎 êł”ìœ ë„Œ êČŒì‹œí•  수 없얎 쀑지되었슔니닀. 닀시 êł”ìœ í•Ž ëłŽì„žìš”." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "맞춀 URL읎 {inviteEndpoint}/{vanitySlug}(윌)로 섀정되었슔니닀" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "ëč„디였 읞윔더에서 프레임을 더 읎상 읞윔딩하지 않아 화멎 êł”ìœ ê°€ 쀑지되었슔니닀. 닀시 êł”ìœ í•Ž ëłŽì„žìš”." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "유ëč„í‚€" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "확대/축소" diff --git a/fluxer_app/src/features/i18n/locales/lt/messages.po b/fluxer_app/src/features/i18n/locales/lt/messages.po index 0b20dfe3d..a9b46c5ff 100644 --- a/fluxer_app/src/features/i18n/locales/lt/messages.po +++ b/fluxer_app/src/features/i18n/locales/lt/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, netrukus" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} matmenys neatitinka ĆĄio iĆĄtekliaus. Pasirinkite kitą vaizdą arba ÄŻkelkite statinÄŻ vaizdą, kurÄŻ galėsite apkirpti." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} failas per didelis. Pasirinkite failą, maĆŸesnÄŻ nei {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} vaizdai negali bĆ«ti animuoti. Naudokite statinÄŻ vaizdą." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Dalijimasis veikla" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Aktyvumo slenkstis" @@ -3566,11 +3561,11 @@ msgstr "Leisti {everyoneMention} ir {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Leiskite {PRODUCT_NAME} pasiekti jĆ«sĆł kamerą: {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Leiskite {PRODUCT_NAME} pasiekti jĆ«sĆł mikrofoną: {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Leiskite {PRODUCT_NAME} pasiekti jĆ«sĆł mikrofoną. Patikrinkite narĆĄyklės adreso juostą arba nustatymus." @@ -3673,7 +3668,7 @@ msgstr "Leisti nariams be leidimo „{readMessageHistoryPermissionLabel}“ maty msgid "Allow mentions for this role" msgstr "Leisti paminėti ĆĄÄŻ vaidmenÄŻ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Leisti naudoti mikrofoną" @@ -3942,25 +3937,21 @@ msgstr "ir dar {remainingCount}" msgid "Animate on interaction" msgstr "Animuoti sąveikaujant" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animuoti {AVIF_FORMAT_LABEL} failai nepalaikomi. Vietoj to ÄŻkelkite statinÄŻ {AVIF_FORMAT_LABEL} failą." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animuotas {avifFormatLabel} formatas nepalaikomas" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animuoti avatarai ({ANIMATED_AVATAR_FORMATS}) prieinami tik {PREMIUM_PRODUCT_NAME} prenumeratoriams." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animuoti avatarai ({ANIMATED_AVATAR_FORMATS}) ĆĄioje instancijoje negalimi. Vietoj to ÄŻkelkite statinÄŻ paveikslėlÄŻ." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animuotiems avatarams ({animatedAvatarFormats}) reikalingas {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animuoti avatarai ir profilio reklamjuostės" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animuoti avatarai nepasiekiami" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animuotiems avatarams reikalingas {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Animuoto paveikslėlio perĆŸiĆ«ra" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animuoti paveikslėliai ĆĄiam iĆĄtekliui nepalaikomi." @@ -4947,7 +4938,7 @@ msgstr "AutomatiĆĄkai aptikti kalbą" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "AutomatiĆĄkai nustatyti aktyvumo slenkstÄŻ" @@ -5127,15 +5118,15 @@ msgstr "Pasiekiama darbalaukio programoje." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avataras" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avataras per didelis. Pasirinkite failą, maĆŸesnÄŻ nei {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avataras per didelis. Pasirinkite maĆŸesnÄŻ nei {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avataro reĆŸimo pasirinkimas" @@ -5187,11 +5178,11 @@ msgstr "Ć iuo metu nesu prie kompiuterio" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "UĆŸblokuoti nariai" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Reklamjuostė" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Reklamjuostės failas per didelis. Pasirinkite failą, maĆŸesnÄŻ nei {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Reklamjuostės reĆŸimo pasirinkimas" @@ -6107,8 +6098,8 @@ msgstr "Äźsigykite {premiumProductName} dovaną skirtuke „{premiumProductName} msgid "Buy gift" msgstr "Pirkti dovaną" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Kurdami bendruomenę, sutinkate laikytis <0>{PRODUCT_NAME} bendruomenės gairiĆł." @@ -6361,7 +6352,7 @@ msgstr "Čia negalima ÄŻkelti failĆł" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centre" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Keisti avatarą" @@ -6627,9 +6618,9 @@ msgstr "Keisti foną" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Keisti reklamjuostę" @@ -6668,13 +6659,13 @@ msgstr "Keisti grupės slapyvardÄŻ" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Keisti piktogramą" @@ -7669,8 +7660,8 @@ msgstr "Atsiimti dovaną" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "UĆŸregistruokite paskyrą" @@ -8518,8 +8509,8 @@ msgstr "Bendruomenė sudaro sąlygas masiniam uĆŸsipuldinėjimui arba tiksliniam msgid "Community filter" msgstr "Bendruomenės filtras" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Bendruomenės piktograma" @@ -8763,6 +8754,11 @@ msgstr "RaĆĄymo lauko mygtukai" msgid "Composer focus" msgstr "RaĆĄymo lauko fokusavimas" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Glaudinama" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Prijunkite kamerą arba virtualĆł fiksavimo ÄŻrenginÄŻ ir bandykite dar msgid "Connect a display, then try again." msgstr "Prijunkite ekraną ir bandykite dar kartą." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Prijunkite mikrofoną ir bandykite dar kartą." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nepavyko sukurti ĆĄio lipduko" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Nepavyko apkarpyti paveikslėlio" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Ć iuo metu nepavyko atnaujinti balso aktyvumo bendrinimo" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nepavyko ÄŻkelti avataro" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nepavyko ÄŻkelti reklamjuostės" @@ -10230,7 +10226,7 @@ msgstr "Sukurti ir bendrinti" msgid "Create a community" msgstr "Sukurti bendruomenę" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Sukurkite bendruomenę, kurioje galėsite bendrauti su draugais." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Apkarpyti kvietimo foną" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Apkarpymo perĆŸiĆ«ra" @@ -10500,30 +10496,15 @@ msgstr "Apkarpyti profilio reklamjuostę" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Apkarpytas vaizdas per didelis. Pasirinkite maĆŸesnÄŻ plotą arba maĆŸesnÄŻ failą (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "AnimuotĆł {formatLabel} failĆł apkarpymas dar nepalaikomas. Bus naudojamas originalus vaizdas." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "AnimuotĆł {formatLabel} failĆł apkarpymas dar nepalaikomas. Bus naudojamas originalus failas." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "AnimuotĆł failĆł apkarpymas dar nepalaikomas. Bus naudojamas originalus vaizdas." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "AnimuotĆł failĆł apkarpymas dar nepalaikomas. Bus naudojamas originalus failas." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Apkarpyti {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Neturite paskyros?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Nerodyti" @@ -16560,8 +16541,8 @@ msgstr "Grupės DM avatarai naudoja tas pačias bĆ«senos kaukes kaip ir ÄŻprasti msgid "Group DMs" msgstr "Grupės DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Grupės piktograma" @@ -16624,8 +16605,8 @@ msgstr "Grupės nustatymai" msgid "Group typing states" msgstr "Grupės raĆĄymo bĆ«senos" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupė atnaujinta" @@ -16803,7 +16784,7 @@ msgstr "Ć irdelė" msgid "Hebrew" msgstr "hebrajĆł" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "AukĆĄtis" @@ -17510,7 +17491,7 @@ msgstr "Vaizdas nukopijuotas ÄŻ iĆĄkarpinę" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Nepavyko panaudoti vaizdo" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "IĆĄvaizda ir stilius" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "PanaĆĄu, kad naudojate „{0}“. Papildomas „{PRODUCT_NAME}“ apdorojimas gali sukelti garso pulsavimą arba iĆĄkraipymus. Tiesioginė ÄŻvestis perduoda jĆ«sĆł garsą nepakeistą." @@ -22577,7 +22558,7 @@ msgstr "Nieko nerasta" msgid "No mentions yet" msgstr "Kol kas nėra paminėjimĆł" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Mikrofonas nerastas" @@ -23806,7 +23787,7 @@ msgstr "Atidaryti sistemos DM" msgid "Open system picker" msgstr "Atidaryti sistemos parinkiklÄŻ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Atidaryti ĆĄablono JSON" @@ -23820,7 +23801,7 @@ msgstr "Atidaryti uĆŸblokavimo dialogo langą ĆĄioje bendruomenėje." msgid "Open the context menu" msgstr "Atidaryti kontekstinÄŻ meniu" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Atidarykite toliau esančią nuorodą narĆĄyklėje, tada nukopijuokite visą JSON atsakymą ir ÄŻklijuokite jÄŻ ÄŻ laukelÄŻ." @@ -24331,7 +24312,7 @@ msgstr "Paskutinės 7 dienos" msgid "Paste" msgstr "Äźklijuoti" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Äźklijuokite „{theOtherPlatform}“ ĆĄablono URL, kad jo struktĆ«rą importuotumėte ÄŻ naują bendruomenę." @@ -25191,6 +25172,11 @@ msgstr "Premium tipas" msgid "Premium until date" msgstr "Premium iki datos" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "RuoĆĄiama" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profilis" msgid "Profile badge" msgstr "Profilio ĆŸenklelis" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profilio reklamjuostė yra {PREMIUM_PRODUCT_NAME} funkcija. Äźsigykite {PREMIUM_PRODUCT_NAME}, kad galėtumėte pridėti reklamjuostę prie savo profilio." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profilio reklamjuostės ĆĄioje instancijoje neÄŻjungtos." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profilio reklamjuostėms reikalingas {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profilio reklamjuostėms reikalingas {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Kalbėjimas paspaudus" msgid "Push-to-talk (limited)" msgstr "Kalbėjimas paspaudus (ribotas)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Kalbėjimas paspaudus tiesioginėje ÄŻvestyje ignoruojamas. Norėdami jÄŻ naudoti, perjunkite ÄŻ fokusuotą balsą arba pasirinktinÄŻ." @@ -26551,8 +26537,8 @@ msgstr "PaĆĄalinti priedą" msgid "Remove authenticator app" msgstr "PaĆĄalinti autentifikavimo programėlę" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "PaĆĄalinti avatarą" @@ -26561,8 +26547,8 @@ msgstr "PaĆĄalinti avatarą" msgid "Remove background" msgstr "PaĆĄalinti foną" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "PaĆĄalinti reklamjuostę" @@ -26625,10 +26611,10 @@ msgstr "Nerodyti virĆĄuje" msgid "Remove from URL-only GIF favorites" msgstr "PaĆĄalinti iĆĄ mėgstamiausiĆł GIF (tik URL)" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "PaĆĄalinti piktogramą" @@ -27331,7 +27317,7 @@ msgstr "IĆĄsiĆłsta iĆĄ naujo" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Atkurti" @@ -28074,7 +28060,7 @@ msgstr "rumunĆł" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Pasukti pagal laikrodĆŸio rodyklę" @@ -28153,8 +28139,8 @@ msgstr "Sodrumas" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Ekrano bendrinimo kodavimo valdikliai" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Ekrano bendrinimas baigėsi" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Rodyti raudoną ĆŸenklelÄŻ programos piktogramoje, kai turite neperskaitytĆł ĆŸinučiĆł" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Rodyti tik akcento spalvą, ignoruojant visuotinÄŻ profilÄŻ" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Rodyti pasirinktinius jaustukus iĆĄraiĆĄkĆł automatiniame pildyme" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Rodyti numatytąjÄŻ avatarą, ignoruojant jĆ«sĆł visuotinÄŻ profilÄŻ" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Rodyti neperskaitytĆł praneĆĄimĆł indikatoriĆł nutildytuose kanaluose" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Rodyti savo visuotinio profilio avatarą ĆĄioje bendruomenėje" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Rodyti savo visuotinio profilio reklamjuostę ĆĄioje bendruomenėje" @@ -30720,7 +30706,7 @@ msgstr "Praleisti" msgid "Skip \"Mark all as read\" confirmation" msgstr "Praleisti patvirtinimą „PaĆŸymėti visus kaip perskaitytus“" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Praleisti apkarpymą" @@ -32346,7 +32332,7 @@ msgstr "Perjungti ÄŻ patogĆł iĆĄdėstymą" msgid "Switch to dense layout" msgstr "Perjungti ÄŻ tankĆł iĆĄdėstymą" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Perjungti ÄŻ tiesioginÄŻ ÄŻvedimą" @@ -32734,7 +32720,7 @@ msgstr "UĆŸduotys" msgid "Teleporting you to another voice region..." msgstr "Perkeliame jus ÄŻ kitą balso regioną..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Ć ablonas" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Ć is vaidmuo suteikė {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Ekrano bendrinimo ĆĄaltinis nustojo siĆłsti vaizdą, todėl ekrano bendrinimas buvo sustabdytas." @@ -33453,6 +33439,11 @@ msgstr "Ć ios paskyros negalima uĆŸblokuoti." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Ć io veiksmo anuliuoti negalima. Visi susiję duomenys, ÄŻskaitant boto naudotoją, bus visam laikui iĆĄtrinti." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ć i animacija yra per ilga arba per didelė, kad ją bĆ«tĆł galima apkarpyti. Pabandykite trumpesnÄŻ arba maĆŸesnÄŻ failą." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ć is botas nėra vieĆĄas, todėl kiti naudotojai negali jo pridėti." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ć is botas praĆĄo administratoriaus leidimo. Suteikite jÄŻ tik tuo atveju, jei visiĆĄkai pasitikite kĆ«rėju. Verčiau papraĆĄykite kĆ«rėjo praĆĄyti maĆŸiau leidimĆł. Jei nesate tikri, uĆŸdarykite ĆĄÄŻ puslapÄŻ." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ć i narĆĄyklė negali apkarpyti animuotĆł {avifFormatLabel} failĆł. Äźkelkite GIF arba WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Ć i narĆĄyklės konsolė yra kĆ«rėjo ÄŻrankis." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ć ioje narĆĄyklėje iĆĄjungtas WebAssembly, todėl animuotĆł vaizdĆł negalima apkarpyti." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ć i grupė pilna. PaĆĄalinkite ką nors prieĆĄ pridėdami daugiau ĆŸmoni msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ć is perdavimo kodas nebegalioja. Norėdami tęsti, sugeneruokite naują." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Ć io paveikslėlio nepavyko nuskaityti. Jis gali bĆ«ti sugadintas." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Äźkelti" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Äźkelkite pasirinktinÄŻ ĆĄios bendruomenės avatarą" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Äźkelkite pasirinktinę ĆĄios bendruomenės reklamjuostę" @@ -36155,10 +36163,10 @@ msgstr "Äźkelkite failus ir mediją ÄŻ ĆŸinutes." msgid "Upload files and media in this channel." msgstr "Äźkelkite failus ir mediją ÄŻ ĆĄÄŻ kanalą." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Äźkelti piktogramą" @@ -36401,8 +36409,8 @@ msgstr "Naudoti anglies temą (visiĆĄkai juodi pavirĆĄiai)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Naudoti pasirinktinÄŻ paveikslėlÄŻ" @@ -36462,8 +36470,8 @@ msgstr "Norėdami rasti ĆŸinutes, naudokite filtrus arba ÄŻveskite raktinius ĆŸo #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Naudoti visuotinÄŻ profilÄŻ" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Balso pokalbio dalyviai" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Balso apdorojimas" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Viskonsinas" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Naudodami {PREMIUM_PRODUCT_NAME}, galite naudoti animuotus avatarus ({ANIMATED_AVATAR_FORMATS}) ir profilio reklamjuostes, tinkinti savo ĆŸymą ir atrakinti daugybę kitĆł {PREMIUM_PRODUCT_NAME} privilegijĆł." @@ -39334,8 +39342,8 @@ msgstr "Norėdami čia naudoti jaustukus iĆĄ kitĆł bendruomeniĆł, turite turėti msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Norėdami čia naudoti lipdukus iĆĄ kitĆł bendruomeniĆł, turite turėti leidimą „{permissionLabel}“." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "PrieĆĄ kurdami bendruomenę turite uĆŸregistruoti savo paskyrą." @@ -39356,8 +39364,8 @@ msgstr "Kad galėtumėte siĆłsti ĆŸinutes ĆĄioje bendruomenėje, turite uĆŸregis msgid "You need to verify a phone number to send messages in this community." msgstr "Norėdami siĆłsti ĆŸinutes ĆĄioje bendruomenėje, turite patvirtinti telefono numerÄŻ." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "PrieĆĄ kurdami bendruomenę, turite patvirtinti savo el. paĆĄto adresą." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "JĆ«sĆł iĆĄsaugotas vaizdo ÄŻraĆĄas {savedResolution} su {savedFrameRate} kadrĆł per sekundę reikalauja {premiumProductName}, todėl bendrinama naudojant {resolution} su {frameRate} kadrĆł per sekundę." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "JĆ«sĆł ekrano bendrinimas negalėjo bĆ«ti paskelbtas naudojant suderinamą vaizdo kodeką, todėl jis buvo sustabdytas. Pabandykite bendrinti dar kartą." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "JĆ«sĆł pasirinktinis URL nustatytas ÄŻ {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "JĆ«sĆł vaizdo kodavimo ÄŻrenginys nustojo koduoti kadrus, todėl jĆ«sĆł ekrano bendrinimas buvo sustabdytas. Pabandykite bendrinti dar kartą." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Priartinimas" diff --git a/fluxer_app/src/features/i18n/locales/nl/messages.po b/fluxer_app/src/features/i18n/locales/nl/messages.po index 4a5cb81a7..73713631f 100644 --- a/fluxer_app/src/features/i18n/locales/nl/messages.po +++ b/fluxer_app/src/features/i18n/locales/nl/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, binnenkort beschikbaar" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "De afmetingen van dit bestand zijn niet geschikt voor {label}. Kies een andere afbeelding of upload een statische afbeelding die je kunt bijsnijden." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Het bestand voor {label} is te groot. Kies een bestand kleiner dan {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Afbeeldingen voor {label} mogen niet geanimeerd zijn. Gebruik een statische afbeelding." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Activiteit delen" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Activiteitsdrempel" @@ -3566,11 +3561,11 @@ msgstr "Sta {everyoneMention} en {hereMention} toe" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Sta {PRODUCT_NAME} toe om je camera te gebruiken in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Geef {PRODUCT_NAME} toegang tot je microfoon via {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Sta {PRODUCT_NAME} toe om je microfoon te gebruiken. Controleer de adresbalk of instellingen van je browser." @@ -3673,7 +3668,7 @@ msgstr "Sta leden zonder de machtiging \"{readMessageHistoryPermissionLabel}\" t msgid "Allow mentions for this role" msgstr "Vermeldingen voor deze rol toestaan" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Microfoontoegang toestaan" @@ -3942,25 +3937,21 @@ msgstr "en nog {remainingCount} andere" msgid "Animate on interaction" msgstr "Animatie bij interactie" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Geanimeerde {AVIF_FORMAT_LABEL}-bestanden worden niet ondersteund. Upload in plaats daarvan een statisch {AVIF_FORMAT_LABEL}-bestand." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Geanimeerde {avifFormatLabel}-bestanden worden niet ondersteund" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Geanimeerde avatars ({ANIMATED_AVATAR_FORMATS}) zijn exclusief beschikbaar voor {PREMIUM_PRODUCT_NAME}-abonnees." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Geanimeerde avatars ({ANIMATED_AVATAR_FORMATS}) zijn niet beschikbaar op deze instantie. Upload in plaats daarvan een statische afbeelding." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Geanimeerde avatars ({animatedAvatarFormats}) vereisen {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Geanimeerde avatars en profielbanners" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Geanimeerde avatars niet beschikbaar" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Geanimeerde avatars vereisen {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Voorbeeld van geanimeerde afbeelding" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Geanimeerde afbeeldingen worden niet ondersteund voor dit bestand." @@ -4947,7 +4938,7 @@ msgstr "Taal automatisch detecteren" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Activiteitsdrempel automatisch instellen" @@ -5127,15 +5118,15 @@ msgstr "Beschikbaar in de desktopapp." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Het avatarbestand is te groot. Kies een bestand kleiner dan {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "De avatar is te groot. Kies een bestand kleiner dan {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avatarmodus selecteren" @@ -5187,11 +5178,11 @@ msgstr "Nu afwezig" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Verbannen gebruikers" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Bannerbestand is te groot. Kies een bestand kleiner dan {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Bannermodus selecteren" @@ -6107,8 +6098,8 @@ msgstr "Koop een {premiumProductName}-cadeau via het tabblad {premiumProductName msgid "Buy gift" msgstr "Cadeau kopen" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Door een community aan te maken, ga je akkoord met het volgen en naleven van de <0>communityrichtlijnen van {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Kan hier geen bestanden uploaden" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Gecentreerd" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Avatar wijzigen" @@ -6627,9 +6618,9 @@ msgstr "Achtergrond wijzigen" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Banner wijzigen" @@ -6668,13 +6659,13 @@ msgstr "Groepsbijnaam wijzigen" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Pictogram wijzigen" @@ -7669,8 +7660,8 @@ msgstr "Cadeau inwisselen" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Voltooi de registratie van je account" @@ -8518,8 +8509,8 @@ msgstr "De community faciliteert groepsgewijze aanvallen of gerichte intimidatie msgid "Community filter" msgstr "Communityfilter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Communitypictogram" @@ -8763,6 +8754,11 @@ msgstr "Knoppen bij berichtinvoer" msgid "Composer focus" msgstr "Focus op berichtinvoer" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Comprimeren" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Sluit een camera of virtueel opnameapparaat aan en probeer het opnieuw." msgid "Connect a display, then try again." msgstr "Sluit een beeldscherm aan en probeer het opnieuw." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Sluit een microfoon aan en probeer het opnieuw." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Sticker kon niet worden gemaakt" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Afbeelding bijsnijden mislukt" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Het delen van spraakchatactiviteit kon nu niet worden bijgewerkt" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Avatar kon niet worden geĂŒpload" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Banner kon niet worden geĂŒpload" @@ -10230,7 +10226,7 @@ msgstr "Maken en delen" msgid "Create a community" msgstr "Community aanmaken" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Maak een community om met je vrienden te chatten." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Achtergrond van uitnodiging bijsnijden" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Voorbeeld van bijgesneden afbeelding" @@ -10500,30 +10496,15 @@ msgstr "Profielbanner bijsnijden" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "De bijgesneden afbeelding is te groot. Kies een kleiner gebied of een kleiner bestand (max. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Het bijsnijden van geanimeerde {formatLabel}-bestanden wordt nog niet ondersteund. De originele afbeelding wordt gebruikt." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Het bijsnijden van geanimeerde {formatLabel}-bestanden wordt nog niet ondersteund. De oorspronkelijke upload wordt gebruikt." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Het bijsnijden van geanimeerde bestanden wordt nog niet ondersteund. De originele afbeelding wordt gebruikt." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Het bijsnijden van geanimeerde bestanden wordt nog niet ondersteund. De oorspronkelijke upload wordt gebruikt." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Bijsnijden {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Nog geen account?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Niet tonen" @@ -16560,8 +16541,8 @@ msgstr "Groeps-DM-avatars gebruiken dezelfde statusmaskers als gewone avatars, i msgid "Group DMs" msgstr "Groeps-DM's" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Groepspictogram" @@ -16624,8 +16605,8 @@ msgstr "Groepsinstellingen" msgid "Group typing states" msgstr "Typestatussen in groepen" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Groep bijgewerkt" @@ -16803,7 +16784,7 @@ msgstr "Hart" msgid "Hebrew" msgstr "Hebreeuws" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Hoogte" @@ -17510,7 +17491,7 @@ msgstr "Afbeelding gekopieerd naar klembord" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Afbeelding kon niet worden gebruikt" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Uiterlijk" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Het lijkt erop dat je {0} gebruikt. Als je daar de audioverwerking van {PRODUCT_NAME} bovenop toepast, kan dit pompend geluid of vervorming veroorzaken. Directe invoer stuurt je audio onbewerkt door." @@ -22577,7 +22558,7 @@ msgstr "Geen resultaten gevonden" msgid "No mentions yet" msgstr "Nog geen vermeldingen" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Geen microfoon gevonden" @@ -23806,7 +23787,7 @@ msgstr "Systeem-DM openen" msgid "Open system picker" msgstr "Systeemkiezer openen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Sjabloon-JSON openen" @@ -23820,7 +23801,7 @@ msgstr "Open het dialoogvenster om iemand uit deze community te verbannen." msgid "Open the context menu" msgstr "Open het contextmenu" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Open de onderstaande link in je browser, kopieer het volledige JSON-antwoord en plak het in het vak." @@ -24331,7 +24312,7 @@ msgstr "Afgelopen 7 dagen" msgid "Paste" msgstr "Plakken" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Plak een {theOtherPlatform}-sjabloon-URL om de structuur ervan te importeren in een nieuwe community." @@ -25191,6 +25172,11 @@ msgstr "Premiumtype" msgid "Premium until date" msgstr "Premium tot datum" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Voorbereiden" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profiel" msgid "Profile badge" msgstr "Profielbadge" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profielbanners zijn een {PREMIUM_PRODUCT_NAME}-functie. Schaf {PREMIUM_PRODUCT_NAME} aan om een banner aan je profiel toe te voegen." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profielbanners zijn niet ingeschakeld op deze instantie." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profielbanners vereisen {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profielbanners vereisen {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (beperkt)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk wordt genegeerd bij directe invoer. Schakel over naar gerichte spraak of aangepast om het te gebruiken." @@ -26551,8 +26537,8 @@ msgstr "Bijlage verwijderen" msgid "Remove authenticator app" msgstr "Authenticator-app verwijderen" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Avatar verwijderen" @@ -26561,8 +26547,8 @@ msgstr "Avatar verwijderen" msgid "Remove background" msgstr "Achtergrond verwijderen" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Banner verwijderen" @@ -26625,10 +26611,10 @@ msgstr "Niet meer altijd bovenaan" msgid "Remove from URL-only GIF favorites" msgstr "Verwijderen uit URL-gebaseerde GIF-favorieten" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Pictogram verwijderen" @@ -27331,7 +27317,7 @@ msgstr "Opnieuw verzonden" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Opnieuw instellen" @@ -28074,7 +28060,7 @@ msgstr "Roemeens" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Rechtsom draaien" @@ -28153,8 +28139,8 @@ msgstr "Verzadiging" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Encoderinstellingen voor schermdelen" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Schermdeling beĂ«indigd" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Toon een rode badge op het apppictogram wanneer je ongelezen berichten hebt" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Alleen accentkleur tonen, je algemene profiel negeren" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Aangepaste emoji's tonen in suggesties voor expressies" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Standaardavatar tonen, je algemene profiel wordt genegeerd" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Ongelezenindicator tonen op gedempte kanalen" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Toon de avatar van je algemene profiel in deze community" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Toon de banner van je algemene profiel in deze community" @@ -30720,7 +30706,7 @@ msgstr "Overslaan" msgid "Skip \"Mark all as read\" confirmation" msgstr "Bevestiging voor \"Alles als gelezen markeren\" overslaan" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Bijsnijden overslaan" @@ -32346,7 +32332,7 @@ msgstr "Overschakelen naar comfortabele lay-out" msgid "Switch to dense layout" msgstr "Overschakelen naar compacte lay-out" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Overschakelen naar directe invoer" @@ -32734,7 +32720,7 @@ msgstr "Taken" msgid "Teleporting you to another voice region..." msgstr "We verplaatsen je naar een andere spraakregio..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Sjabloon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "De rol verleende {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "De bron van het gedeelde scherm verstuurde geen video meer. Daarom is het schermdelen gestopt." @@ -33453,6 +33439,11 @@ msgstr "Dit account kan niet worden geblokkeerd." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Deze actie kan niet ongedaan worden gemaakt. Alle bijbehorende gegevens, inclusief de botgebruiker, worden permanent verwijderd." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Deze animatie is te lang of te groot om bij te snijden. Probeer een korter of kleiner bestand." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Deze bot is niet openbaar en kan niet worden toegevoegd door andere gebr msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Deze bot vraagt om beheerdersrechten. Geef deze alleen als je de ontwikkelaar volledig vertrouwt. Vraag hen om minder rechten aan te vragen. Sluit deze pagina als je twijfelt." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Deze browser kan geen geanimeerde {avifFormatLabel}-bestanden bijsnijden. Upload in plaats daarvan een GIF of WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Deze browserconsole is een ontwikkelaarstool." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Deze browser heeft WebAssembly uitgeschakeld, dus geanimeerde afbeeldingen kunnen niet worden bijgesneden." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Deze groep is vol. Verwijder iemand voordat je meer mensen toevoegt." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Deze overdrachtscode is verlopen. Genereer een nieuwe om verder te gaan." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Deze afbeelding kon niet worden gelezen. Mogelijk is deze beschadigd." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Uploaden" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Upload een aangepaste avatar voor deze community" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Upload een aangepaste banner voor deze community" @@ -36155,10 +36163,10 @@ msgstr "Upload bestanden en media in berichten." msgid "Upload files and media in this channel." msgstr "Upload bestanden en media in dit kanaal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Pictogram uploaden" @@ -36401,8 +36409,8 @@ msgstr "Kolenzwart thema gebruiken (gitzwarte oppervlakken)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Aangepaste afbeelding gebruiken" @@ -36462,8 +36470,8 @@ msgstr "Gebruik filters of typ trefwoorden om berichten te vinden" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Algemeen profiel gebruiken" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Deelnemers spraakoproep" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Spraakverwerking" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Met {PREMIUM_PRODUCT_NAME} kun je geanimeerde avatars ({ANIMATED_AVATAR_FORMATS}) en profielbanners gebruiken, je tag aanpassen en vele andere {PREMIUM_PRODUCT_NAME}-voordelen ontgrendelen." @@ -39334,8 +39342,8 @@ msgstr "Je hebt de machtiging \"{permissionLabel}\" nodig om hier emoji uit ande msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Je hebt de \"{permissionLabel}\"-machtiging nodig om hier stickers van andere communities te gebruiken." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Je moet de registratie van je account voltooien voordat je een community kunt aanmaken." @@ -39356,8 +39364,8 @@ msgstr "Je moet de registratie van je account voltooien om berichten in deze com msgid "You need to verify a phone number to send messages in this community." msgstr "Je moet een telefoonnummer verifiĂ«ren om berichten te kunnen versturen in deze community." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Je moet je e-mailadres verifiĂ«ren voordat je een community kunt aanmaken." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Je opgeslagen {savedResolution} met {savedFrameRate} FPS vereist {premiumProductName}, dus delen gebruiken {resolution} met {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Je gedeelde scherm kon niet met een compatibele videocodec worden uitgezonden. Daarom is het schermdelen gestopt. Probeer je scherm opnieuw te delen." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Je aangepaste URL is ingesteld op {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Je video-encoder is gestopt met het coderen van frames. Daarom is het schermdelen gestopt. Probeer je scherm opnieuw te delen." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoomen" diff --git a/fluxer_app/src/features/i18n/locales/no/messages.po b/fluxer_app/src/features/i18n/locales/no/messages.po index 245ec0517..cf714a3e1 100644 --- a/fluxer_app/src/features/i18n/locales/no/messages.po +++ b/fluxer_app/src/features/i18n/locales/no/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, kommer snart" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label}-dimensjonene samsvarer ikke med denne ressursen. Velg et annet bilde eller last opp et statisk bilde du kan beskjĂŠre." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Filen for {label} er for stor. Velg en fil som er mindre enn {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label}-bilder kan ikke vĂŠre animerte. Bruk et statisk bilde." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Aktivitetsdeling" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Aktivitetsterskel" @@ -3566,11 +3561,11 @@ msgstr "Tillat {everyoneMention} og {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Tillat {PRODUCT_NAME} Ă„ fĂ„ tilgang til kameraet ditt i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Gi {PRODUCT_NAME} tilgang til mikrofonen din i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Tillat {PRODUCT_NAME} Ă„ fĂ„ tilgang til mikrofonen din. Sjekk nettleserens adressefelt eller innstillinger." @@ -3673,7 +3668,7 @@ msgstr "Tillat medlemmer uten tillatelsen {readMessageHistoryPermissionLabel} Ă„ msgid "Allow mentions for this role" msgstr "Tillat omtaler for denne rollen" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Tillat mikrofontilgang" @@ -3942,25 +3937,21 @@ msgstr "og {remainingCount} til" msgid "Animate on interaction" msgstr "Animer ved interaksjon" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animerte {AVIF_FORMAT_LABEL}-filer stĂžttes ikke. Last opp en statisk {AVIF_FORMAT_LABEL}-fil i stedet." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animert {avifFormatLabel} stĂžttes ikke" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animerte avatarer ({ANIMATED_AVATAR_FORMATS}) er bare tilgjengelige for {PREMIUM_PRODUCT_NAME}-abonnenter." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animerte avatarer ({ANIMATED_AVATAR_FORMATS}) er ikke tilgjengelige pĂ„ denne instansen. Last opp et statisk bilde i stedet." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animerte avatarer ({animatedAvatarFormats}) krever {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animerte avatarer og profilbannere" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animerte avatarer er ikke tilgjengelige" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animerte avatarer krever {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ForhĂ„ndsvisning av animert bilde" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animerte bilder stĂžttes ikke for dette elementet." @@ -4947,7 +4938,7 @@ msgstr "Gjenkjenn sprĂ„k automatisk" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Angi aktivitetsterskel automatisk" @@ -5127,15 +5118,15 @@ msgstr "Tilgjengelig i skrivebordsappen." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatarfilen er for stor. Velg en fil som er mindre enn {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avataren er for stor – velg en under {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Valg av avatarmodus" @@ -5187,11 +5178,11 @@ msgstr "Borte akkurat nĂ„" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Utestengte brukere" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Bannerfilen er for stor. Velg en fil som er mindre enn {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Valg av bannermodus" @@ -6107,8 +6098,8 @@ msgstr "KjĂžp en {premiumProductName}-gave fra {premiumProductName}-fanen for Ă„ msgid "Buy gift" msgstr "KjĂžp gave" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Ved Ă„ opprette et fellesskap godtar du Ă„ fĂžlge og overholde <0>retningslinjene for {PRODUCT_NAME}-fellesskapet." @@ -6361,7 +6352,7 @@ msgstr "Kan ikke laste opp filer her" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Midtstilt" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Endre avatar" @@ -6627,9 +6618,9 @@ msgstr "Endre bakgrunn" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Endre banner" @@ -6668,13 +6659,13 @@ msgstr "Endre kallenavn i gruppen" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Endre ikon" @@ -7669,8 +7660,8 @@ msgstr "Hent gave" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "FullfĂžr registreringen av kontoen din" @@ -8518,8 +8509,8 @@ msgstr "Fellesskapet legger til rette for hets eller mĂ„lrettet trakassering." msgid "Community filter" msgstr "Fellesskapsfilter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Fellesskapsikon" @@ -8763,6 +8754,11 @@ msgstr "Knapper i skrivefeltet" msgid "Composer focus" msgstr "Fokus pĂ„ skrivefeltet" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimerer" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Koble til et kamera eller en virtuell opptaksenhet, og prĂžv deretter p msgid "Connect a display, then try again." msgstr "Koble til en skjerm, og prĂžv igjen." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Koble til en mikrofon og prĂžv igjen." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Kunne ikke opprette dette klistremerket" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Kunne ikke beskjĂŠre bildet" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Kunne ikke oppdatere deling av taleaktivitet akkurat nĂ„" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Kunne ikke laste opp avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Kunne ikke laste opp banner" @@ -10230,7 +10226,7 @@ msgstr "Opprett og del" msgid "Create a community" msgstr "Opprett et fellesskap" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Opprett et fellesskap der du og vennene dine kan chatte." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "BeskjĂŠr invitasjonsbakgrunn" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ForhĂ„ndsvisning av beskjĂŠring" @@ -10500,30 +10496,15 @@ msgstr "BeskjĂŠr profilbanner" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Det beskĂ„rne bildet er for stort. Velg et mindre omrĂ„de eller en mindre fil (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "BeskjĂŠring av animerte {formatLabel}-filer stĂžttes ikke ennĂ„. Det originale bildet blir brukt." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "BeskjĂŠring av animerte {formatLabel}-filer stĂžttes ikke ennĂ„. Den originale opplastingen blir brukt." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "BeskjĂŠring av animerte filer stĂžttes ikke ennĂ„. Det originale bildet blir brukt." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "BeskjĂŠring av animerte filer stĂžttes ikke ennĂ„. Den originale opplastingen blir brukt." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "BeskjĂŠrer {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Har du ingen konto?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Ikke vis" @@ -16560,8 +16541,8 @@ msgstr "Avatarer for gruppechatter bruker de samme statusmaskene som vanlige ava msgid "Group DMs" msgstr "Gruppechatter" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Gruppeikon" @@ -16624,8 +16605,8 @@ msgstr "Gruppeinnstillinger" msgid "Group typing states" msgstr "Gruppens skriveindikatorer" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Gruppe oppdatert" @@ -16803,7 +16784,7 @@ msgstr "Hjerte" msgid "Hebrew" msgstr "Hebraisk" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "HĂžyde" @@ -17510,7 +17491,7 @@ msgstr "Bilde kopiert til utklippstavlen" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Bildet kunne ikke brukes" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Utseende og fĂžlelse" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Det ser ut som du bruker {0}. Hvis du legger til lydbehandlingen fra {PRODUCT_NAME} i tillegg, kan det fĂžre til pumping eller forvrengning. Direkte inndata sender lyden din uendret gjennom." @@ -22577,7 +22558,7 @@ msgstr "Ingen treff" msgid "No mentions yet" msgstr "Ingen omtaler ennĂ„" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Ingen mikrofon funnet" @@ -23806,7 +23787,7 @@ msgstr "Åpne systemsamtalen" msgid "Open system picker" msgstr "Åpne systemvelger" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Åpne mal-JSON" @@ -23820,7 +23801,7 @@ msgstr "Åpne dialogen for utestenging fra dette fellesskapet." msgid "Open the context menu" msgstr "Åpne hurtigmenyen" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Åpne lenken nedenfor i nettleseren din, kopier hele JSON-svaret og lim det inn i boksen." @@ -24331,7 +24312,7 @@ msgstr "Siste 7 dager" msgid "Paste" msgstr "Lim inn" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Lim inn en {theOtherPlatform}-mal-URL for Ă„ importere strukturen til et nytt fellesskap." @@ -25191,6 +25172,11 @@ msgstr "Premiumtype" msgid "Premium until date" msgstr "Sluttdato for Premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Forbereder" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Profilmerke" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profilbannere er en {PREMIUM_PRODUCT_NAME}-funksjon. Skaff deg {PREMIUM_PRODUCT_NAME} for Ă„ legge til et banner pĂ„ profilen din." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profilbannere er ikke aktivert pĂ„ denne instansen." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profilbannere krever {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profilbannere krever {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Trykk for Ă„ snakke" msgid "Push-to-talk (limited)" msgstr "Trykk for Ă„ snakke (begrenset)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Trykk for Ă„ snakke ignoreres med «Direkte inndata». Bytt til «Tale i fokus» eller «Egendefinert» for Ă„ bruke det." @@ -26551,8 +26537,8 @@ msgstr "Fjern vedlegg" msgid "Remove authenticator app" msgstr "Fjern autentiseringsapp" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Fjern avatar" @@ -26561,8 +26547,8 @@ msgstr "Fjern avatar" msgid "Remove background" msgstr "Fjern bakgrunn" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Fjern banner" @@ -26625,10 +26611,10 @@ msgstr "Slutt Ă„ vise Ăžverst" msgid "Remove from URL-only GIF favorites" msgstr "Fjern fra URL-baserte GIF-favoritter" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Fjern ikon" @@ -27331,7 +27317,7 @@ msgstr "Sendt pĂ„ nytt" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Tilbakestill" @@ -28074,7 +28060,7 @@ msgstr "Rumensk" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Roter med klokken" @@ -28153,8 +28139,8 @@ msgstr "Metning" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Kontroller for skjermdelingskoding" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Skjermdelingen ble avsluttet" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Vis et rĂždt merke pĂ„ appikonet nĂ„r du har uleste meldinger" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Vis bare aksentfargen og se bort fra den globale profilen din" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Vis egendefinerte emojier i autofullfĂžring av uttrykk" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Vis standardavataren og se bort fra den globale profilen din" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Vis ulest-indikator pĂ„ dempede kanaler" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Vis din globale profilavatar i dette fellesskapet" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Vis banneret for den globale profilen din i dette fellesskapet" @@ -30720,7 +30706,7 @@ msgstr "Hopp over" msgid "Skip \"Mark all as read\" confirmation" msgstr "Hopp over bekreftelse for «Merk alle som lest»" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Hopp over beskjĂŠring" @@ -32346,7 +32332,7 @@ msgstr "Bytt til romslig oppsett" msgid "Switch to dense layout" msgstr "Bytt til kompakt oppsett" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Bytt til direkte inndata" @@ -32734,7 +32720,7 @@ msgstr "Oppgaver" msgid "Teleporting you to another voice region..." msgstr "Teleporterer deg til en annen taleregion 
" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Mal" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rollen ga {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Kilden for skjermdelingen sluttet Ă„ sende video, sĂ„ skjermdelingen ble stoppet." @@ -33453,6 +33439,11 @@ msgstr "Denne kontoen kan ikke blokkeres." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Denne handlingen kan ikke angres. Alle tilknyttede data, inkludert bot-brukeren, blir slettet permanent." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Denne animasjonen er for lang eller for stor til Ă„ beskjĂŠres. PrĂžv en kortere eller mindre fil." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Denne boten er ikke offentlig og kan ikke legges til av andre brukere." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Denne boten ber om administratortillatelsen. Gi den bare denne tillatelsen hvis du stoler fullt og helt pĂ„ utvikleren. Be utvikleren om Ă„ be om fĂŠrre tillatelser i stedet. Lukk denne siden hvis du er usikker." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Denne nettleseren kan ikke beskjĂŠre animerte {avifFormatLabel}-filer. Last opp en GIF eller WebP i stedet." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Denne nettleserkonsollen er et utviklerverktĂžy." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Nettleseren din har WebAssembly deaktivert, sĂ„ animerte bilder kan ikke beskjĂŠres." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Denne gruppen er full. Fjern noen fĂžr du legger til flere." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Denne overfĂžringskoden har utlĂžpt. Generer en ny for Ă„ fortsette." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Dette bildet kunne ikke leses. Det kan vĂŠre skadet." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Last opp" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Last opp en egendefinert avatar for dette fellesskapet" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Last opp et egendefinert banner for dette fellesskapet" @@ -36155,10 +36163,10 @@ msgstr "Last opp filer og medier i meldinger." msgid "Upload files and media in this channel." msgstr "Last opp filer og medier i denne kanalen." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Last opp ikon" @@ -36401,8 +36409,8 @@ msgstr "Bruk kulltema (beksvarte overflater)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Bruk egendefinert bilde" @@ -36462,8 +36470,8 @@ msgstr "Bruk filtre eller skriv inn sĂžkeord for Ă„ finne meldinger" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Bruk global profil" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Taledeltakere" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Talebehandling" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Med {PREMIUM_PRODUCT_NAME} kan du bruke animerte avatarer ({ANIMATED_AVATAR_FORMATS}) og profilbannere, tilpasse taggen din og lĂ„se opp mange andre {PREMIUM_PRODUCT_NAME}-fordeler." @@ -39334,8 +39342,8 @@ msgstr "Du trenger tillatelsen «{permissionLabel}» for Ă„ bruke emojier fra an msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Du trenger tillatelsen «{permissionLabel}» for Ă„ bruke klistremerker fra andre fellesskap her." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Du mĂ„ fullfĂžre registreringen av kontoen din fĂžr du kan opprette et fellesskap." @@ -39356,8 +39364,8 @@ msgstr "Du mĂ„ fullfĂžre registreringen av kontoen din for Ă„ sende meldinger i msgid "You need to verify a phone number to send messages in this community." msgstr "Du mĂ„ bekrefte et telefonnummer for Ă„ sende meldinger i dette fellesskapet." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Du mĂ„ bekrefte e-postadressen din fĂžr du kan opprette et fellesskap." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Ditt lagrede {savedResolution} med {savedFrameRate} FPS krever {premiumProductName}, sĂ„ delinger bruker {resolution} med {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Skjermdelingen din kunne ikke publiseres med en kompatibel videokodek, sĂ„ den ble stoppet. PrĂžv Ă„ dele igjen." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Den egendefinerte URL-en er nĂ„ satt til {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Videokoderen din sluttet Ă„ kode bilder, sĂ„ skjermdelingen ble stoppet. PrĂžv Ă„ dele igjen." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/pl/messages.po b/fluxer_app/src/features/i18n/locales/pl/messages.po index 48679b3ff..659b55ffe 100644 --- a/fluxer_app/src/features/i18n/locales/pl/messages.po +++ b/fluxer_app/src/features/i18n/locales/pl/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel} – juĆŒ wkrĂłtce" msgid "{kilobits} kbps" msgstr "{kilobits} kb/s" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Wymiary {label} nie pasują do tego zasobu. Wybierz inny obraz albo przeƛlij statyczny obraz, ktĂłry moĆŒesz przyciąć." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Plik {label} jest za duĆŒy. Wybierz plik mniejszy niĆŒ {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Obrazy {label} nie mogą być animowane. UĆŒyj statycznego obrazu." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Udostępnianie aktywnoƛci" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "PrĂłg aktywnoƛci" @@ -3566,11 +3561,11 @@ msgstr "ZezwĂłl na {everyoneMention} i {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "ZezwĂłl aplikacji {PRODUCT_NAME} na dostęp do kamery w obszarze {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "ZezwĂłl aplikacji {PRODUCT_NAME} na dostęp do mikrofonu w: {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "ZezwĂłl aplikacji {PRODUCT_NAME} na dostęp do mikrofonu. SprawdĆș pasek adresu lub ustawienia przeglądarki." @@ -3673,7 +3668,7 @@ msgstr "ZezwĂłl czƂonkom bez uprawnienia „{readMessageHistoryPermissionLabel} msgid "Allow mentions for this role" msgstr "ZezwĂłl na wzmianki dla tej roli" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ZezwĂłl na dostęp do mikrofonu" @@ -3942,25 +3937,21 @@ msgstr "i jeszcze {remainingCount}" msgid "Animate on interaction" msgstr "Animuj przy interakcji" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animowane pliki {AVIF_FORMAT_LABEL} nie są obsƂugiwane. Zamiast tego przeƛlij statyczny plik {AVIF_FORMAT_LABEL}." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animowane pliki {avifFormatLabel} nie są obsƂugiwane" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animowane awatary ({ANIMATED_AVATAR_FORMATS}) są dostępne wyƂącznie dla subskrybentĂłw {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animowane awatary ({ANIMATED_AVATAR_FORMATS}) nie są dostępne w tej instancji. Zamiast tego przeƛlij statyczny obraz." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animowane awatary ({animatedAvatarFormats}) wymagają {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animowane awatary i banery profilowe" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animowane awatary niedostępne" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animowane awatary wymagają {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Podgląd animowanego obrazu" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animowane obrazy nie są obsƂugiwane dla tego zasobu." @@ -4947,7 +4938,7 @@ msgstr "Automatyczne wykrywanie języka" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Automatyczne ustawianie progu aktywnoƛci" @@ -5127,15 +5118,15 @@ msgstr "Dostępne w aplikacji komputerowej." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Awatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Plik awatara jest za duĆŒy. Wybierz plik mniejszy niĆŒ {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Awatar jest za duĆŒy — wybierz plik mniejszy niĆŒ {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "WybĂłr trybu awatara" @@ -5187,11 +5178,11 @@ msgstr "Chwilowo mnie nie ma" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Zbanowani uĆŒytkownicy" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Baner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Plik banera jest za duĆŒy. Wybierz plik mniejszy niĆŒ {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "WybĂłr trybu banera" @@ -6107,8 +6098,8 @@ msgstr "Kup prezent {premiumProductName} w zakƂadce {premiumProductName}, aby p msgid "Buy gift" msgstr "Kup prezent" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Tworząc spoƂecznoƛć, zobowiązujesz się do przestrzegania i egzekwowania <0>zasad spoƂecznoƛci {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Nie moĆŒna tu przesyƂać plikĂłw" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Wyƛrodkowano" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "ZmieƄ awatar" @@ -6627,9 +6618,9 @@ msgstr "ZmieƄ tƂo" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "ZmieƄ baner" @@ -6668,13 +6659,13 @@ msgstr "ZmieƄ pseudonim w grupie" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "ZmieƄ ikonę" @@ -7669,8 +7660,8 @@ msgstr "Odbierz prezent" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "DokoƄcz rejestrację swojego konta" @@ -8518,8 +8509,8 @@ msgstr "SpoƂecznoƛć uƂatwia nękanie grupowe lub ukierunkowane ataki." msgid "Community filter" msgstr "Filtr spoƂecznoƛci" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ikona spoƂecznoƛci" @@ -8763,6 +8754,11 @@ msgstr "Przyciski edytora wiadomoƛci" msgid "Composer focus" msgstr "Fokus edytora wiadomoƛci" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Kompresowanie" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "PodƂącz kamerę lub wirtualne urządzenie do przechwytywania, a nastę msgid "Connect a display, then try again." msgstr "PodƂącz wyƛwietlacz, a następnie sprĂłbuj ponownie." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "PodƂącz mikrofon i sprĂłbuj ponownie." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nie udaƂo się utworzyć tej naklejki" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Nie udaƂo się przyciąć obrazu" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Nie udaƂo się teraz zaktualizować udostępniania aktywnoƛci gƂosowej" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nie udaƂo się przesƂać awatara" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nie udaƂo się przesƂać banera" @@ -10230,7 +10226,7 @@ msgstr "UtwĂłrz i udostępnij" msgid "Create a community" msgstr "UtwĂłrz spoƂecznoƛć" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "StwĂłrz spoƂecznoƛć, aby rozmawiać ze znajomymi." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Przytnij tƂo zaproszenia" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Podgląd kadrowania" @@ -10500,30 +10496,15 @@ msgstr "Przytnij baner profilowy" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Przycięty obraz jest za duĆŒy. Wybierz mniejszy obszar lub mniejszy plik (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Przycinanie animowanych plikĂłw {formatLabel} nie jest jeszcze obsƂugiwane. Zostanie uĆŒyty oryginalny obraz." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Przycinanie animowanych plikĂłw {formatLabel} nie jest jeszcze obsƂugiwane. Zostanie uĆŒyty oryginalny plik." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Przycinanie animowanych plikĂłw nie jest jeszcze obsƂugiwane. Zostanie uĆŒyty oryginalny obraz." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Przycinanie animowanych plikĂłw nie jest jeszcze obsƂugiwane. Zostanie uĆŒyty oryginalny plik." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Przycinanie {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Nie masz konta?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Nie pokazuj" @@ -16560,8 +16541,8 @@ msgstr "Awatary czatĂłw grupowych uĆŒywają tych samych masek statusu co zwykƂe msgid "Group DMs" msgstr "Czaty grupowe" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ikona grupy" @@ -16624,8 +16605,8 @@ msgstr "Ustawienia grupy" msgid "Group typing states" msgstr "Stany pisania w grupie" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupa zaktualizowana" @@ -16803,7 +16784,7 @@ msgstr "Serce" msgid "Hebrew" msgstr "Hebrajski" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Wysokoƛć" @@ -17510,7 +17491,7 @@ msgstr "Obraz skopiowany do schowka" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Nie moĆŒna uĆŒyć obrazu" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Wygląd i styl" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Wygląda na to, ĆŒe uĆŒywasz {0}. Dodatkowe przetwarzanie dĆșwięku przez {PRODUCT_NAME} moĆŒe powodować pompowanie gƂoƛnoƛci lub znieksztaƂcenia. Tryb „Bezpoƛrednie wejƛcie” przepuszcza dĆșwięk bez zmian." @@ -22577,7 +22558,7 @@ msgstr "Brak wynikĂłw" msgid "No mentions yet" msgstr "Brak wzmianek" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nie znaleziono mikrofonu" @@ -23806,7 +23787,7 @@ msgstr "OtwĂłrz rozmowę z kontem systemowym" msgid "Open system picker" msgstr "OtwĂłrz systemowy panel wyboru" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "OtwĂłrz szablon JSON" @@ -23820,7 +23801,7 @@ msgstr "OtwĂłrz okno banowania w tej spoƂecznoƛci." msgid "Open the context menu" msgstr "OtwĂłrz menu kontekstowe" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "OtwĂłrz poniĆŒszy link w przeglądarce, a następnie skopiuj caƂą odpowiedĆș JSON i wklej ją w polu." @@ -24331,7 +24312,7 @@ msgstr "Ostatnie 7 dni" msgid "Paste" msgstr "Wklej" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Wklej adres URL szablonu z {theOtherPlatform}, aby zaimportować jego strukturę do nowej spoƂecznoƛci." @@ -25191,6 +25172,11 @@ msgstr "Typ Premium" msgid "Premium until date" msgstr "Premium waĆŒne do" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Przygotowywanie" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Odznaka profilu" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Banery profilu to funkcja {PREMIUM_PRODUCT_NAME}. ZdobądĆș {PREMIUM_PRODUCT_NAME}, aby dodać baner do swojego profilu." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Banery profilowe nie są wƂączone na tej instancji." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Banery profilowe wymagają {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Banery profilowe wymagają {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Naciƛnij i mĂłw" msgid "Push-to-talk (limited)" msgstr "Naciƛnij i mĂłw (ograniczone)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Funkcja „naciƛnij i mĂłw” jest ignorowana w trybie „Bezpoƛrednie wejƛcie”. Aby z niej korzystać, przeƂącz profil na „Wyrazisty gƂos” lub „Niestandardowy”." @@ -26551,8 +26537,8 @@ msgstr "UsuƄ zaƂącznik" msgid "Remove authenticator app" msgstr "UsuƄ aplikację uwierzytelniającą" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "UsuƄ awatar" @@ -26561,8 +26547,8 @@ msgstr "UsuƄ awatar" msgid "Remove background" msgstr "UsuƄ tƂo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "UsuƄ baner" @@ -26625,10 +26611,10 @@ msgstr "UsuƄ z gĂłry" msgid "Remove from URL-only GIF favorites" msgstr "UsuƄ z ulubionych GIF-Ăłw zapisanych na podstawie adresu URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "UsuƄ ikonę" @@ -27331,7 +27317,7 @@ msgstr "WysƂano ponownie" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Resetuj" @@ -28074,7 +28060,7 @@ msgstr "RumuƄski" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Obróć zgodnie z ruchem wskazĂłwek zegara" @@ -28153,8 +28139,8 @@ msgstr "Nasycenie" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Sterowanie ustawieniami kodowania udostępniania ekranu" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Udostępnianie ekranu zakoƄczone" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "PokaĆŒ czerwony znacznik na ikonie aplikacji, gdy masz nieprzeczytane wiadomoƛci" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "PokaĆŒ tylko kolor akcentu, ignorując profil globalny" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "PokaĆŒ niestandardowe emoji w autouzupeƂnianiu wyraĆŒeƄ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "PokaĆŒ domyƛlny awatar, ignorując TwĂłj profil globalny" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "PokaĆŒ wskaĆșnik nieprzeczytanych wiadomoƛci na wyciszonych kanaƂach" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "PokaĆŒ swĂłj globalny awatar profilowy w tej spoƂecznoƛci" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "PokaĆŒ swĂłj globalny baner profilowy w tej spoƂecznoƛci" @@ -30720,7 +30706,7 @@ msgstr "PomiƄ" msgid "Skip \"Mark all as read\" confirmation" msgstr "PomiƄ potwierdzenie „Oznacz wszystkie jako przeczytane”" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "PomiƄ kadrowanie" @@ -32346,7 +32332,7 @@ msgstr "PrzeƂącz na wygodny ukƂad" msgid "Switch to dense layout" msgstr "PrzeƂącz na zwarty ukƂad" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "PrzeƂącz na bezpoƛrednie wejƛcie" @@ -32734,7 +32720,7 @@ msgstr "Zadania" msgid "Teleporting you to another voice region..." msgstr "Przenosimy Cię do innego regionu gƂosowego..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Szablon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rola przyznaƂa {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "ĆčrĂłdƂo udostępniania ekranu przestaƂo wysyƂać wideo, więc udostępnianie ekranu zostaƂo zatrzymane." @@ -33453,6 +33439,11 @@ msgstr "Tego konta nie moĆŒna zablokować." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Tej czynnoƛci nie moĆŒna cofnąć. Wszystkie powiązane dane, w tym konto bota, zostaną trwale usunięte." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Ten plik animacji jest za dƂugi lub za duĆŒy, aby go przyciąć. SprĂłbuj uĆŒyć krĂłtszego lub mniejszego pliku." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Ten bot nie jest publiczny i nie moĆŒe być dodawany przez innych uĆŒytk msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Ten bot prosi o uprawnienia administratora. Udziel ich tylko, jeƛli w peƂni ufasz deweloperowi. Poproƛ go, aby zamiast tego zaĆŒÄ…daƂ mniej uprawnieƄ. Zamknij tę stronę, jeƛli nie masz pewnoƛci." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Ta przeglądarka nie moĆŒe przycinać animowanych plikĂłw {avifFormatLabel}. Zamiast tego przeƛlij plik GIF lub WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Ta konsola przeglądarki to narzędzie dla programistĂłw." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Ta przeglądarka ma wyƂączony WebAssembly, więc animowane obrazy nie mogą być przycinane." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Ta grupa jest peƂna. UsuƄ kogoƛ, zanim dodasz więcej osĂłb." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Ten kod przekazania wygasƂ. Wygeneruj nowy, aby kontynuować." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Nie moĆŒna odczytać tego obrazu. MoĆŒe być uszkodzony." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Przeƛlij" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Przeƛlij wƂasny awatar dla tej spoƂecznoƛci" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Przeƛlij wƂasny baner dla tej spoƂecznoƛci" @@ -36155,10 +36163,10 @@ msgstr "PrzesyƂaj pliki i multimedia w wiadomoƛciach." msgid "Upload files and media in this channel." msgstr "PrzesyƂaj pliki i multimedia na ten kanaƂ." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Przeƛlij ikonę" @@ -36401,8 +36409,8 @@ msgstr "UĆŒyj motywu węglowego (caƂkowicie czarne powierzchnie)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "UĆŒyj wƂasnego obrazu" @@ -36462,8 +36470,8 @@ msgstr "UĆŒyj filtrĂłw lub wpisz sƂowa kluczowe, aby znaleĆșć wiadomoƛci" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "UĆŒyj profilu globalnego" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Uczestnicy rozmowy gƂosowej" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Przetwarzanie gƂosu" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Dzięki {PREMIUM_PRODUCT_NAME} moĆŒesz uĆŒywać animowanych awatarĂłw ({ANIMATED_AVATAR_FORMATS}) i banerĂłw profilowych, dostosowywać swĂłj tag i odblokować wiele innych korzyƛci z {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Potrzebujesz uprawnienia „{permissionLabel}”, aby uĆŒywać tutaj emo msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Aby uĆŒywać naklejek z innych spoƂecznoƛci, potrzebujesz uprawnienia „{permissionLabel}”." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Musisz dokoƄczyć rejestrację konta, zanim utworzysz spoƂecznoƛć." @@ -39356,8 +39364,8 @@ msgstr "Musisz dokoƄczyć rejestrację konta, aby wysyƂać wiadomoƛci w tej s msgid "You need to verify a phone number to send messages in this community." msgstr "Aby wysyƂać wiadomoƛci w tej spoƂecznoƛci, musisz zweryfikować swĂłj numer telefonu." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Musisz zweryfikować swĂłj adres e-mail, zanim utworzysz spoƂecznoƛć." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Twoje zapisane {savedResolution} przy {savedFrameRate} FPS wymaga {premiumProductName}, więc udostępnianie uĆŒywa {resolution} przy {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Nie udaƂo się opublikować udostępniania ekranu za pomocą zgodnego kodeka wideo, dlatego zostaƂo ono zatrzymane. SprĂłbuj udostępnić ponownie." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "TwĂłj niestandardowy adres URL zostaƂ ustawiony na {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "TwĂłj koder wideo przestaƂ kodować klatki, więc udostępnianie ekranu zostaƂo zatrzymane. SprĂłbuj udostępnić ponownie." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Powiększenie" diff --git a/fluxer_app/src/features/i18n/locales/pt-BR/messages.po b/fluxer_app/src/features/i18n/locales/pt-BR/messages.po index a4e31dee6..78c45615e 100644 --- a/fluxer_app/src/features/i18n/locales/pt-BR/messages.po +++ b/fluxer_app/src/features/i18n/locales/pt-BR/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, em breve" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "As dimensĂ”es de {label} nĂŁo correspondem a este recurso. Escolha outra imagem ou envie uma imagem estĂĄtica que vocĂȘ possa recortar." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "O arquivo {label} Ă© muito grande. Escolha um arquivo menor que {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Imagens {label} nĂŁo podem ser animadas. Use uma imagem estĂĄtica." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Compartilhamento de atividade" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Limite de atividade" @@ -3566,11 +3561,11 @@ msgstr "Permitir {everyoneMention} e {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Permita que o {PRODUCT_NAME} acesse sua cĂąmera em {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Permita que o {PRODUCT_NAME} acesse seu microfone em {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Permita que o {PRODUCT_NAME} acesse seu microfone. Verifique a barra de endereço ou as configuraçÔes do seu navegador." @@ -3673,7 +3668,7 @@ msgstr "Permitir que membros sem a permissĂŁo {readMessageHistoryPermissionLabel msgid "Allow mentions for this role" msgstr "Permitir mençÔes a este cargo" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Permitir acesso ao microfone" @@ -3942,25 +3937,21 @@ msgstr "e mais {remainingCount}" msgid "Animate on interaction" msgstr "Animar ao interagir" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Arquivos {AVIF_FORMAT_LABEL} animados nĂŁo sĂŁo compatĂ­veis. Em vez disso, envie um arquivo {AVIF_FORMAT_LABEL} estĂĄtico." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "{avifFormatLabel} animado nĂŁo Ă© compatĂ­vel" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Avatares animados ({ANIMATED_AVATAR_FORMATS}) estĂŁo disponĂ­veis exclusivamente para assinantes {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Avatares animados ({ANIMATED_AVATAR_FORMATS}) nĂŁo estĂŁo disponĂ­veis nesta instĂąncia. Envie uma imagem estĂĄtica em vez disso." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Avatares animados ({animatedAvatarFormats}) exigem {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatares e banners de perfil animados" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatares animados nĂŁo estĂŁo disponĂ­veis" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Avatares animados exigem {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "PrĂ©via de imagem animada" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Imagens animadas nĂŁo sĂŁo compatĂ­veis com este recurso." @@ -4947,7 +4938,7 @@ msgstr "Detectar idioma automaticamente" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Definir limite de atividade automaticamente" @@ -5127,15 +5118,15 @@ msgstr "DisponĂ­vel no app para computador." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "O arquivo do avatar Ă© muito grande. Escolha um arquivo menor que {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "O avatar Ă© muito grande. Escolha um com menos de {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Seleção do modo do avatar" @@ -5187,11 +5178,11 @@ msgstr "Ausente no momento" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "UsuĂĄrios banidos" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "O arquivo do banner Ă© muito grande. Escolha um arquivo menor que {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Seleção do modo do banner" @@ -6107,8 +6098,8 @@ msgstr "Compre um presente {premiumProductName} na aba {premiumProductName} para msgid "Buy gift" msgstr "Comprar presente" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Ao criar uma comunidade, vocĂȘ concorda em seguir e fazer cumprir as <0>diretrizes da comunidade do {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "NĂŁo Ă© possĂ­vel enviar arquivos aqui" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centralizado" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Alterar avatar" @@ -6627,9 +6618,9 @@ msgstr "Alterar plano de fundo" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Alterar banner" @@ -6668,13 +6659,13 @@ msgstr "Alterar apelido do grupo" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Alterar Ă­cone" @@ -7669,8 +7660,8 @@ msgstr "Resgatar presente" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Reivindique sua conta" @@ -8518,8 +8509,8 @@ msgstr "A comunidade facilita ataques em massa ou abuso direcionado." msgid "Community filter" msgstr "Filtro da comunidade" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Ícone da comunidade" @@ -8763,6 +8754,11 @@ msgstr "BotĂ”es do editor de mensagens" msgid "Composer focus" msgstr "Foco do editor de mensagens" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Comprimindo" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Conecte uma cĂąmera ou dispositivo de captura virtual e tente novamente. msgid "Connect a display, then try again." msgstr "Conecte um monitor e tente novamente." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Conecte um microfone e tente novamente." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "NĂŁo foi possĂ­vel criar esta figurinha" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "NĂŁo foi possĂ­vel cortar a imagem" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "NĂŁo foi possĂ­vel atualizar o compartilhamento de atividade de voz agora" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "NĂŁo foi possĂ­vel enviar o avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "NĂŁo foi possĂ­vel enviar o banner" @@ -10230,7 +10226,7 @@ msgstr "Criar e compartilhar" msgid "Create a community" msgstr "Criar uma comunidade" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Crie uma comunidade para vocĂȘ e seus amigos conversarem." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Recortar imagem de fundo do convite" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "PrĂ©via do corte" @@ -10500,30 +10496,15 @@ msgstr "Recortar banner do perfil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "A imagem cortada Ă© muito grande. Escolha uma ĂĄrea menor ou um arquivo menor (mĂĄx. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Ainda nĂŁo Ă© possĂ­vel cortar arquivos {formatLabel} animados. A imagem original serĂĄ usada." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Ainda nĂŁo Ă© possĂ­vel cortar arquivos {formatLabel} animados. O arquivo original serĂĄ usado." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Ainda nĂŁo Ă© possĂ­vel cortar arquivos animados. A imagem original serĂĄ usada." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Ainda nĂŁo Ă© possĂ­vel cortar arquivos animados. O arquivo original serĂĄ usado." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Cortando {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "NĂŁo tem uma conta?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "NĂŁo mostrar" @@ -16560,8 +16541,8 @@ msgstr "Os avatares de conversas em grupo usam as mesmas mĂĄscaras de status dos msgid "Group DMs" msgstr "Conversas em grupo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Ícone do grupo" @@ -16624,8 +16605,8 @@ msgstr "ConfiguraçÔes do grupo" msgid "Group typing states" msgstr "Status de digitação do grupo" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grupo atualizado" @@ -16803,7 +16784,7 @@ msgstr "Coração" msgid "Hebrew" msgstr "Hebraico" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Altura" @@ -17510,7 +17491,7 @@ msgstr "Imagem copiada para a ĂĄrea de transferĂȘncia" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "NĂŁo foi possĂ­vel usar a imagem" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "AparĂȘncia" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Parece que vocĂȘ estĂĄ usando {0}. Usar o processamento do {PRODUCT_NAME} em conjunto pode causar bombeamento ou distorção. A entrada direta passa seu ĂĄudio sem alteraçÔes." @@ -22577,7 +22558,7 @@ msgstr "Nenhum resultado encontrado" msgid "No mentions yet" msgstr "Nenhuma menção ainda" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nenhum microfone encontrado" @@ -23806,7 +23787,7 @@ msgstr "Abrir mensagem direta do sistema" msgid "Open system picker" msgstr "Abrir seletor do sistema" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Abrir JSON do modelo" @@ -23820,7 +23801,7 @@ msgstr "Abrir a caixa de diĂĄlogo de banimento para esta comunidade." msgid "Open the context menu" msgstr "Abrir o menu de contexto" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Abra o link abaixo no seu navegador, depois copie a resposta JSON inteira e cole na caixa." @@ -24331,7 +24312,7 @@ msgstr "Últimos 7 dias" msgid "Paste" msgstr "Colar" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Cole a URL de um modelo do {theOtherPlatform} para importar sua estrutura para uma nova comunidade." @@ -25191,6 +25172,11 @@ msgstr "Tipo premium" msgid "Premium until date" msgstr "Data de fim do Premium" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Preparando" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Perfil" msgid "Profile badge" msgstr "Selo do perfil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Banners de perfil sĂŁo um recurso {PREMIUM_PRODUCT_NAME}. Obtenha o {PREMIUM_PRODUCT_NAME} para adicionar um banner ao seu perfil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Banners de perfil nĂŁo estĂŁo ativados nesta instĂąncia." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Banners de perfil exigem {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Banners de perfil exigem {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Apertar para falar" msgid "Push-to-talk (limited)" msgstr "Apertar para falar (limitado)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "\"Apertar para falar\" Ă© ignorado no modo Entrada direta. Mude para Voz focada ou Personalizado para usar o recurso." @@ -26551,8 +26537,8 @@ msgstr "Remover anexo" msgid "Remove authenticator app" msgstr "Remover app autenticador" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Remover avatar" @@ -26561,8 +26547,8 @@ msgstr "Remover avatar" msgid "Remove background" msgstr "Remover plano de fundo" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Remover banner" @@ -26625,10 +26611,10 @@ msgstr "Desativar sempre no topo" msgid "Remove from URL-only GIF favorites" msgstr "Remover dos GIFs favoritos salvos por URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Remover Ă­cone" @@ -27331,7 +27317,7 @@ msgstr "Reenviado" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Redefinir" @@ -28074,7 +28060,7 @@ msgstr "Romeno" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Girar no sentido horĂĄrio" @@ -28153,8 +28139,8 @@ msgstr "Saturação" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Controles do codificador de compartilhamento de tela" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Compartilhamento de tela encerrado" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Mostrar um aviso vermelho no Ă­cone do app quando houver mensagens nĂŁo lidas" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Mostrar apenas a cor de destaque, ignorando seu perfil global" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Mostrar emojis personalizados no preenchimento automĂĄtico de expressĂ”es" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Mostrar avatar padrĂŁo, ignorando seu perfil global" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Mostrar indicador de nĂŁo lidas em canais silenciados" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Mostrar o avatar do seu perfil global nesta comunidade" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Mostrar seu banner de perfil global nesta comunidade" @@ -30720,7 +30706,7 @@ msgstr "Pular" msgid "Skip \"Mark all as read\" confirmation" msgstr "Pular confirmação de \"Marcar tudo como lido\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Pular recorte" @@ -32346,7 +32332,7 @@ msgstr "Mudar para o layout confortĂĄvel" msgid "Switch to dense layout" msgstr "Mudar para layout compacto" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Mudar para entrada direta" @@ -32734,7 +32720,7 @@ msgstr "Tarefas" msgid "Teleporting you to another voice region..." msgstr "Transferindo vocĂȘ para outra regiĂŁo de voz..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Modelo" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "O cargo concedeu {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "A fonte de compartilhamento de tela parou de enviar vĂ­deo, entĂŁo o seu compartilhamento de tela foi interrompido." @@ -33453,6 +33439,11 @@ msgstr "NĂŁo Ă© possĂ­vel bloquear esta conta." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Esta ação nĂŁo poderĂĄ ser desfeita. Todos os dados associados, incluindo o bot, serĂŁo excluĂ­dos permanentemente." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Esta animação Ă© muito longa ou grande para ser cortada. Tente um arquivo menor ou mais curto." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Este bot nĂŁo Ă© pĂșblico e nĂŁo pode ser adicionado por outros usuĂĄrio msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Este bot solicita permissĂŁo de administrador. Conceda-a apenas se vocĂȘ confiar totalmente no desenvolvedor. Peça para que solicite menos permissĂ”es. Feche esta pĂĄgina se nĂŁo tiver certeza." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Este navegador nĂŁo consegue cortar arquivos animados de {avifFormatLabel}. Envie um GIF ou WebP em vez disso." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Este console do navegador Ă© uma ferramenta de desenvolvedor." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Este navegador estĂĄ com o WebAssembly desativado, entĂŁo imagens animadas nĂŁo podem ser cortadas." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Este grupo estĂĄ cheio. Remova alguĂ©m antes de adicionar mais pessoas." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Este cĂłdigo de transferĂȘncia expirou. Gere um novo para continuar." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Esta imagem nĂŁo pĂŽde ser lida. Ela pode estar danificada." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Enviar" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Enviar um avatar personalizado para esta comunidade" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Enviar um banner personalizado para esta comunidade" @@ -36155,10 +36163,10 @@ msgstr "Envie arquivos e mĂ­dias em mensagens." msgid "Upload files and media in this channel." msgstr "Envie arquivos e mĂ­dias neste canal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Enviar Ă­cone" @@ -36401,8 +36409,8 @@ msgstr "Usar tema carvĂŁo (superfĂ­cies pretas)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Usar imagem personalizada" @@ -36462,8 +36470,8 @@ msgstr "Use filtros ou digite palavras-chave para encontrar mensagens" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Usar perfil global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Participantes da chamada de voz" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Processamento de voz" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Com o {PREMIUM_PRODUCT_NAME}, vocĂȘ pode usar avatares animados ({ANIMATED_AVATAR_FORMATS}), banners de perfil, personalizar sua tag e desbloquear muitos outros benefĂ­cios do {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "VocĂȘ precisa da permissĂŁo \"{permissionLabel}\" para usar emojis de ou msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "VocĂȘ precisa da permissĂŁo \"{permissionLabel}\" para usar figurinhas de outras comunidades aqui." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "VocĂȘ precisa reivindicar sua conta antes de criar uma comunidade." @@ -39356,8 +39364,8 @@ msgstr "VocĂȘ precisa reivindicar sua conta para enviar mensagens nesta comunida msgid "You need to verify a phone number to send messages in this community." msgstr "VocĂȘ precisa verificar um nĂșmero de telefone para enviar mensagens nesta comunidade." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "VocĂȘ precisa verificar seu endereço de e-mail antes de criar uma comunidade." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Seu {savedResolution} salvo a {savedFrameRate} FPS precisa de {premiumProductName}, entĂŁo o compartilhamento usa {resolution} a {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Seu compartilhamento de tela nĂŁo pĂŽde ser publicado com um codec de vĂ­deo compatĂ­vel, por isso foi interrompido. Tente compartilhar novamente." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Seu URL personalizado foi definido como {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Seu codificador de vĂ­deo parou de codificar quadros, entĂŁo o compartilhamento de tela foi interrompido. Tente compartilhar novamente." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/ro/messages.po b/fluxer_app/src/features/i18n/locales/ro/messages.po index 691bc0a9e..c97f7051b 100644 --- a/fluxer_app/src/features/i18n/locales/ro/messages.po +++ b/fluxer_app/src/features/i18n/locales/ro/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, Ăźn curĂąnd" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Dimensiunile pentru {label} nu corespund acestui element. Alege o altă imagine sau Ăźncarcă o imagine statică pe care o poți decupa." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Fișierul {label} este prea mare. Alege un fișier mai mic de {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Imaginile {label} nu pot fi animate. Folosește o imagine statică." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Partajarea activității" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Prag de activitate" @@ -3566,11 +3561,11 @@ msgstr "Permite {everyoneMention} și {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Permite aplicației {PRODUCT_NAME} să ĂźÈ›i acceseze camera Ăźn {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Permite aplicației {PRODUCT_NAME} să ĂźÈ›i acceseze microfonul Ăźn {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Permite aplicației {PRODUCT_NAME} să ĂźÈ›i acceseze microfonul. Verifică bara de adrese sau setările browserului." @@ -3673,7 +3668,7 @@ msgstr "Permite membrilor fără permisiunea {readMessageHistoryPermissionLabel} msgid "Allow mentions for this role" msgstr "Permite menționări pentru acest rol" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Permite accesul la microfon" @@ -3942,25 +3937,21 @@ msgstr "și Ăźncă {remainingCount}" msgid "Animate on interaction" msgstr "Animează la interacțiune" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Fișierele {AVIF_FORMAT_LABEL} animate nu sunt acceptate. Încarcă Ăźn schimb un fișier {AVIF_FORMAT_LABEL} static." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Formatul {avifFormatLabel} animat nu este acceptat" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Avatarele animate ({ANIMATED_AVATAR_FORMATS}) sunt disponibile exclusiv abonaților {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Avatarele animate ({ANIMATED_AVATAR_FORMATS}) nu sunt disponibile pe această instanță. Încarcă Ăźn schimb o imagine statică." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Avatarele animate ({animatedAvatarFormats}) necesită {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Avatare animate și bannere de profil" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Avatarele animate nu sunt disponibile" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Avatarele animate necesită {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Previzualizare imagine animată" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Imaginile animate nu sunt acceptate pentru acest element." @@ -4947,7 +4938,7 @@ msgstr "Detectare automată a limbii" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Setează automat pragul de activitate" @@ -5127,15 +5118,15 @@ msgstr "Disponibil Ăźn aplicația desktop." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Fișierul avatar este prea mare. Alege un fișier mai mic de {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatarul este prea mare — alege unul sub {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Selectare mod avatar" @@ -5187,11 +5178,11 @@ msgstr "Plecat acum" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Utilizatori banați" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Fișierul banner este prea mare. Alege un fișier mai mic de {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Selectare mod banner" @@ -6107,8 +6098,8 @@ msgstr "Cumpără un cadou {premiumProductName} din fila {premiumProductName} pe msgid "Buy gift" msgstr "Cumpără cadou" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Prin crearea unei comunități, ești de acord să respecți și să susții <0>regulile comunității {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "Nu se pot Ăźncărca fișiere aici" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrat" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Schimbă avatarul" @@ -6627,9 +6618,9 @@ msgstr "Schimbă fundalul" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Schimbă bannerul" @@ -6668,13 +6659,13 @@ msgstr "Schimbă pseudonimul Ăźn grup" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Schimbă pictograma" @@ -7669,8 +7660,8 @@ msgstr "Revendică cadoul" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Revendică-ți contul" @@ -8518,8 +8509,8 @@ msgstr "Comunitatea facilitează atacurile Ăźn grup sau abuzurile direcționate. msgid "Community filter" msgstr "Filtru de comunități" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Pictogramă comunitate" @@ -8763,6 +8754,11 @@ msgstr "Butoane din editor" msgid "Composer focus" msgstr "Focalizare pe editor" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Se comprimă" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Conectează o cameră sau un dispozitiv de captură virtual, apoi Ăźncea msgid "Connect a display, then try again." msgstr "Conectează un ecran, apoi Ăźncearcă din nou." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Conectează un microfon și Ăźncearcă din nou." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Nu s-a putut crea acest sticker" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Nu s-a putut decupa imaginea" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Nu s-a putut actualiza acum partajarea activității vocale" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Nu s-a putut Ăźncărca avatarul" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Nu s-a putut Ăźncărca bannerul" @@ -10230,7 +10226,7 @@ msgstr "Creează și distribuie" msgid "Create a community" msgstr "Creează o comunitate" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Creează o comunitate pentru tine și prietenii tăi, unde puteți discuta." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Decupează fundalul invitației" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Previzualizare decupare" @@ -10500,30 +10496,15 @@ msgstr "Decupează bannerul de profil" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Imaginea decupată este prea mare. Alege o zonă mai mică sau un fișier mai mic (maxim {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Decuparea fișierelor animate {formatLabel} nu este Ăźncă acceptată. Se va folosi imaginea originală." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Decuparea fișierelor animate {formatLabel} nu este Ăźncă acceptată. Se va folosi fișierul original." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Decuparea fișierelor animate nu este Ăźncă acceptată. Se va folosi imaginea originală." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Decuparea fișierelor animate nu este Ăźncă acceptată. Se va folosi fișierul original." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Se decupează {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Nu ai un cont?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Nu afișa" @@ -16560,8 +16541,8 @@ msgstr "Avatarele DM de grup folosesc aceleași măști de stare ca avatarele ob msgid "Group DMs" msgstr "DM-uri de grup" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Pictograma grupului" @@ -16624,8 +16605,8 @@ msgstr "Setări grup" msgid "Group typing states" msgstr "Stări de tastare Ăźn grup" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grup actualizat" @@ -16803,7 +16784,7 @@ msgstr "Inimă" msgid "Hebrew" msgstr "Ebraică" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Înălțime" @@ -17510,7 +17491,7 @@ msgstr "Imagine copiată Ăźn clipboard" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Imaginea nu a putut fi utilizată" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Aspect și stil" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Se pare că folosești {0}. Suprapunerea procesării audio de la {PRODUCT_NAME} poate cauza distorsiuni sau efecte de pompare. Intrarea directă transmite sunetul netratat." @@ -22577,7 +22558,7 @@ msgstr "Niciun rezultat găsit" msgid "No mentions yet" msgstr "Încă nu există mențiuni" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Nu s-a găsit niciun microfon" @@ -23806,7 +23787,7 @@ msgstr "Deschide DM-ul de sistem" msgid "Open system picker" msgstr "Deschide selectorul de sistem" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Deschide șablonul JSON" @@ -23820,7 +23801,7 @@ msgstr "Deschide fereastra de banare pentru această comunitate." msgid "Open the context menu" msgstr "Deschide meniul contextual" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Deschide linkul de mai jos Ăźn browser, apoi copiază Ăźntregul răspuns JSON și lipește-l Ăźn căsuță." @@ -24331,7 +24312,7 @@ msgstr "Ultimele 7 zile" msgid "Paste" msgstr "Lipește" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Lipește un URL de șablon {theOtherPlatform} pentru a-i importa structura Ăźntr-o comunitate nouă." @@ -25191,6 +25172,11 @@ msgstr "Tip premium" msgid "Premium until date" msgstr "Premium pĂąnă la data de" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Pregătire" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Insignă de profil" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Bannerele de profil sunt o funcție {PREMIUM_PRODUCT_NAME}. Obține {PREMIUM_PRODUCT_NAME} pentru a adăuga un banner la profilul tău." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Bannerele de profil nu sunt activate pe această instanță." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Bannerele de profil necesită {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Bannerele de profil necesită {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Push-to-talk" msgid "Push-to-talk (limited)" msgstr "Push-to-talk (limitat)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Push-to-talk este ignorat Ăźn modul intrare directă. Comută pe voce focalizată sau pe profilul personalizat ca să Ăźl poți folosi." @@ -26551,8 +26537,8 @@ msgstr "Elimină atașamentul" msgid "Remove authenticator app" msgstr "Elimină aplicația de autentificare" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Elimină avatarul" @@ -26561,8 +26547,8 @@ msgstr "Elimină avatarul" msgid "Remove background" msgstr "Elimină fundalul" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Elimină bannerul" @@ -26625,10 +26611,10 @@ msgstr "Scoate fereastra din prim-plan" msgid "Remove from URL-only GIF favorites" msgstr "Elimină din favoritele GIF salvate doar prin URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Elimină pictograma" @@ -27331,7 +27317,7 @@ msgstr "Retrimis" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Resetare" @@ -28074,7 +28060,7 @@ msgstr "RomĂąnă" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Rotește Ăźn sens orar" @@ -28153,8 +28139,8 @@ msgstr "Saturație" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Controalele codificatorului pentru partajarea ecranului" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Partajarea ecranului s-a Ăźncheiat" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Afișează o insignă roșie pe pictograma aplicației cĂąnd ai mesaje necitite" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Afișează doar culoarea de accent, ignorĂąnd profilul tău global" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Afișează emoji personalizate Ăźn completarea automată a expresiilor" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Afișează avatarul implicit, ignorĂąnd profilul tău global" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Afișează indicatorul de mesaje necitite pe canalele puse pe silențios" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Afișează-ți avatarul de profil global Ăźn această comunitate" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Afișează-ți bannerul de profil global Ăźn această comunitate" @@ -30720,7 +30706,7 @@ msgstr "Omitere" msgid "Skip \"Mark all as read\" confirmation" msgstr "Omitere confirmare „Marchează tot ca citit”" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Omite decuparea" @@ -32346,7 +32332,7 @@ msgstr "Treci la aspectul confortabil" msgid "Switch to dense layout" msgstr "Treci la aspectul compact" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Treci la intrarea directă" @@ -32734,7 +32720,7 @@ msgstr "Activități" msgid "Teleporting you to another voice region..." msgstr "Te teleportăm Ăźn altă regiune vocală..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Șablon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rolul a acordat {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Sursa partajării ecranului a Ăźncetat să trimită video, astfel ĂźncĂąt partajarea ecranului s-a oprit." @@ -33453,6 +33439,11 @@ msgstr "Acest cont nu poate fi blocat." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Această acțiune nu poate fi anulată. Toate datele asociate, inclusiv utilizatorul bot, vor fi șterse definitiv." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Animația este prea lungă sau prea mare pentru a fi decupată. Încearcă un fișier mai scurt sau mai mic." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Acest bot nu este public și nu poate fi adăugat de alți utilizatori." msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Acest bot solicită permisiunea de administrator. Acordă această permisiune doar dacă ai Ăźncredere deplină Ăźn dezvoltator. Mai bine roagă-l să solicite mai puține permisiuni. Închide această pagină dacă nu ești sigur." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Browserul tău nu poate decupa fișiere animate {avifFormatLabel}. Încarcă Ăźn schimb un GIF sau WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Această consolă de browser este un instrument pentru dezvoltatori." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Browserul tău are dezactivată funcția WebAssembly, așa că imaginile animate nu pot fi decupate." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Acest grup este plin. Elimină pe cineva Ăźnainte de a adăuga mai multe msgid "This handoff code has expired. Generate a new one to continue." msgstr "Acest cod de transfer a expirat. Generează unul nou pentru a continua." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Imaginea nu a putut fi citită. S-ar putea să fie coruptă." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Încarcă" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Încarcă un avatar personalizat pentru această comunitate" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Încarcă un banner personalizat pentru această comunitate" @@ -36155,10 +36163,10 @@ msgstr "Încarcă fișiere și media Ăźn mesaje." msgid "Upload files and media in this channel." msgstr "Încarcă fișiere și media Ăźn acest canal." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Încarcă pictogramă" @@ -36401,8 +36409,8 @@ msgstr "Folosește tema cărbune (suprafețe negru-smoală)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Folosește o imagine personalizată" @@ -36462,8 +36470,8 @@ msgstr "Folosește filtre sau introdu cuvinte-cheie pentru a găsi mesaje" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Folosește profilul global" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Participanți la apelul vocal" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Procesarea vocii" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Cu {PREMIUM_PRODUCT_NAME}, poți folosi avatare animate ({ANIMATED_AVATAR_FORMATS}), bannere de profil, ĂźÈ›i poți personaliza tagul și poți debloca multe alte avantaje {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Ai nevoie de permisiunea „{permissionLabel}” pentru a folosi emoji d msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Ai nevoie de permisiunea „{permissionLabel}” pentru a folosi stickere din alte comunități aici." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Trebuie să-ți revendici contul Ăźnainte de a putea crea o comunitate." @@ -39356,8 +39364,8 @@ msgstr "Trebuie să-ți revendici contul pentru a trimite mesaje Ăźn această co msgid "You need to verify a phone number to send messages in this community." msgstr "Trebuie să-ți verifici numărul de telefon pentru a trimite mesaje Ăźn această comunitate." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Trebuie să-ți verifici adresa de e-mail Ăźnainte de a putea crea o comunitate." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Calitatea salvată de {savedResolution} la {savedFrameRate} FPS necesită {premiumProductName}, așa că partajările folosesc {resolution} la {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Partajarea ecranului tău nu a putut fi publicată cu un codec video compatibil, așa că a fost oprită. Încearcă să partajezi din nou." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Adresa URL personalizată a fost setată la {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Codificatorul tău video a Ăźncetat să codifice cadre, așa că partajarea ecranului a fost oprită. Încearcă să partajezi din nou." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zoom" diff --git a/fluxer_app/src/features/i18n/locales/ru/messages.po b/fluxer_app/src/features/i18n/locales/ru/messages.po index 4fa3cbfa9..f3b717333 100644 --- a/fluxer_app/src/features/i18n/locales/ru/messages.po +++ b/fluxer_app/src/features/i18n/locales/ru/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, сĐșĐŸŃ€ĐŸ" msgid "{kilobits} kbps" msgstr "{kilobits} КбОт/с" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Đ Đ°Đ·ĐŒĐ”Ń€Ń‹ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐœĐ” ĐżĐŸĐŽŃ…ĐŸĐŽŃŃ‚ ĐŽĐ»Ń «{label}». ВыбДрОтД ĐŽŃ€ŃƒĐłĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” ОлО Đ·Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚Đ” ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”, ĐșĐŸŃ‚ĐŸŃ€ĐŸĐ” ĐŒĐŸĐ¶ĐœĐŸ ĐŸĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "ЀаĐčĐ» «{label}» слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐč. ВыбДрОтД фаĐčĐ» Ń€Đ°Đ·ĐŒĐ”Ń€ĐŸĐŒ ĐŒĐ”ĐœŃŒŃˆĐ” {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐŽĐ»Ń «{label}» ĐœĐ” ĐŒĐŸĐłŃƒŃ‚ Đ±Ń‹Ń‚ŃŒ Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹ĐŒĐž. Đ˜ŃĐżĐŸĐ»ŃŒĐ·ŃƒĐčтД ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "ĐŸĐŸĐșаз аĐșтоĐČĐœĐŸŃŃ‚Đž" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "ĐŸĐŸŃ€ĐŸĐł аĐșтоĐČĐœĐŸŃŃ‚Đž" @@ -3566,11 +3561,11 @@ msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚ŃŒ {everyoneMention} Đž {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż Đș ĐČашДĐč ĐșĐ°ĐŒĐ”Ń€Đ” ĐČ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż Đș ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœŃƒ ĐČ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż Đș ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœŃƒ. ĐŸŃ€ĐŸĐČĐ”Ń€ŃŒŃ‚Đ” Đ°ĐŽŃ€Đ”ŃĐœŃƒŃŽ ŃŃ‚Ń€ĐŸĐșу ОлО ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ°." @@ -3673,7 +3668,7 @@ msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚ŃŒ ŃƒŃ‡Đ°ŃŃ‚ĐœĐžĐșĐ°ĐŒ бДз Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžŃ «{r msgid "Allow mentions for this role" msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚ŃŒ ŃƒĐżĐŸĐŒĐžĐœĐ°ĐœĐžŃ ĐŽĐ»Ń ŃŃ‚ĐŸĐč Ń€ĐŸĐ»Đž" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Đ Đ°Đ·Ń€Đ”ŃˆĐžŃ‚ŃŒ ĐŽĐŸŃŃ‚ŃƒĐż Đș ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœŃƒ" @@ -3942,25 +3937,21 @@ msgstr "Đž ДщД {remainingCount}" msgid "Animate on interaction" msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČать про ĐČĐ·Đ°ĐžĐŒĐŸĐŽĐ”ĐčстĐČОО" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” фаĐčлы {AVIF_FORMAT_LABEL} ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČаются. Đ’ĐŒĐ”ŃŃ‚ĐŸ ŃŃ‚ĐŸĐłĐŸ Đ·Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚Đ” статОчДсĐșĐžĐč фаĐčĐ» {AVIF_FORMAT_LABEL}." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đč Ń„ĐŸŃ€ĐŒĐ°Ń‚ {avifFormatLabel} ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” аĐČатары ({ANIMATED_AVATAR_FORMATS}) ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ‹ Ń‚ĐŸĐ»ŃŒĐșĐŸ ĐżĐŸĐŽĐżĐžŃŃ‡ĐžĐșĐ°ĐŒ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” аĐČатары ({ANIMATED_AVATAR_FORMATS}) ĐœĐ”ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ‹ ĐČ ŃŃ‚ĐŸĐŒ эĐșĐ·Đ”ĐŒĐżĐ»ŃŃ€Đ”. Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚Đ” ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Đ”Đ»Ń Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… аĐČĐ°Ń‚Đ°Ń€ĐŸĐČ ({animatedAvatarFormats}) Ń‚Ń€Đ”Đ±ŃƒĐ”Ń‚ŃŃ {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” аĐČатары Đž Đ±Đ°ĐœĐœĐ”Ń€Ń‹ ĐżŃ€ĐŸŃ„ĐžĐ»Ń" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” аĐČатары ĐœĐ”ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ‹" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Đ”Đ»Ń Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… аĐČĐ°Ń‚Đ°Ń€ĐŸĐČ Ń‚Ń€Đ”Đ±ŃƒĐ”Ń‚ŃŃ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ĐŸŃ€Đ”ĐŽĐżŃ€ĐŸŃĐŒĐŸŃ‚Ń€ Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœĐŸĐłĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ĐĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČаются ĐŽĐ»Ń ŃŃ‚ĐŸĐłĐŸ Ń€Đ”ŃŃƒŃ€ŃĐ°." @@ -4947,7 +4938,7 @@ msgstr "АĐČŃ‚ĐŸĐŸĐżŃ€Đ”ĐŽĐ”Đ»Đ”ĐœĐžĐ” ŃĐ·Ń‹Đșа" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "АĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡Đ”ŃĐșĐž ŃƒŃŃ‚Đ°ĐœĐ°ĐČлОĐČать ĐżĐŸŃ€ĐŸĐł аĐșтоĐČĐœĐŸŃŃ‚Đž" @@ -5127,15 +5118,15 @@ msgstr "Đ”ĐŸŃŃ‚ŃƒĐżĐœĐŸ ĐČ ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐž ĐŽĐ»Ń ПК." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "АĐČатар" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčĐ» аĐČатара слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐč. ВыбДрОтД фаĐčĐ» Ń€Đ°Đ·ĐŒĐ”Ń€ĐŸĐŒ ĐŒĐ”ĐœŃŒŃˆĐ” {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "АĐČатар слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐč — ĐČыбДрОтД фаĐčĐ» Ń€Đ°Đ·ĐŒĐ”Ń€ĐŸĐŒ ĐŽĐŸ {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Đ’Ń‹Đ±ĐŸŃ€ Ń€Đ”Đ¶ĐžĐŒĐ° аĐČатара" @@ -5187,11 +5178,11 @@ msgstr "ĐĄĐ”Đčчас ĐœĐ”Ń‚ ĐœĐ° ĐŒĐ”ŃŃ‚Đ”" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Đ—Đ°Đ±Đ°ĐœĐ”ĐœĐœŃ‹Đ” ĐżĐŸĐ»ŃŒĐ·ĐŸĐČатДлО" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Đ‘Đ°ĐœĐœĐ”Ń€" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčĐ» Đ±Đ°ĐœĐœĐ”Ń€Đ° слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐč. ВыбДрОтД фаĐčĐ» Ń€Đ°Đ·ĐŒĐ”Ń€ĐŸĐŒ ĐŒĐ”ĐœŃŒŃˆĐ” {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Đ’Ń‹Đ±ĐŸŃ€ Ń€Đ”Đ¶ĐžĐŒĐ° Đ±Đ°ĐœĐœĐ”Ń€Đ°" @@ -6107,8 +6098,8 @@ msgstr "ĐšŃƒĐżĐžŃ‚Đ” ĐżĐŸĐŽĐ°Ń€ĐŸĐș {premiumProductName} ĐœĐ° ĐČĐșлаЎĐșĐ” {pr msgid "Buy gift" msgstr "Купоть ĐżĐŸĐŽĐ°Ń€ĐŸĐș" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ĐĄĐŸĐ·ĐŽĐ°ĐČая ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ, ĐČы ŃĐŸĐłĐ»Đ°ŃˆĐ°Đ”Ń‚Đ”ŃŃŒ ŃĐŸĐ±Đ»ŃŽĐŽĐ°Ń‚ŃŒ <0>праĐČОла ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČа {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "СюЮа ĐœĐ”Đ»ŃŒĐ·Ń Đ·Đ°ĐłŃ€ŃƒĐ¶Đ°Ń‚ŃŒ фаĐčлы" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ĐŸĐŸ Ń†Đ”ĐœŃ‚Ń€Ńƒ" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ аĐČатар" @@ -6627,9 +6618,9 @@ msgstr "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ Ń„ĐŸĐœ" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ Đ±Đ°ĐœĐœĐ”Ń€" @@ -6668,13 +6659,13 @@ msgstr "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ ĐœĐžĐșĐœĐ”ĐčĐŒ ĐČ ĐłŃ€ŃƒĐżĐżĐ”" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Đ˜Đ·ĐŒĐ”ĐœĐžŃ‚ŃŒ Đ·ĐœĐ°Ń‡ĐŸĐș" @@ -7669,8 +7660,8 @@ msgstr "Đ—Đ°Đ±Ń€Đ°Ń‚ŃŒ ĐżĐŸĐŽĐ°Ń€ĐŸĐș" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "ĐŸĐŸĐŽŃ‚ĐČДрЎОтД аĐșĐșĐ°ŃƒĐœŃ‚" @@ -8518,8 +8509,8 @@ msgstr "ĐĄĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ ŃĐżĐŸŃĐŸĐ±ŃŃ‚ĐČŃƒĐ”Ń‚ траĐČлД ОлО цДл msgid "Community filter" msgstr "Đ€ĐžĐ»ŃŒŃ‚Ń€ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Đ—ĐœĐ°Ń‡ĐŸĐș ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČа" @@ -8763,6 +8754,11 @@ msgstr "ĐšĐœĐŸĐżĐșĐž ĐżĐŸĐ»Ń ĐČĐČĐŸĐŽĐ°" msgid "Composer focus" msgstr "Đ€ĐŸĐșус ĐœĐ° ĐżĐŸĐ»Đ” ĐČĐČĐŸĐŽĐ°" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "ĐĄĐ¶ĐžĐŒĐ°Đ”ĐŒ" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ĐŸĐŸĐŽĐșлючОтД ĐșĐ°ĐŒĐ”Ń€Ńƒ ОлО ĐČĐžŃ€Ń‚ŃƒĐ°Đ»ŃŒĐœĐŸĐ” устр msgid "Connect a display, then try again." msgstr "ĐŸĐŸĐŽĐșлючОтД ЎОсплДĐč Đž ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД ŃĐœĐŸĐČа." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ĐŸĐŸĐŽĐșлючОтД ĐŒĐžĐșŃ€ĐŸŃ„ĐŸĐœ Đž ĐżĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД ŃĐœĐŸĐČа." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ŃĐŸĐ·ĐŽĐ°Ń‚ŃŒ стоĐșДр" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐŸĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐŸĐ±ĐœĐŸĐČоть ĐœĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč аĐșтоĐČĐœĐŸŃŃ‚Đž" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ Đ·Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ аĐČатар" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ Đ·Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ Đ±Đ°ĐœĐœĐ”Ń€" @@ -10230,7 +10226,7 @@ msgstr "ĐĄĐŸĐ·ĐŽĐ°Ń‚ŃŒ Đž ĐżĐŸĐŽĐ”Đ»ĐžŃ‚ŃŒŃŃ" msgid "Create a community" msgstr "ĐĄĐŸĐ·ĐŽĐ°Ń‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ĐĄĐŸĐ·ĐŽĐ°ĐčтД ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ ĐŽĐ»Ń ĐŸĐ±Ń‰Đ”ĐœĐžŃ с ĐŽŃ€ŃƒĐ·ŃŒŃĐŒĐž." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "ĐžĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ Ń„ĐŸĐœ ĐżŃ€ĐžĐłĐ»Đ°ŃˆĐ”ĐœĐžŃ" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ĐŸŃ€Đ”ĐŽĐżŃ€ĐŸŃĐŒĐŸŃ‚Ń€ ĐŸĐ±Ń€Đ”Đ·ĐșĐž" @@ -10500,30 +10496,15 @@ msgstr "ĐžĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ Đ±Đ°ĐœĐœĐ”Ń€ ĐżŃ€ĐŸŃ„ĐžĐ»Ń" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "ĐžĐ±Ń€Đ”Đ·Đ°ĐœĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” слОшĐșĐŸĐŒ Đ±ĐŸĐ»ŃŒŃˆĐŸĐ”. ВыбДрОтД ĐŒĐ”ĐœŃŒŃˆŃƒŃŽ ĐŸĐ±Đ»Đ°ŃŃ‚ŃŒ ОлО фаĐčĐ» ĐŒĐ”ĐœŃŒŃˆĐ”ĐłĐŸ Ń€Đ°Đ·ĐŒĐ”Ń€Đ° (ĐŒĐ°Đșс. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "ОбрДзĐșа Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… фаĐčĐ»ĐŸĐČ Ń„ĐŸŃ€ĐŒĐ°Ń‚Đ° {formatLabel} ĐżĐŸĐșа ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ. Đ‘ŃƒĐŽĐ”Ń‚ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°ĐœĐŸ ĐžŃŃ…ĐŸĐŽĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "ОбрДзĐșа Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… фаĐčĐ»ĐŸĐČ Ń„ĐŸŃ€ĐŒĐ°Ń‚Đ° {formatLabel} ĐżĐŸĐșа ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ. Đ‘ŃƒĐŽĐ”Ń‚ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Đœ ĐžŃŃ…ĐŸĐŽĐœŃ‹Đč фаĐčĐ»." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "ОбрДзĐșа Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… фаĐčĐ»ĐŸĐČ ĐżĐŸĐșа ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ. Đ‘ŃƒĐŽĐ”Ń‚ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°ĐœĐŸ ĐžŃŃ…ĐŸĐŽĐœĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "ОбрДзĐșа Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Ń… фаĐčĐ»ĐŸĐČ ĐżĐŸĐșа ĐœĐ” ĐżĐŸĐŽĐŽĐ”Ń€Đ¶ĐžĐČĐ°Đ”Ń‚ŃŃ. Đ‘ŃƒĐŽĐ”Ń‚ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Đœ ĐžŃŃ…ĐŸĐŽĐœŃ‹Đč фаĐčĐ»." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "ĐžĐ±Ń€Đ”Đ·Đ°Đ”ĐŒ {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ĐĐ”Ń‚ аĐșĐșĐ°ŃƒĐœŃ‚Đ°?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ĐĐ” ĐżĐŸĐșазыĐČать" @@ -16560,8 +16541,8 @@ msgstr "АĐČатары ĐłŃ€ŃƒĐżĐżĐŸĐČых Ń‡Đ°Ń‚ĐŸĐČ ĐžŃĐżĐŸĐ»ŃŒĐ·ŃƒŃŽŃ‚ тД msgid "Group DMs" msgstr "Đ“Ń€ŃƒĐżĐżĐŸĐČыД чаты" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Đ—ĐœĐ°Ń‡ĐŸĐș группы" @@ -16624,8 +16605,8 @@ msgstr "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž группы" msgid "Group typing states" msgstr "Статусы ĐœĐ°Đ±ĐŸŃ€Đ° ĐČ ĐłŃ€ŃƒĐżĐżĐ°Ń…" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Группа ĐŸĐ±ĐœĐŸĐČĐ»Đ”ĐœĐ°" @@ -16803,7 +16784,7 @@ msgstr "ХДрЎцД" msgid "Hebrew" msgstr "ИĐČрот" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Đ’Ń‹ŃĐŸŃ‚Đ°" @@ -17510,7 +17491,7 @@ msgstr "Đ˜Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ” сĐșĐŸĐżĐžŃ€ĐŸĐČĐ°ĐœĐŸ ĐČ Đ±ŃƒŃ„Đ”Ń€ ĐŸĐ±ĐŒĐ”ĐœĐ° #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Đ’ĐœĐ”ŃˆĐœĐžĐč ĐČОЎ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ĐŸĐŸŃ…ĐŸĐ¶Đ”, ĐČы ĐžŃĐżĐŸĐ»ŃŒĐ·ŃƒĐ”Ń‚Đ” {0}. Đ”ĐŸĐżĐŸĐ»ĐœĐžŃ‚Đ”Đ»ŃŒĐœĐ°Ń ĐŸĐ±Ń€Đ°Đ±ĐŸŃ‚Đșа Đ·ĐČуĐșа ĐČ {PRODUCT_NAME} ĐŒĐŸĐ¶Đ”Ń‚ проĐČДстО Đș ОсĐșĐ°Đ¶Đ”ĐœĐžŃĐŒ. ĐŸŃ€ŃĐŒĐŸĐč ĐČĐČĐŸĐŽ пДрДЎаДт ĐČаш Đ·ĐČуĐș бДз ĐžĐ·ĐŒĐ”ĐœĐ”ĐœĐžĐč." @@ -22577,7 +22558,7 @@ msgstr "ĐĄĐŸĐČĐżĐ°ĐŽĐ”ĐœĐžĐč ĐœĐ” ĐœĐ°ĐčĐŽĐ”ĐœĐŸ" msgid "No mentions yet" msgstr "ĐŸĐŸĐșа ĐœĐ”Ń‚ ŃƒĐżĐŸĐŒĐžĐœĐ°ĐœĐžĐč" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "МоĐșŃ€ĐŸŃ„ĐŸĐœ ĐœĐ” ĐœĐ°ĐčĐŽĐ”Đœ" @@ -23806,7 +23787,7 @@ msgstr "ОтĐșрыть ŃĐžŃŃ‚Đ”ĐŒĐœŃ‹Đč чат" msgid "Open system picker" msgstr "ОтĐșрыть ŃĐžŃŃ‚Đ”ĐŒĐœŃ‹Đč ĐČŃ‹Đ±ĐŸŃ€ ĐžŃŃ‚ĐŸŃ‡ĐœĐžĐșа" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "ОтĐșрыть JSON ŃˆĐ°Đ±Đ»ĐŸĐœĐ°" @@ -23820,7 +23801,7 @@ msgstr "ОтĐșрыть ĐŸĐșĐœĐŸ Đ±Đ°ĐœĐ° ĐŽĐ»Ń ŃŃ‚ĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČа. msgid "Open the context menu" msgstr "ОтĐșрыть ĐșĐŸĐœŃ‚Đ”ĐșŃŃ‚ĐœĐŸĐ” ĐŒĐ”ĐœŃŽ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "ОтĐșŃ€ĐŸĐčтД ссылĐșу ĐœĐžĐ¶Đ” ĐČ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ”, Đ·Đ°Ń‚Đ”ĐŒ сĐșĐŸĐżĐžŃ€ŃƒĐčтД ĐČĐ”ŃŃŒ JSON-ĐŸŃ‚ĐČДт Đž ĐČстаĐČŃŒŃ‚Đ” Đ”ĐłĐŸ ĐČ ĐżĐŸĐ»Đ”." @@ -24331,7 +24312,7 @@ msgstr "ĐŸĐŸŃĐ»Đ”ĐŽĐœĐžĐ” 7 ĐŽĐœĐ”Đč" msgid "Paste" msgstr "ВстаĐČоть" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "ВстаĐČŃŒŃ‚Đ” URL ŃˆĐ°Đ±Đ»ĐŸĐœĐ° {theOtherPlatform}, Ń‡Ń‚ĐŸĐ±Ń‹ ĐžĐŒĐżĐŸŃ€Ń‚ĐžŃ€ĐŸĐČать Đ”ĐłĐŸ струĐșтуру ĐČ ĐœĐŸĐČĐŸĐ” ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ." @@ -25191,6 +25172,11 @@ msgstr "йОп ĐżĐŸĐŽĐżĐžŃĐșĐž" msgid "Premium until date" msgstr "Дата ĐŸĐșĐŸĐœŃ‡Đ°ĐœĐžŃ ĐżŃ€Đ”ĐŒĐžŃƒĐŒĐ°" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ĐŸĐŸĐŽĐłĐŸŃ‚ĐŸĐČĐșа" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "ĐŸŃ€ĐŸŃ„ĐžĐ»ŃŒ" msgid "Profile badge" msgstr "Đ—ĐœĐ°Ń‡ĐŸĐș ĐżŃ€ĐŸŃ„ĐžĐ»Ń" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Đ‘Đ°ĐœĐœĐ”Ń€Ń‹ ĐżŃ€ĐŸŃ„ĐžĐ»Ń — ŃŃ‚ĐŸ Ń„ŃƒĐœĐșцоя {PREMIUM_PRODUCT_NAME}. ĐžŃ„ĐŸŃ€ĐŒĐžŃ‚Đ” ĐżĐŸĐŽĐżĐžŃĐșу {PREMIUM_PRODUCT_NAME}, Ń‡Ń‚ĐŸĐ±Ń‹ ĐŽĐŸĐ±Đ°ĐČоть Đ±Đ°ĐœĐœĐ”Ń€ ĐČ ŃĐČĐŸĐč ĐżŃ€ĐŸŃ„ĐžĐ»ŃŒ." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Đ‘Đ°ĐœĐœĐ”Ń€Ń‹ ĐżŃ€ĐŸŃ„ĐžĐ»Ń ĐœĐ” ĐČĐșĐ»ŃŽŃ‡Đ”ĐœŃ‹ ĐČ ŃŃ‚ĐŸĐŒ эĐșĐ·Đ”ĐŒĐżĐ»ŃŃ€Đ”." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Đ”Đ»Ń Đ±Đ°ĐœĐœĐ”Ń€ĐŸĐČ ĐżŃ€ĐŸŃ„ĐžĐ»Ń Ń‚Ń€Đ”Đ±ŃƒĐ”Ń‚ŃŃ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Đ”Đ»Ń Đ±Đ°ĐœĐœĐ”Ń€ĐŸĐČ ĐżŃ€ĐŸŃ„ĐžĐ»Ń Ń‚Ń€Đ”Đ±ŃƒĐ”Ń‚ŃŃ {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "ĐĐ°Đ¶ĐŒĐž Đž ĐłĐŸĐČĐŸŃ€Đž" msgid "Push-to-talk (limited)" msgstr "ĐĐ°Đ¶ĐŒĐž Đž ĐłĐŸĐČĐŸŃ€Đž (с ĐŸĐłŃ€Đ°ĐœĐžŃ‡Đ”ĐœĐžŃĐŒĐž)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Đ Đ”Đ¶ĐžĐŒ Â«ĐĐ°Đ¶ĐŒĐž Đž ĐłĐŸĐČĐŸŃ€ĐžÂ» ĐžĐłĐœĐŸŃ€ĐžŃ€ŃƒĐ”Ń‚ŃŃ про ĐżŃ€ŃĐŒĐŸĐŒ ĐČĐČĐŸĐŽĐ”. ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚Đ”ŃŃŒ ĐœĐ° Â«Đ€ĐŸĐșŃƒŃĐžŃ€ĐŸĐČĐșу ĐłĐŸĐ»ĐŸŃĐ°Â» ОлО Â«ĐŸĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»ŃŒŃĐșĐžĐč», Ń‡Ń‚ĐŸĐ±Ń‹ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать Đ”ĐłĐŸ." @@ -26551,8 +26537,8 @@ msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐČĐ»ĐŸĐ¶Đ”ĐœĐžĐ”" msgid "Remove authenticator app" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžĐ” ĐŽĐ»Ń Đ°ŃƒŃ‚Đ”ĐœŃ‚ĐžŃ„ĐžĐșацоо" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ аĐČатар" @@ -26561,8 +26547,8 @@ msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ аĐČатар" msgid "Remove background" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ Ń„ĐŸĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ Đ±Đ°ĐœĐœĐ”Ń€" @@ -26625,10 +26611,10 @@ msgstr "ĐŁĐ±Ń€Đ°Ń‚ŃŒ заĐșŃ€Đ”ĐżĐ»Đ”ĐœĐžĐ” сĐČĐ”Ń€Ń…Ńƒ" msgid "Remove from URL-only GIF favorites" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ Оз ĐžĐ·Đ±Ń€Đ°ĐœĐœŃ‹Ń… GIF (Ń‚ĐŸĐ»ŃŒĐșĐŸ ĐżĐŸ URL)" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ĐŁĐŽĐ°Đ»ĐžŃ‚ŃŒ Đ·ĐœĐ°Ń‡ĐŸĐș" @@ -27331,7 +27317,7 @@ msgstr "ОтпраĐČĐ»Đ”ĐœĐŸ ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ĐĄĐ±Ń€ĐŸŃĐžŃ‚ŃŒ" @@ -28074,7 +28060,7 @@ msgstr "Đ ŃƒĐŒŃ‹ĐœŃĐșĐžĐč" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ĐŸĐŸĐČĐ”Ń€ĐœŃƒŃ‚ŃŒ ĐżĐŸ Ń‡Đ°ŃĐŸĐČĐŸĐč стрДлĐșĐ”" @@ -28153,8 +28139,8 @@ msgstr "ĐĐ°ŃŃ‹Ń‰Đ”ĐœĐœĐŸŃŃ‚ŃŒ" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ĐĐ°ŃŃ‚Ń€ĐŸĐčĐșĐž ĐșĐŸĐŽĐžŃ€ĐŸĐČщоĐșа ĐŽĐ»Ń ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžĐž эĐșŃ€Đ°ĐœĐ°" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Đ”Đ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃ эĐșŃ€Đ°ĐœĐ° заĐČĐ”Ń€ŃˆĐ”ĐœĐ°" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "ĐŸĐŸĐșазыĐČать ĐșŃ€Đ°ŃĐœŃ‹Đč Đ·ĐœĐ°Ń‡ĐŸĐș ĐœĐ° ĐžĐșĐŸĐœĐșĐ” ĐżŃ€ĐžĐ»ĐŸĐ¶Đ”ĐœĐžŃ про ĐœĐ°Đ»ĐžŃ‡ĐžĐž ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐœŃ‹Ń… ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "ĐŸĐŸĐșазыĐČать Ń‚ĐŸĐ»ŃŒĐșĐŸ аĐșŃ†Đ”ĐœŃ‚ĐœŃ‹Đč цĐČДт, ĐžĐłĐœĐŸŃ€ĐžŃ€ŃƒŃ ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœŃ‹Đč ĐżŃ€ĐŸŃ„ĐžĐ»ŃŒ" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "ĐŸĐŸĐșазыĐČать ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»ŃŒŃĐșОД ŃĐŒĐŸĐŽĐ·Đž ĐČ Đ°ĐČŃ‚ĐŸĐ·Đ°ĐČĐ”Ń€ŃˆĐ”ĐœĐžĐž ĐČŃ‹Ń€Đ°Đ¶Đ”ĐœĐžĐč" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "ĐŸĐŸĐșазыĐČать аĐČатар ĐżĐŸ ŃƒĐŒĐŸĐ»Ń‡Đ°ĐœĐžŃŽ, ĐžĐłĐœĐŸŃ€ĐžŃ€ŃƒŃ ĐČаш ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœŃ‹Đč ĐżŃ€ĐŸŃ„ĐžĐ»ŃŒ" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "ĐŸĐŸĐșазыĐČать ĐžĐœĐŽĐžĐșĐ°Ń‚ĐŸŃ€ ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐœŃ‹Ń… ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžĐč ĐČ ĐșĐ°ĐœĐ°Đ»Đ°Ń… бДз уĐČĐ”ĐŽĐŸĐŒĐ»Đ”ĐœĐžĐč" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ĐŸĐŸĐșазыĐČать аĐČатар ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐŸĐłĐŸ ĐżŃ€ĐŸŃ„ĐžĐ»Ń ĐČ ŃŃ‚ĐŸĐŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐ”" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ĐŸĐŸĐșазыĐČать Đ±Đ°ĐœĐœĐ”Ń€ ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐŸĐłĐŸ ĐżŃ€ĐŸŃ„ĐžĐ»Ń ĐČ ŃŃ‚ĐŸĐŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐ”" @@ -30720,7 +30706,7 @@ msgstr "ĐŸŃ€ĐŸĐżŃƒŃŃ‚ĐžŃ‚ŃŒ" msgid "Skip \"Mark all as read\" confirmation" msgstr "ĐŸŃ€ĐŸĐżŃƒŃĐșать ĐżĐŸĐŽŃ‚ĐČĐ”Ń€Đ¶ĐŽĐ”ĐœĐžĐ” Â«ĐžŃ‚ĐŒĐ”Ń‚ĐžŃ‚ŃŒ ĐČсД ĐșаĐș ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐœŃ‹Đ”Â»" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "ĐŸŃ€ĐŸĐżŃƒŃŃ‚ĐžŃ‚ŃŒ ĐŸĐ±Ń€Đ”Đ·Đșу" @@ -32346,7 +32332,7 @@ msgstr "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒŃŃ ĐœĐ° ĐżŃ€ĐŸŃŃ‚ĐŸŃ€ĐœŃ‹Đč ĐČОЎ" msgid "Switch to dense layout" msgstr "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒŃŃ ĐœĐ° ĐșĐŸĐŒĐżĐ°ĐșŃ‚ĐœŃ‹Đč ĐČОЎ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ĐŸĐ”Ń€Đ”ĐșĐ»ŃŽŃ‡ĐžŃ‚ŃŒŃŃ ĐœĐ° ĐżŃ€ŃĐŒĐŸĐč ĐČĐČĐŸĐŽ" @@ -32734,7 +32720,7 @@ msgstr "ЗаЮачо" msgid "Teleporting you to another voice region..." msgstr "ĐŸĐ”Ń€Đ”ĐŒĐ”Ń‰Đ°Đ”ĐŒ ĐČас ĐČ ĐŽŃ€ŃƒĐłĐŸĐč ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐč Ń€Đ”ĐłĐžĐŸĐœ..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ĐšĐ°Đ±Đ»ĐŸĐœ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Đ ĐŸĐ»ŃŒ ĐżŃ€Đ”ĐŽĐŸŃŃ‚Đ°ĐČĐ»ŃĐ»Đ° {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Đ˜ŃŃ‚ĐŸŃ‡ĐœĐžĐș ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžĐž эĐșŃ€Đ°ĐœĐ° прДĐșратОл ĐżĐ”Ń€Đ”ĐŽĐ°Ń‡Ńƒ ĐČĐžĐŽĐ”ĐŸ, ĐżĐŸŃŃ‚ĐŸĐŒŃƒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃ была ĐŸŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐ°." @@ -33453,6 +33439,11 @@ msgstr "Đ­Ń‚ĐŸŃ‚ аĐșĐșĐ°ŃƒĐœŃ‚ ĐœĐ”Đ»ŃŒĐ·Ń Đ·Đ°Đ±Đ»ĐŸĐșĐžŃ€ĐŸĐČать." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Đ­Ń‚ĐŸ ĐŽĐ”ĐčстĐČОД ĐœĐ”ĐŸĐ±Ń€Đ°Ń‚ĐžĐŒĐŸ. ВсД сĐČŃĐ·Đ°ĐœĐœŃ‹Đ” ĐŽĐ°ĐœĐœŃ‹Đ”, ĐČĐșĐ»ŃŽŃ‡Đ°Ń ĐżĐŸĐ»ŃŒĐ·ĐŸĐČĐ°Ń‚Đ”Đ»Ń-Đ±ĐŸŃ‚Đ°, Đ±ŃƒĐŽŃƒŃ‚ ŃƒĐŽĐ°Đ»Đ”ĐœŃ‹ бДз ĐČĐŸĐ·ĐŒĐŸĐ¶ĐœĐŸŃŃ‚Đž ĐČĐŸŃŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐžŃ." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Đ­Ń‚ĐŸŃ‚ Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đč фаĐčĐ» слОшĐșĐŸĐŒ ĐŽĐ»ĐžĐœĐœŃ‹Đč ОлО Đ±ĐŸĐ»ŃŒŃˆĐŸĐč ĐŽĐ»Ń ĐŸĐ±Ń€Đ”Đ·ĐșĐž. ĐŸĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД Đ±ĐŸĐ»Đ”Đ” ĐșĐŸŃ€ĐŸŃ‚ĐșĐžĐč ОлО ĐŒĐ”ĐœŃŒŃˆĐžĐč фаĐčĐ»." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Đ­Ń‚ĐŸŃ‚ Đ±ĐŸŃ‚ ĐœĐ” яĐČĐ»ŃĐ”Ń‚ŃŃ ĐżŃƒĐ±Đ»ĐžŃ‡ĐœŃ‹ĐŒ, Đž Юруго msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Đ­Ń‚ĐŸŃ‚ Đ±ĐŸŃ‚ Đ·Đ°ĐżŃ€Đ°ŃˆĐžĐČаДт праĐČа Đ°ĐŽĐŒĐžĐœĐžŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°. ĐŸŃ€Đ”ĐŽĐŸŃŃ‚Đ°ĐČĐ»ŃĐčтД ох, Ń‚ĐŸĐ»ŃŒĐșĐŸ ДслО ĐżĐŸĐ»ĐœĐŸŃŃ‚ŃŒŃŽ ĐŽĐŸĐČĐ”Ń€ŃĐ”Ń‚Đ” Ń€Đ°Đ·Ń€Đ°Đ±ĐŸŃ‚Ń‡ĐžĐșу. ĐŸĐŸĐżŃ€ĐŸŃĐžŃ‚Đ” Đ”ĐłĐŸ Đ·Đ°ĐżŃ€Đ°ŃˆĐžĐČать ĐŒĐ”ĐœŃŒŃˆĐ” Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐč. ЗаĐșŃ€ĐŸĐčтД эту ŃŃ‚Ń€Đ°ĐœĐžŃ†Ńƒ, ДслО ĐœĐ” уĐČĐ”Ń€Đ”ĐœŃ‹." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Đ­Ń‚ĐŸŃ‚ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€ ĐœĐ” ĐŒĐŸĐ¶Đ”Ń‚ ĐŸĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” фаĐčлы {avifFormatLabel}. Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚Đ” ĐČĐŒĐ”ŃŃ‚ĐŸ ŃŃ‚ĐŸĐłĐŸ GIF ОлО WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "ĐšĐŸĐœŃĐŸĐ»ŃŒ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ° — ŃŃ‚ĐŸ ĐžĐœŃŃ‚Ń€ŃƒĐŒĐ”ĐœŃ‚ Ń€Đ°Đ·Ń€Đ°Đ±ĐŸŃ‚Ń‡ĐžĐșа." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "В ŃŃ‚ĐŸĐŒ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ” ĐŸŃ‚ĐșĐ»ŃŽŃ‡Đ”Đœ WebAssembly, ĐżĐŸŃŃ‚ĐŸĐŒŃƒ Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžŃ ĐœĐ”Đ»ŃŒĐ·Ń ĐŸĐ±Ń€Đ”Đ·Đ°Ń‚ŃŒ." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Эта группа Đ·Đ°ĐżĐŸĐ»ĐœĐ”ĐœĐ°. УЎалОтД ĐșĐŸĐłĐŸ-ĐœĐžĐ±Ńƒ msgid "This handoff code has expired. Generate a new one to continue." msgstr "ĐĄŃ€ĐŸĐș ĐŽĐ”ĐčстĐČоя ŃŃ‚ĐŸĐłĐŸ ĐșĐŸĐŽĐ° остёĐș. ĐĄĐŸĐ·ĐŽĐ°ĐčтД ĐœĐŸĐČыĐč, Ń‡Ń‚ĐŸĐ±Ń‹ ĐżŃ€ĐŸĐŽĐŸĐ»Đ¶ĐžŃ‚ŃŒ." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°Ń‚ŃŒ ŃŃ‚ĐŸ ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”. ĐžĐœĐŸ ĐŒĐŸĐ¶Đ”Ń‚ Đ±Ń‹Ń‚ŃŒ ĐżĐŸĐČŃ€Đ”Đ¶ĐŽĐ”ĐœĐŸ." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ сĐČĐŸĐč аĐČатар ĐŽĐ»Ń ŃŃ‚ĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČа" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ сĐČĐŸĐč Đ±Đ°ĐœĐœĐ”Ń€ ĐŽĐ»Ń ŃŃ‚ĐŸĐłĐŸ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČа" @@ -36155,10 +36163,10 @@ msgstr "Đ—Đ°ĐłŃ€ŃƒĐ¶Đ°Ń‚ŃŒ фаĐčлы Đž ĐŒĐ”ĐŽĐžĐ° ĐČ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ." msgid "Upload files and media in this channel." msgstr "Đ—Đ°ĐłŃ€ŃƒĐ¶Đ°Ń‚ŃŒ фаĐčлы Đž ĐŒĐ”ĐŽĐžĐ° ĐČ ŃŃ‚ĐŸĐŒ ĐșĐ°ĐœĐ°Đ»Đ”." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Đ—Đ°ĐłŃ€ŃƒĐ·ĐžŃ‚ŃŒ Đ·ĐœĐ°Ń‡ĐŸĐș" @@ -36401,8 +36409,8 @@ msgstr "Đ˜ŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать ŃƒĐłĐŸĐ»ŃŒĐœŃƒŃŽ Ń‚Đ”ĐŒŃƒ (Đ°Đ±ŃĐŸĐ»ŃŽŃ‚ĐœĐŸ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Đ˜ŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать сĐČĐŸĐ” ĐžĐ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐžĐ”" @@ -36462,8 +36470,8 @@ msgstr "Đ˜ŃĐżĐŸĐ»ŃŒĐ·ŃƒĐčтД Ń„ĐžĐ»ŃŒŃ‚Ń€Ń‹ ОлО ĐČĐČДЎОтД ĐșлючДĐČ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Đ˜ŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœŃ‹Đč ĐżŃ€ĐŸŃ„ĐžĐ»ŃŒ" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ĐŁŃ‡Đ°ŃŃ‚ĐœĐžĐșĐž ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐłĐŸ чата" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ĐžĐ±Ń€Đ°Đ±ĐŸŃ‚Đșа ĐłĐŸĐ»ĐŸŃĐ°" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ВосĐșĐŸĐœŃĐžĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Đ‘Đ»Đ°ĐłĐŸĐŽĐ°Ń€Ń {PREMIUM_PRODUCT_NAME} ĐČы ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать Đ°ĐœĐžĐŒĐžŃ€ĐŸĐČĐ°ĐœĐœŃ‹Đ” аĐČатары ({ANIMATED_AVATAR_FORMATS}), Đ±Đ°ĐœĐœĐ”Ń€Ń‹ ĐżŃ€ĐŸŃ„ĐžĐ»Ń, ĐœĐ°ŃŃ‚Ń€Đ°ĐžĐČать сĐČĐŸĐč тДг Đž ĐżĐŸĐ»ŃƒŃ‡Đ°Ń‚ŃŒ ĐŒĐœĐŸĐ¶Đ”ŃŃ‚ĐČĐŸ Юругох ĐżŃ€Đ”ĐžĐŒŃƒŃ‰Đ”ŃŃ‚ĐČ {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать Đ·ĐŽĐ”ŃŃŒ ŃĐŒĐŸĐŽĐ·Đž Оз Юру msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ĐžŃĐżĐŸĐ»ŃŒĐ·ĐŸĐČать Đ·ĐŽĐ”ŃŃŒ стоĐșДры Оз Юругох ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČ, ĐČĐ°ĐŒ ĐœŃƒĐ¶ĐœĐŸ Ń€Đ°Đ·Ń€Đ”ŃˆĐ”ĐœĐžĐ” «{permissionLabel}»." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ŃĐŸĐ·ĐŽĐ°Ń‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ, ĐœŃƒĐ¶ĐœĐŸ ŃĐœĐ°Ń‡Đ°Đ»Đ° ĐżĐŸĐŽŃ‚ĐČĐ”Ń€ĐŽĐžŃ‚ŃŒ аĐșĐșĐ°ŃƒĐœŃ‚." @@ -39356,8 +39364,8 @@ msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ĐŸŃ‚ĐżŃ€Đ°ĐČĐ»ŃŃ‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ ĐČ ŃŃ‚ĐŸĐŒ ŃĐŸĐŸĐ± msgid "You need to verify a phone number to send messages in this community." msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ĐŸŃ‚ĐżŃ€Đ°ĐČĐ»ŃŃ‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ĐœĐžŃ ĐČ ŃŃ‚ĐŸĐŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐ”, ĐżĐŸĐŽŃ‚ĐČДрЎОтД ĐœĐŸĐŒĐ”Ń€ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœĐ°." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Đ§Ń‚ĐŸĐ±Ń‹ ŃĐŸĐ·ĐŽĐ°Ń‚ŃŒ ŃĐŸĐŸĐ±Ń‰Đ”ŃŃ‚ĐČĐŸ, ĐżĐŸĐŽŃ‚ĐČДрЎОтД аЎрДс ŃĐ»Đ”ĐșŃ‚Ń€ĐŸĐœĐœĐŸĐč ĐżĐŸŃ‡Ń‚Ń‹." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Đ’Đ°ŃˆĐ” ŃĐŸŃ…Ń€Đ°ĐœĐ”ĐœĐœĐŸĐ” ĐșачДстĐČĐŸ {savedResolution} про {savedFrameRate} FPS Ń‚Ń€Đ”Đ±ŃƒĐ”Ń‚ {premiumProductName}, ĐżĐŸŃŃ‚ĐŸĐŒŃƒ ĐžŃĐżĐŸĐ»ŃŒĐ·ŃƒĐ”Ń‚ŃŃ ĐșачДстĐČĐŸ {resolution} про {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ĐĐ” ŃƒĐŽĐ°Đ»ĐŸŃŃŒ ĐŸĐżŃƒĐ±Đ»ĐžĐșĐŸĐČать ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃŽ эĐșŃ€Đ°ĐœĐ° с ŃĐŸĐČĐŒĐ”ŃŃ‚ĐžĐŒŃ‹ĐŒ ĐČĐžĐŽĐ”ĐŸĐșĐŸĐŽĐ”ĐșĐŸĐŒ, ĐżĐŸŃŃ‚ĐŸĐŒŃƒ ĐŸĐœĐ° была ĐŸŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐ°. ĐŸĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД ĐœĐ°Ń‡Đ°Ń‚ŃŒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃŽ ŃĐœĐŸĐČа." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "ĐšĐŸŃ€ĐŸŃ‚Đșая ссылĐșа ŃƒŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐ°: {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Ваш ĐČĐžĐŽĐ”ĐŸĐșĐŸĐŽĐ”Ń€ пДрДстал ĐșĐŸĐŽĐžŃ€ĐŸĐČать ĐșаЮры, ĐżĐŸŃŃ‚ĐŸĐŒŃƒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃ эĐșŃ€Đ°ĐœĐ° была ĐŸŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐ°. ĐŸĐŸĐżŃ€ĐŸĐ±ŃƒĐčтД ĐœĐ°Ń‡Đ°Ń‚ŃŒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†ĐžŃŽ ŃĐœĐŸĐČа." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "ĐœĐ°ŃŃˆŃ‚Đ°Đ±" diff --git a/fluxer_app/src/features/i18n/locales/sv-SE/messages.po b/fluxer_app/src/features/i18n/locales/sv-SE/messages.po index ecd9a2a29..dc6838b40 100644 --- a/fluxer_app/src/features/i18n/locales/sv-SE/messages.po +++ b/fluxer_app/src/features/i18n/locales/sv-SE/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, kommer snart" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "MĂ„tten för {label} matchar inte den hĂ€r resursen. VĂ€lj en annan bild eller ladda upp en statisk bild som du kan beskĂ€ra." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Filen för {label} Ă€r för stor. VĂ€lj en fil som Ă€r mindre Ă€n {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label}-bilder kan inte vara animerade. AnvĂ€nd en statisk bild." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Delning av aktivitet" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Aktivitetströskel" @@ -3566,11 +3561,11 @@ msgstr "TillĂ„t {everyoneMention} och {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "TillĂ„t {PRODUCT_NAME} att komma Ă„t din kamera i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "TillĂ„t att {PRODUCT_NAME} fĂ„r Ă„tkomst till din mikrofon i {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "TillĂ„t {PRODUCT_NAME} att komma Ă„t din mikrofon. Kontrollera webblĂ€sarens adressfĂ€lt eller instĂ€llningar." @@ -3673,7 +3668,7 @@ msgstr "TillĂ„t medlemmar utan behörigheten {readMessageHistoryPermissionLabel} msgid "Allow mentions for this role" msgstr "TillĂ„t omnĂ€mnanden för den hĂ€r rollen" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "TillĂ„t mikrofon" @@ -3942,25 +3937,21 @@ msgstr "och {remainingCount} till" msgid "Animate on interaction" msgstr "Animera vid interaktion" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Animerade {AVIF_FORMAT_LABEL}-filer stöds inte. Ladda upp en statisk {AVIF_FORMAT_LABEL}-fil istĂ€llet." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Animerad {avifFormatLabel} stöds inte" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Animerade avatarer ({ANIMATED_AVATAR_FORMATS}) Ă€r bara tillgĂ€ngliga för abonnenter pĂ„ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Animerade avatarer ({ANIMATED_AVATAR_FORMATS}) Ă€r inte tillgĂ€ngliga pĂ„ den hĂ€r instansen. Ladda upp en statisk bild istĂ€llet." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Animerade avatarer ({animatedAvatarFormats}) krĂ€ver {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Animerade avatarer och profilbanners" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Animerade avatarer Ă€r inte tillgĂ€ngliga" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Animerade avatarer krĂ€ver {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Förhandsvisning av animerad bild" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Animerade bilder stöds inte för den hĂ€r resursen." @@ -4947,7 +4938,7 @@ msgstr "Identifiera sprĂ„k automatiskt" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "StĂ€ll in aktivitetströskel automatiskt" @@ -5127,15 +5118,15 @@ msgstr "TillgĂ€nglig i datorappen." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatarfilen Ă€r för stor. VĂ€lj en fil som Ă€r mindre Ă€n {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avataren Ă€r för stor – vĂ€lj en under {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "VĂ€lj avatarlĂ€ge" @@ -5187,11 +5178,11 @@ msgstr "Borta just nu" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Bannlysta anvĂ€ndare" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Bannerfilen Ă€r för stor. VĂ€lj en fil som Ă€r mindre Ă€n {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Val av bannerlĂ€ge" @@ -6107,8 +6098,8 @@ msgstr "Köp en {premiumProductName}-present pĂ„ fliken {premiumProductName} fö msgid "Buy gift" msgstr "Köp present" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Genom att skapa en community godkĂ€nner du att följa och upprĂ€tthĂ„lla <0>{PRODUCT_NAME}s communityriktlinjer." @@ -6361,7 +6352,7 @@ msgstr "Kan inte ladda upp filer hĂ€r" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Centrerad" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Ändra avatar" @@ -6627,9 +6618,9 @@ msgstr "Ändra bakgrund" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Ändra banner" @@ -6668,13 +6659,13 @@ msgstr "Ändra gruppsmeknamn" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Ändra ikon" @@ -7669,8 +7660,8 @@ msgstr "Lös in present" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "SĂ€kra ditt konto" @@ -8518,8 +8509,8 @@ msgstr "Communityn underlĂ€ttar pĂ„hopp eller riktade trakasserier." msgid "Community filter" msgstr "Communityfilter" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Communityikon" @@ -8763,6 +8754,11 @@ msgstr "Knappar i skrivfĂ€ltet" msgid "Composer focus" msgstr "Fokus pĂ„ skrivfĂ€ltet" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Komprimerar" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Anslut en kamera eller virtuell inspelningsenhet och försök igen." msgid "Connect a display, then try again." msgstr "Anslut en skĂ€rm och försök igen." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Anslut en mikrofon och försök igen." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Kunde inte skapa det hĂ€r klistermĂ€rket" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Kunde inte beskĂ€ra bilden" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Kunde inte uppdatera delning av röstaktivitet just nu" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Kunde inte ladda upp avatar" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Kunde inte ladda upp bannern" @@ -10230,7 +10226,7 @@ msgstr "Skapa och dela" msgid "Create a community" msgstr "Skapa en community" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Skapa en community dĂ€r du och dina vĂ€nner kan chatta." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "BeskĂ€r inbjudningsbakgrund" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "BeskĂ€r förhandsvisning" @@ -10500,30 +10496,15 @@ msgstr "BeskĂ€r profilbanner" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Den beskurna bilden Ă€r för stor. VĂ€lj ett mindre omrĂ„de eller en mindre fil (max {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Det gĂ„r inte att beskĂ€ra animerade {formatLabel}-filer Ă€n. Originalbilden kommer att anvĂ€ndas." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Det gĂ„r inte att beskĂ€ra animerade {formatLabel}-filer Ă€n. Den ursprungliga filen kommer att anvĂ€ndas." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "BeskĂ€rning av animerade filer stöds inte Ă€n. Originalbilden kommer att anvĂ€ndas." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Det gĂ„r inte att beskĂ€ra animerade filer Ă€n. Den ursprungliga filen kommer att anvĂ€ndas." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "BeskĂ€rning {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Har du inget konto?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Visa inte" @@ -16560,8 +16541,8 @@ msgstr "Grupp-DM-avatarer anvĂ€nder samma statusmasker som vanliga avatarer, ink msgid "Group DMs" msgstr "Grupp-DM" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Gruppikon" @@ -16624,8 +16605,8 @@ msgstr "GruppinstĂ€llningar" msgid "Group typing states" msgstr "Gruppens skrivindikationer" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Gruppen uppdaterad" @@ -16803,7 +16784,7 @@ msgstr "HjĂ€rta" msgid "Hebrew" msgstr "Hebreiska" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Höjd" @@ -17510,7 +17491,7 @@ msgstr "Bild kopierad till urklipp" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Bilden kunde inte anvĂ€ndas" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Utseende och kĂ€nsla" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "Det verkar som att du anvĂ€nder {0}. Om du lĂ€gger till ljudbehandlingen i {PRODUCT_NAME} ovanpĂ„ den kan det orsaka pumpning eller distorsion. Direktinmatning skickar ditt ljud oförĂ€ndrat." @@ -22577,7 +22558,7 @@ msgstr "Inga trĂ€ffar" msgid "No mentions yet" msgstr "Inga omnĂ€mnanden Ă€n" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Ingen mikrofon hittades" @@ -23806,7 +23787,7 @@ msgstr "Öppna system-DM" msgid "Open system picker" msgstr "Öppna systemvĂ€ljaren" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Öppna mall-JSON" @@ -23820,7 +23801,7 @@ msgstr "Öppna bannlysningsdialogen för den hĂ€r communityn." msgid "Open the context menu" msgstr "Öppna snabbmenyn" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Öppna lĂ€nken nedan i din webblĂ€sare, kopiera sedan hela JSON-svaret och klistra in det i rutan." @@ -24331,7 +24312,7 @@ msgstr "Senaste 7 dagarna" msgid "Paste" msgstr "Klistra in" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Klistra in en {theOtherPlatform}-mall-URL för att importera dess struktur till en ny community." @@ -25191,6 +25172,11 @@ msgstr "Premiumtyp" msgid "Premium until date" msgstr "Premium till och med" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Förbereder" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "ProfilmĂ€rke" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profilbannrar Ă€r en {PREMIUM_PRODUCT_NAME}-funktion. Skaffa {PREMIUM_PRODUCT_NAME} för att lĂ€gga till en banner pĂ„ din profil." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Profilbannrar Ă€r inte aktiverade pĂ„ den hĂ€r instansen." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profilbannrar krĂ€ver {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profilbannrar krĂ€ver {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Tryck för att prata" msgid "Push-to-talk (limited)" msgstr "Tryck för att prata (begrĂ€nsat)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Tryck för att prata ignoreras vid direktinmatning. VĂ€xla till fokuserat röstlĂ€ge eller anpassat lĂ€ge för att anvĂ€nda funktionen." @@ -26551,8 +26537,8 @@ msgstr "Ta bort bilaga" msgid "Remove authenticator app" msgstr "Ta bort autentiseringsapp" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Ta bort profilbild" @@ -26561,8 +26547,8 @@ msgstr "Ta bort profilbild" msgid "Remove background" msgstr "Ta bort bakgrund" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Ta bort banner" @@ -26625,10 +26611,10 @@ msgstr "Sluta visa överst" msgid "Remove from URL-only GIF favorites" msgstr "Ta bort frĂ„n URL-baserade GIF-favoriter" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Ta bort ikon" @@ -27331,7 +27317,7 @@ msgstr "Skickat igen" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ÅterstĂ€ll" @@ -28074,7 +28060,7 @@ msgstr "RumĂ€nska" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Rotera medurs" @@ -28153,8 +28139,8 @@ msgstr "MĂ€ttnad" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "InstĂ€llningar för skĂ€rmdelningskodare" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "SkĂ€rmdelningen avslutades" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Visa ett rött mĂ€rke pĂ„ appikonen nĂ€r du har olĂ€sta meddelanden" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Visa endast accentfĂ€rg, ignorera din globala profil" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Visa anpassade emojier i förslag för uttryck" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Visa standardavatar, ignorera din globala profil" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Visa indikator för olĂ€sta meddelanden pĂ„ tystade kanaler" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Visa din globala profilavatar i den hĂ€r communityn" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Visa din globala profilbanner i den hĂ€r communityn" @@ -30720,7 +30706,7 @@ msgstr "Hoppa över" msgid "Skip \"Mark all as read\" confirmation" msgstr "Hoppa över bekrĂ€ftelse för \"Markera alla som lĂ€sta\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Hoppa över beskĂ€rning" @@ -32346,7 +32332,7 @@ msgstr "Byt till rymlig layout" msgid "Switch to dense layout" msgstr "VĂ€xla till kompakt layout" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Byt till direktinmatning" @@ -32734,7 +32720,7 @@ msgstr "Uppgifter" msgid "Teleporting you to another voice region..." msgstr "Teleporterar dig till en annan röstregion..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Mall" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rollen gav {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "SkĂ€rmdelningskĂ€llan slutade skicka video, sĂ„ din skĂ€rmdelning har stoppats." @@ -33453,6 +33439,11 @@ msgstr "Det hĂ€r kontot kan inte blockeras." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Den hĂ€r Ă„tgĂ€rden kan inte Ă„ngras. All tillhörande data, inklusive botanvĂ€ndaren, kommer att raderas permanent." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Den hĂ€r animeringen Ă€r för lĂ„ng eller för stor för att beskĂ€ra. Prova en kortare eller mindre fil." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Den hĂ€r botten Ă€r inte offentlig och kan inte lĂ€ggas till av andra an msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Den hĂ€r boten begĂ€r administratörsbehörighet. Ge den bara behörighet om du litar helt pĂ„ utvecklaren. Be dem att begĂ€ra fĂ€rre behörigheter istĂ€llet. StĂ€ng den hĂ€r sidan om du Ă€r osĂ€ker." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "WebblĂ€saren kan inte beskĂ€ra animerade {avifFormatLabel}-filer. Ladda upp en GIF eller WebP istĂ€llet." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Den hĂ€r webblĂ€sarkonsolen Ă€r ett utvecklarverktyg." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "WebAssembly Ă€r avstĂ€ngt i den hĂ€r webblĂ€saren, sĂ„ animerade bilder kan inte beskĂ€ras." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Den hĂ€r gruppen Ă€r full. Ta bort nĂ„gon innan du lĂ€gger till fler per msgid "This handoff code has expired. Generate a new one to continue." msgstr "Den hĂ€r överlĂ€mningskoden har gĂ„tt ut. Skapa en ny för att fortsĂ€tta." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Bilden kunde inte lĂ€sas. Den kan vara skadad." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "Ladda upp" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Ladda upp en anpassad avatar för den hĂ€r communityn" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Ladda upp en anpassad banner för den hĂ€r communityn" @@ -36155,10 +36163,10 @@ msgstr "Ladda upp filer och medier i meddelanden." msgid "Upload files and media in this channel." msgstr "Ladda upp filer och medier i den hĂ€r kanalen." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Ladda upp ikon" @@ -36401,8 +36409,8 @@ msgstr "AnvĂ€nd koltema (kolsvarta ytor)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "AnvĂ€nd egen bild" @@ -36462,8 +36470,8 @@ msgstr "AnvĂ€nd filter eller skriv in sökord för att hitta meddelanden" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "AnvĂ€nd global profil" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Röstdeltagare" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Röstbearbetning" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Med {PREMIUM_PRODUCT_NAME} kan du anvĂ€nda animerade avatarer ({ANIMATED_AVATAR_FORMATS}) och profilbannrar, anpassa din tagg och fĂ„ mĂ„nga andra {PREMIUM_PRODUCT_NAME}-förmĂ„ner." @@ -39334,8 +39342,8 @@ msgstr "Du behöver behörigheten ”{permissionLabel}” för att anvĂ€nda emoj msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Du behöver behörigheten ”{permissionLabel}” för att anvĂ€nda klistermĂ€rken frĂ„n andra communities hĂ€r." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Du mĂ„ste sĂ€kra ditt konto innan du kan skapa en community." @@ -39356,8 +39364,8 @@ msgstr "Du mĂ„ste sĂ€kra ditt konto för att skicka meddelanden i den hĂ€r commu msgid "You need to verify a phone number to send messages in this community." msgstr "Du mĂ„ste verifiera ett telefonnummer för att skicka meddelanden i den hĂ€r communityn." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Du mĂ„ste verifiera din e-postadress innan du kan skapa en community." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Din sparade {savedResolution} med {savedFrameRate} FPS krĂ€ver {premiumProductName}, sĂ„ delningar anvĂ€nder {resolution} med {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Din skĂ€rmdelning kunde inte publiceras med en kompatibel videokodek, sĂ„ den stoppades. Försök dela igen." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Din anpassade URL har stĂ€llts in till {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Din videokodare slutade koda bildrutor, sĂ„ din skĂ€rmdelning stoppades. Försök dela igen." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Zooma" diff --git a/fluxer_app/src/features/i18n/locales/th/messages.po b/fluxer_app/src/features/i18n/locales/th/messages.po index dd1a73113..c0eec15dd 100644 --- a/fluxer_app/src/features/i18n/locales/th/messages.po +++ b/fluxer_app/src/features/i18n/locales/th/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel} àč€àžŁàč‡àž§àč† àž™àž”àč‰" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "àž‚àž™àžČàž”àž‚àž­àž‡ {label} àč„àžĄàčˆàž•àžŁàž‡àžàž±àžšàž—àž”àčˆàž•àč‰àž­àž‡àžàžČàžŁ àč€àž„àž·àž­àžàžŁàžčàž›àž àžČàžžàž­àž·àčˆàž™àž«àžŁàž·àž­àž­àž±àž›àč‚àž«àž„àž”àž àžČàžžàž™àžŽàčˆàž‡àž—àž”àčˆàž„àžŁàž­àžšàž•àž±àž”àč„àž”àč‰" - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "àč„àžŸàž„àčŒ {label} àžĄàž”àž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž› àč€àž„àž·àž­àžàč„àžŸàž„àčŒàž—àž”àčˆàč€àž„àč‡àžàžàž§àčˆàžČ {maxSizeLabel}" #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àč€àž›àč‡àž™àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àč„àž”àč‰ àčƒàžŠàč‰àž àžČàžžàž™àžŽàčˆàž‡" @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "àžàžČàžŁàčàžŠàžŁàčŒàžàžŽàžˆàžàžŁàžŁàžĄ" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "àč€àžàž“àž‘àčŒàžàžŽàžˆàžàžŁàžŁàžĄ" @@ -3566,11 +3561,11 @@ msgstr "àž­àž™àžžàžàžČàž• {everyoneMention} àčàž„àž° {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰ {PRODUCT_NAME} àč€àž‚àč‰àžČàž–àž¶àž‡àžàž„àč‰àž­àž‡àž‚àž­àž‡àž„àžžàž“àčƒàž™ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰ {PRODUCT_NAME} àč€àž‚àč‰àžČàž–àž¶àž‡àč„àžĄàč‚àž„àžŁàč‚àžŸàž™àž‚àž­àž‡àž„àžžàž“àčƒàž™ {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰ {PRODUCT_NAME} àč€àž‚àč‰àžČàž–àž¶àž‡àč„àžĄàč‚àž„àžŁàč‚àžŸàž™àž‚àž­àž‡àž„àžžàž“ àž•àžŁàž§àžˆàžȘàž­àžšàčàž–àžšàž—àž”àčˆàž­àžąàžčàčˆàž«àžŁàž·àž­àžàžČàžŁàž•àž±àč‰àž‡àž„àčˆàžČàž‚àž­àž‡àč€àžšàžŁàžČàž§àčŒàč€àž‹àž­àžŁàčŒàž‚àž­àž‡àž„àžžàž“" @@ -3673,7 +3668,7 @@ msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰àžȘàžĄàžČàžŠàžŽàžàž—àž”àčˆàč„àžĄàčˆàžĄàž”àžȘ msgid "Allow mentions for this role" msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰àžàž„àčˆàžČàž§àž–àž¶àž‡àžšàž—àžšàžČàž—àž™àž”àč‰" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "àž­àž™àžžàžàžČàž•àčƒàž«àč‰àčƒàžŠàč‰àč„àžĄàč‚àž„àžŁàč‚àžŸàž™" @@ -3942,25 +3937,21 @@ msgstr "àčàž„àž°àž­àž”àž {remainingCount} àžŁàžČàžąàžàžČàžŁ" msgid "Animate on interaction" msgstr "àč€àž„àčˆàž™àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àč€àžĄàž·àčˆàž­àžĄàž”àžàžČàžŁàč‚àž•àč‰àž•àž­àžš" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàč„àžŸàž„àčŒ {AVIF_FORMAT_LABEL} àčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ àč‚àž›àžŁàž”àž­àž±àž›àč‚àž«àž„àž”àč„àžŸàž„àčŒ {AVIF_FORMAT_LABEL} àčàžšàžšàž„àž‡àž—àž”àčˆàčàž—àž™" - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžš {avifFormatLabel} àčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ ({ANIMATED_AVATAR_FORMATS}) àčƒàžŠàč‰àč„àž”àč‰àč€àž‰àžžàžČàž°àžœàžčàč‰àžȘàžĄàž±àž„àžŁàžȘàžĄàžČàžŠàžŽàž {PREMIUM_PRODUCT_NAME} àč€àž—àčˆàžČàž™àž±àč‰àž™" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ ({ANIMATED_AVATAR_FORMATS}) àč„àžĄàčˆàžžàžŁàč‰àž­àžĄàčƒàžŠàč‰àž‡àžČàž™àčƒàž™àž­àžŽàž™àžȘàčàž•àž™àž‹àčŒàž™àž”àč‰ àč‚àž›àžŁàž”àž­àž±àž›àč‚àž«àž„àž”àžŁàžčàž›àž àžČàžžàž™àžŽàčˆàž‡àčàž—àž™" #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ ({animatedAvatarFormats}) àž•àč‰àž­àž‡àčƒàžŠàč‰ {premiumProductName}" @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàž„àž°àčàžšàž™àč€àž™àž­àžŁàčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àč„àžĄàčˆàžžàžŁàč‰àž­àžĄàčƒàžŠàč‰àž‡àžČàž™" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àž•àč‰àž­àž‡àčƒàžŠàč‰ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "àž•àž±àž§àž­àžąàčˆàžČàž‡àžŁàžčàž›àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàžŁàžčàž›àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àžȘàžłàž«àžŁàž±àžšàžŁàžčàž›àž™àž”àč‰" @@ -4947,7 +4938,7 @@ msgstr "àž•àžŁàž§àžˆàžˆàž±àžšàž àžČàž©àžČàž­àž±àž•àč‚àž™àžĄàž±àž•àžŽ" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "àž•àž±àč‰àž‡àž„àčˆàžČàč€àžàž“àž‘àčŒàžàžŽàžˆàžàžŁàžŁàžĄàž­àž±àž•àč‚àž™àžĄàž±àž•àžŽ" @@ -5127,15 +5118,15 @@ msgstr "àčƒàžŠàč‰àž‡àžČàž™àč„àž”àč‰àčƒàž™àčàž­àž›àč€àž”àžȘàžàčŒàž—àč‡àž­àž›" #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒ" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "àč„àžŸàž„àčŒàžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàžĄàž”àž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž› àč‚àž›àžŁàž”àč€àž„àž·àž­àžàč„àžŸàž„àčŒàž—àž”àčˆàžĄàž”àž‚àž™àžČàž”àč€àž„àč‡àžàžàž§àčˆàžČ {imageMaxSizeLabel}" @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčƒàž«àžàčˆàč€àžàžŽàž™àč„àž› àč€àž„àž·àž­àžàžŁàžčàž›àž—àž”àčˆàž‚àž™àžČàž”àč„àžĄàčˆàč€àžàžŽàž™ {imageMaxSizeLabel}" #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "àč€àž„àž·àž­àžàč‚àž«àžĄàž”àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒ" @@ -5187,11 +5178,11 @@ msgstr "àč„àžĄàčˆàž­àžąàžčàčˆàž•àž­àž™àž™àž”àč‰" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "àžœàžčàč‰àčƒàžŠàč‰àž—àž”àčˆàž–àžčàžàčàžšàž™" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "àčàžšàž™àč€àž™àž­àžŁàčŒ" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "àč„àžŸàž„àčŒàčàžšàž™àč€àž™àž­àžŁàčŒàžĄàž”àž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž› àč‚àž›àžŁàž”àč€àž„àž·àž­àžàč„àžŸàž„àčŒàž—àž”àčˆàžĄàž”àž‚àž™àžČàž”àč€àž„àč‡àžàžàž§àčˆàžČ {imageMaxSizeLabel}" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "àč€àž„àž·àž­àžàč‚àž«àžĄàž”àčàžšàž™àč€àž™àž­àžŁàčŒ" @@ -6107,8 +6098,8 @@ msgstr "àž‹àž·àč‰àž­àž‚àž­àž‡àž‚àž§àž±àž {premiumProductName} àžˆàžČàžàčàž— msgid "Buy gift" msgstr "àž‹àž·àč‰àž­àž‚àž­àž‡àž‚àž§àž±àž" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "àžàžČàžŁàžȘàžŁàč‰àžČàž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àčàžȘàž”àž‡àž§àčˆàžČàž„àžžàž“àžąàž­àžĄàžŁàž±àžšàž—àž”àčˆàžˆàž°àž›àžàžŽàžšàž±àž•àžŽàž•àžČàžĄàčàž„àž°àžŁàž±àžàž©àžČ<0>àž«àž„àž±àžàč€àžàž“àž‘àčŒàž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž‚àž­àž‡ {PRODUCT_NAME}" @@ -6361,7 +6352,7 @@ msgstr "àž­àž±àž›àč‚àž«àž„àž”àč„àžŸàž„àčŒàž—àž”àčˆàž™àž”àčˆàč„àžĄàčˆàč„àž”àč‰" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "àžˆàž±àž”àžàž¶àčˆàž‡àžàž„àžČàž‡" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "àč€àž›àž„àž”àčˆàžąàž™àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒ" @@ -6627,9 +6618,9 @@ msgstr "àč€àž›àž„àž”àčˆàžąàž™àžžàž·àč‰àž™àž«àž„àž±àž‡" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "àč€àž›àž„àž”àčˆàžąàž™àž àžČàžžàž›àž" @@ -6668,13 +6659,13 @@ msgstr "àč€àž›àž„àž”àčˆàžąàž™àžŠàž·àčˆàž­àč€àž„àčˆàž™àžàž„àžžàčˆàžĄ" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "àč€àž›àž„àž”àčˆàžąàž™àč„àž­àž„àž­àž™" @@ -7669,8 +7660,8 @@ msgstr "àžŁàž±àžšàž‚àž­àž‡àž‚àž§àž±àž" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "àžąàž·àž™àžąàž±àž™àžšàž±àžàžŠàž”àž‚àž­àž‡àž„àžžàž“" @@ -8518,8 +8509,8 @@ msgstr "àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰àč€àž­àž·àč‰àž­àčƒàž«àč‰àč€àžàžŽ msgid "Community filter" msgstr "àž•àž±àž§àžàžŁàž­àž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "àč„àž­àž„àž­àž™àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰" @@ -8763,6 +8754,11 @@ msgstr "àž›àžžàčˆàžĄàčƒàž™àžŠàčˆàž­àž‡àžžàžŽàžĄàžžàčŒàž‚àč‰àž­àž„àž§àžČàžĄ" msgid "Composer focus" msgstr "àč‚àžŸàžàž±àžȘàžŠàčˆàž­àž‡àžžàžŽàžĄàžžàčŒàž‚àč‰àž­àž„àž§àžČàžĄ" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "àžàžłàž„àž±àž‡àžšàž”àžšàž­àž±àž”" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "àč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àžàž„àč‰àž­àž‡àž«àžŁàž·àž­àž­àžžàž›àžàžŁàž“ msgid "Connect a display, then try again." msgstr "àč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àžˆàž­àčàžȘàž”àž‡àžœàž„ àčàž„àč‰àž§àž„àž­àž‡àž­àž”àžàž„àžŁàž±àč‰àž‡" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "àč€àžŠàž·àčˆàž­àžĄàž•àčˆàž­àč„àžĄàč‚àž„àžŁàč‚àžŸàž™àčàž„àč‰àž§àž„àž­àž‡àž­àž”àžàž„àžŁàž±àč‰àž‡" @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "àžȘàžŁàč‰àžČàž‡àžȘàž•àžŽàžàč€àžàž­àžŁàčŒàž™àž”àč‰àč„àžĄàčˆàč„àž”àč‰" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž„àžŁàž­àžšàž•àž±àž”àžŁàžčàž›àž àžČàžžàč„àž”àč‰" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž­àž±àž›àč€àž”àž•àžàžČàžŁàčàžŠàžŁàčŒàžàžŽàžˆàžàžŁàžŁàžĄàč€àžȘàž”àžąàž‡àč„àž”àč‰àčƒàž™àž‚àž“àž°àž™àž”àč‰" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "àž­àž±àž›àč‚àž«àž„àž”àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàč„àžĄàčˆàč„àž”àč‰" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "àž­àž±àž›àč‚àž«àž„àž”àčàžšàž™àč€àž™àž­àžŁàčŒàč„àžĄàčˆàč„àž”àč‰" @@ -10230,7 +10226,7 @@ msgstr "àžȘàžŁàč‰àžČàž‡àčàž„àž°àčàžŠàžŁàčŒ" msgid "Create a community" msgstr "àžȘàžŁàč‰àžČàž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "àžȘàžŁàč‰àžČàž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àčƒàž«àč‰àž„àžžàž“àčàž„àž°àč€àžžàž·àčˆàž­àž™àč† àč„àž”àč‰àčàžŠàž—àžàž±àž™" @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "àž„àžŁàž­àžšàž•àž±àž”àžžàž·àč‰àž™àž«àž„àž±àž‡àž„àžłàč€àžŠàžŽàž" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "àž•àž±àž§àž­àžąàčˆàžČàž‡àžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”" @@ -10500,30 +10496,15 @@ msgstr "àž„àžŁàž­àžšàž•àž±àž”àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "àžŁàžčàž›àž àžČàžžàž—àž”àčˆàž„àžŁàž­àžšàž•àž±àž”àžĄàž”àž‚àž™àžČàž”àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž› àč€àž„àž·àž­àžàžžàž·àč‰àž™àž—àž”àčˆàž—àž”àčˆàč€àž„àč‡àžàž„àž‡àž«àžŁàž·àž­àč„àžŸàž„àčŒàž—àž”àčˆàč€àž„àč‡àžàž„àž‡ (àžȘàžčàž‡àžȘàžžàž” {maxSizeLabel})" -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "àžąàž±àž‡àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”àč„àžŸàž„àčŒ {formatLabel} àčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ àžˆàž°àčƒàžŠàč‰àžŁàžčàž›àž àžČàžžàž•àč‰àž™àž‰àžšàž±àžšàčàž—àž™" - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "àžąàž±àž‡àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”àč„àžŸàž„àčŒ {formatLabel} àčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ àžˆàž°àčƒàžŠàč‰àč„àžŸàž„àčŒàž—àž”àčˆàž­àž±àž›àč‚àž«àž„àž”àž•àč‰àž™àž‰àžšàž±àžšàčàž—àž™" - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "àžąàž±àž‡àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”àč„àžŸàž„àčŒàž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ àžˆàž°àčƒàžŠàč‰àžŁàžčàž›àž àžČàžžàž•àč‰àž™àž‰àžšàž±àžšàčàž—àž™" - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "àžąàž±àž‡àč„àžĄàčˆàžŁàž­àž‡àžŁàž±àžšàžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”àč„àžŸàž„àčŒàž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ àžˆàž°àčƒàžŠàč‰àč„àžŸàž„àčŒàž—àž”àčˆàž­àž±àž›àč‚àž«àž„àž”àž•àč‰àž™àž‰àžšàž±àžšàčàž—àž™" +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "àžàžłàž„àž±àž‡àž„àžŁàž­àžšàž•àž±àž” {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "àžąàž±àž‡àč„àžĄàčˆàžĄàž”àžšàž±àžàžŠàž”àčƒàžŠàčˆàč„àž«àžĄ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "àč„àžĄàčˆàčàžȘàž”àž‡" @@ -16560,8 +16541,8 @@ msgstr "àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàčàžŠàž—àžàž„àžžàčˆàžĄàčƒàžŠàč‰àžĄàžČàžȘ msgid "Group DMs" msgstr "àčàžŠàž—àžàž„àžžàčˆàžĄ" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "àč„àž­àž„àž­àž™àžàž„àžžàčˆàžĄ" @@ -16624,8 +16605,8 @@ msgstr "àž•àž±àč‰àž‡àž„àčˆàžČàžàž„àžžàčˆàžĄ" msgid "Group typing states" msgstr "àžȘàž–àžČàž™àž°àžàžłàž„àž±àž‡àžžàžŽàžĄàžžàčŒàž‚àž­àž‡àžàž„àžžàčˆàžĄ" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "àž­àž±àž›àč€àž”àž•àžàž„àžžàčˆàžĄàčàž„àč‰àž§" @@ -16803,7 +16784,7 @@ msgstr "àž«àž±àž§àčƒàžˆ" msgid "Hebrew" msgstr "àžźàž”àžšàžŁàžč" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "àž„àž§àžČàžĄàžȘàžčàž‡" @@ -17510,7 +17491,7 @@ msgstr "àž„àž±àž”àž„àž­àžàžŁàžčàž›àž àžČàžžàčàž„àč‰àž§" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "àčƒàžŠàč‰àžŁàžčàž›àž àžČàžžàč„àžĄàčˆàč„àž”àč‰" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "àžŁàžčàž›àž„àž±àžàž©àž“àčŒàčàž„àž°àžàžČàžŁàčàžȘàž”àž‡àžœàž„" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "àž”àžčàč€àž«àžĄàž·àž­àž™àž§àčˆàžČàž„àžžàž“àžàžłàž„àž±àž‡àčƒàžŠàč‰ {0} àžàžČàžŁàž›àžŁàž°àžĄàž§àž„àžœàž„àž‚àž­àž‡ {PRODUCT_NAME} àč€àžžàžŽàčˆàžĄàč€àž•àžŽàžĄàž­àžČàžˆàž—àžłàčƒàž«àč‰àč€àžàžŽàž”àč€àžȘàž”àžąàž‡àž›àž±àčŠàžĄàž«àžŁàž·àž­àč€àžȘàž”àžąàž‡àžœàžŽàž”àč€àžžàž”àč‰àžąàž™àč„àž”àč‰ àž­àžŽàž™àžžàžžàž•àč‚àž”àžąàž•àžŁàž‡àžˆàž°àžȘàčˆàž‡àžȘàž±àžàžàžČàž“àč€àžȘàž”àžąàž‡àž‚àž­àž‡àž„àžžàž“àč„àž›àč‚àž”àžąàč„àžĄàčˆàžĄàž”àžàžČàžŁàč€àž›àž„àž”àčˆàžąàž™àčàž›àž„àž‡" @@ -22577,7 +22558,7 @@ msgstr "àč„àžĄàčˆàžžàžšàžœàž„àž„àž±àžžàž˜àčŒ" msgid "No mentions yet" msgstr "àžąàž±àž‡àč„àžĄàčˆàžĄàž”àžàžČàžŁàžàž„àčˆàžČàž§àž–àž¶àž‡" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "àč„àžĄàčˆàžžàžšàč„àžĄàč‚àž„àžŁàč‚àžŸàž™" @@ -23806,7 +23787,7 @@ msgstr "àč€àž›àžŽàž”àž‚àč‰àž­àž„àž§àžČàžĄàžȘàčˆàž§àž™àž•àž±àž§àž‚àž­àž‡àžŁàž°àžš msgid "Open system picker" msgstr "àč€àž›àžŽàž”àž•àž±àž§àč€àž„àž·àž­àžàž‚àž­àž‡àžŁàž°àžšàžš" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "àč€àž›àžŽàž”àč€àž—àžĄàč€àžžàž„àž• JSON" @@ -23820,7 +23801,7 @@ msgstr "àč€àž›àžŽàž”àžàž„àčˆàž­àž‡àč‚àž•àč‰àž•àž­àžšàžàžČàžŁàčàžšàž™àžȘàžłàž« msgid "Open the context menu" msgstr "àč€àž›àžŽàž”àč€àžĄàž™àžčàž•àž±àž§àč€àž„àž·àž­àž" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "àč€àž›àžŽàž”àž„àžŽàž‡àžàčŒàž”àč‰àžČàž™àž„àčˆàžČàž‡àčƒàž™àč€àžšàžŁàžČàž§àčŒàč€àž‹àž­àžŁàčŒ àžˆàžČàžàž™àž±àč‰àž™àž„àž±àž”àž„àž­àžàžàžČàžŁàž•àž­àžšàžàž„àž±àžš JSON àž—àž±àč‰àž‡àž«àžĄàž” àčàž„àč‰àž§àž§àžČàž‡àž„àž‡àčƒàž™àžŠàčˆàž­àž‡" @@ -24331,7 +24312,7 @@ msgstr "7 àž§àž±àž™àž—àž”àčˆàžœàčˆàžČàž™àžĄàžČ" msgid "Paste" msgstr "àž§àžČàž‡" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "àž§àžČàž‡ URL àč€àž—àžĄàč€àžžàž„àž•àž‚àž­àž‡ {theOtherPlatform} àč€àžžàž·àčˆàž­àž™àžłàč€àž‚àč‰àžČàč‚àž„àžŁàž‡àžȘàžŁàč‰àžČàž‡àč„àž›àžąàž±àž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àčƒàž«àžĄàčˆ" @@ -25191,6 +25172,11 @@ msgstr "àž›àžŁàž°àč€àž àž—àžžàžŁàž”àč€àžĄàž”àžąàžĄ" msgid "Premium until date" msgstr "àžžàžŁàž”àč€àžĄàž”àžąàžĄàž–àž¶àž‡àž§àž±àž™àž—àž”àčˆ" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "àžàžłàž„àž±àž‡àč€àž•àžŁàž”àžąàžĄ" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "àč‚àž›àžŁàč„àžŸàž„àčŒ" msgid "Profile badge" msgstr "àž›àč‰àžČàžąàč‚àž›àžŁàč„àžŸàž„àčŒ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒàč€àž›àč‡àž™àžŸàž”àč€àžˆàž­àžŁàčŒàž‚àž­àž‡ {PREMIUM_PRODUCT_NAME} àžŁàž±àžš {PREMIUM_PRODUCT_NAME} àč€àžžàž·àčˆàž­àč€àžžàžŽàčˆàžĄàčàžšàž™àč€àž™àž­àžŁàčŒàčƒàž™àč‚àž›àžŁàč„àžŸàž„àčŒàž‚àž­àž‡àž„àžžàž“" #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒàč„àžĄàčˆàč„àž”àč‰àč€àž›àžŽàž”àčƒàžŠàč‰àž‡àžČàž™àčƒàž™àž­àžŽàž™àžȘàčàž•àž™àž‹àčŒàž™àž”àč‰" #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒàž•àč‰àž­àž‡àčƒàžŠàč‰ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒàž•àč‰àž­àž‡àčƒàžŠàč‰ {premiumProductName}" @@ -25838,7 +25824,7 @@ msgstr "àžàž”àč€àžžàž·àčˆàž­àžžàžčàž”" msgid "Push-to-talk (limited)" msgstr "àžàž”àč€àžžàž·àčˆàž­àžžàžčàž” (àžˆàžłàžàž±àž”)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "àžàž”àč€àžžàž·àčˆàž­àžžàžčàž”àžˆàž°àč„àžĄàčˆàž—àžłàž‡àžČàž™àčƒàž™àč‚àž«àžĄàž”àž­àžŽàž™àžžàžžàž•àč‚àž”àžąàž•àžŁàž‡ àž«àžČàžàž•àč‰àž­àž‡àžàžČàžŁàčƒàžŠàč‰àž‡àžČàž™ àčƒàž«àč‰àč€àž›àž„àž”àčˆàžąàž™àč€àž›àč‡àž™àč€àž™àč‰àž™àč€àžȘàž”àžąàž‡àžžàžčàž”àž«àžŁàž·àž­àžàžłàž«àž™àž”àč€àž­àž‡" @@ -26551,8 +26537,8 @@ msgstr "àž„àžšàč„àžŸàž„àčŒàčàž™àžš" msgid "Remove authenticator app" msgstr "àž™àžłàčàž­àž›àžąàž·àž™àžąàž±àž™àž•àž±àž§àž•àž™àž­àž­àž" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "àž„àžšàžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒ" @@ -26561,8 +26547,8 @@ msgstr "àž„àžšàžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒ" msgid "Remove background" msgstr "àž„àžšàž àžČàžžàžžàž·àč‰àž™àž«àž„àž±àž‡" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "àž„àžšàčàžšàž™àč€àž™àž­àžŁàčŒ" @@ -26625,10 +26611,10 @@ msgstr "àč€àž„àžŽàžàž•àžŁàž¶àž‡àč„àž§àč‰àž”àč‰àžČàž™àžšàž™" msgid "Remove from URL-only GIF favorites" msgstr "àž™àžłàž­àž­àžàžˆàžČàž GIF àžŁàžČàžąàžàžČàžŁàč‚àž›àžŁàž” (àč€àž‰àžžàžČàž° URL)" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "àž„àžšàč„àž­àž„àž­àž™" @@ -27331,7 +27317,7 @@ msgstr "àžȘàčˆàž‡àž­àž”àžàž„àžŁàž±àč‰àž‡àčàž„àč‰àž§" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "àžŁàž”àč€àž‹àč‡àž•" @@ -28074,7 +28060,7 @@ msgstr "àč‚àžŁàžĄàžČàč€àž™àž”àžą" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "àž«àžĄàžžàž™àž•àžČàžĄàč€àž‚àč‡àžĄàž™àžČàžŹàžŽàžàžČ" @@ -28153,8 +28139,8 @@ msgstr "àž„àž§àžČàžĄàž­àžŽàčˆàžĄàž•àž±àž§àž‚àž­àž‡àžȘàž”" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "àžàžČàžŁàž„àž§àžšàž„àžžàžĄàž•àž±àž§àč€àž‚àč‰àžČàžŁàž«àž±àžȘàžȘàžłàž«àžŁàž±àžšàžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "àžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­àžȘàžŽàč‰àž™àžȘàžžàž”àž„àž‡" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "àčàžȘàž”àž‡àž›àč‰àžČàžąàžȘàž”àčàž”àž‡àžšàž™àč„àž­àž„àž­àž™àčàž­àž›àč€àžĄàž·àčˆàž­àžĄàž”àž‚àč‰àž­àž„àž§àžČàžĄàž—àž”àčˆàžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àž­àčˆàžČàž™" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "àčàžȘàž”àž‡àč€àž‰àžžàžČàž°àžȘàž”àč€àž™àč‰àž™ àč„àžĄàčˆàčƒàžŠàč‰àč‚àž›àžŁàč„àžŸàž„àčŒàžȘàčˆàž§àž™àžàž„àžČàž‡àž‚àž­àž‡àž„àžžàž“" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "àčàžȘàž”àž‡àž­àžŽàč‚àžĄàžˆàžŽàž—àž”àčˆàžàžłàž«àž™àž”àč€àž­àž‡àčƒàž™àžàžČàžŁàč€àž•àžŽàžĄàž‚àč‰àž­àž„àž§àžČàžĄàž­àž±àž•àč‚àž™àžĄàž±àž•àžŽ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "àčàžȘàž”àž‡àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàč€àžŁàžŽàčˆàžĄàž•àč‰àž™ àč„àžĄàčˆàčƒàžŠàč‰àč‚àž›àžŁàč„àžŸàž„àčŒàžȘàčˆàž§àž™àžàž„àžČàž‡àž‚àž­àž‡àž„àžžàž“" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "àčàžȘàž”àž‡àž•àž±àž§àžšàčˆàž‡àžŠàž”àč‰àž‚àč‰àž­àž„àž§àžČàžĄàž—àž”àčˆàžąàž±àž‡àč„àžĄàčˆàč„àž”àč‰àž­àčˆàžČàž™àčƒàž™àžŠàčˆàž­àž‡àž—àž”àčˆàž›àžŽàž”àč€àžȘàž”àžąàž‡" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "àčàžȘàž”àž‡àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàžȘàčˆàž§àž™àžàž„àžČàž‡àž‚àž­àž‡àž„àžžàž“àčƒàž™àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "àčàžȘàž”àž‡àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒàžȘàčˆàž§àž™àžàž„àžČàž‡àž‚àž­àž‡àž„àžžàž“àčƒàž™àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰" @@ -30720,7 +30706,7 @@ msgstr "àž‚àč‰àžČàžĄ" msgid "Skip \"Mark all as read\" confirmation" msgstr "àž‚àč‰àžČàžĄàžàžČàžŁàžąàž·àž™àžąàž±àž™ \"àž—àžłàč€àž„àžŁàž·àčˆàž­àž‡àž«àžĄàžČàžąàž§àčˆàžČàž­àčˆàžČàž™àčàž„àč‰àž§àž—àž±àč‰àž‡àž«àžĄàž”\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "àž‚àč‰àžČàžĄàžàžČàžŁàž„àžŁàž­àžšàž•àž±àž”" @@ -32346,7 +32332,7 @@ msgstr "àč€àž›àž„àž”àčˆàžąàž™àč€àž›àč‡àž™àč€àž„àžąàčŒàč€àž­àžČàž•àčŒàžȘàžšàžČàžą msgid "Switch to dense layout" msgstr "àč€àž›àž„àž”àčˆàžąàž™àč€àž›àč‡àž™àč€àž„àžąàčŒàč€àž­àžČàž•àčŒàčàžšàžšàžàžŁàž°àžŠàž±àžš" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "àč€àž›àž„àž”àčˆàžąàž™àč€àž›àč‡àž™àž­àžŽàž™àžžàžžàž•àč‚àž”àžąàž•àžŁàž‡" @@ -32734,7 +32720,7 @@ msgstr "àž‡àžČàž™" msgid "Teleporting you to another voice region..." msgstr "àžàžłàž„àž±àž‡àžąàč‰àžČàžąàž„àžžàž“àč„àž›àžąàž±àž‡àž àžčàžĄàžŽàž àžČàž„àč€àžȘàž”àžąàž‡àž­àž·àčˆàž™..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "àč€àž—àžĄàč€àžžàž„àž•" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "àžšàž—àžšàžČàž—àž™àž”àč‰àč€àž„àžąàčƒàž«àč‰àžȘàžŽàž—àž˜àžŽàčŒ {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "àčàž«àž„àčˆàž‡àž—àž”àčˆàžĄàžČàž‚àž­àž‡àžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­àž«àžąàžžàž”àžȘàčˆàž‡àž§àžŽàž”àž”àč‚àž­ àžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­àž‚àž­àž‡àž„àžžàž“àžˆàž¶àž‡àž«àžąàžžàž”àž„àž‡" @@ -33453,6 +33439,11 @@ msgstr "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àžšàž„àč‡àž­àžàžšàž±àžàžŠàž”àž™àž”àč‰àč„àž” msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "àžàžČàžŁàž”àžłàč€àž™àžŽàž™àžàžČàžŁàž™àž”àč‰àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àč€àž„àžŽàžàž—àžłàč„àž”àč‰ àž‚àč‰àž­àžĄàžčàž„àž—àž”àčˆàč€àžàž”àčˆàžąàž§àž‚àč‰àž­àž‡àž—àž±àč‰àž‡àž«àžĄàž” àžŁàž§àžĄàž–àž¶àž‡àžœàžčàč‰àčƒàžŠàč‰àžšàž­àž— àžˆàž°àž–àžčàžàž„àžšàž­àžąàčˆàžČàž‡àž–àžČàž§àžŁ" +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àž™àž”àč‰àžąàžČàž§àž«àžŁàž·àž­àčƒàž«àžàčˆàč€àžàžŽàž™àč„àž›àž—àž”àčˆàžˆàž°àž„àžŁàž­àžšàž•àž±àž”àč„àž”àč‰ àž„àž­àž‡àčƒàžŠàč‰àč„àžŸàž„àčŒàž—àž”àčˆàžȘàž±àč‰àž™àžàž§àčˆàžČàž«àžŁàž·àž­àč€àž„àč‡àžàžàž§àčˆàžČ" + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "àžšàž­àž—àž™àž”àč‰àč„àžĄàčˆàč€àž›àč‡àž™àžȘàžČàž˜àžČàžŁàž“àž°àčàž„àž°àžœ msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "àžšàž­àž—àž™àž”àč‰àž‚àž­àžȘàžŽàž—àž˜àžŽàčŒàžœàžčàč‰àž”àžčàčàž„àžŁàž°àžšàžš àčƒàž«àč‰àžȘàžŽàž—àž˜àžŽàčŒàžàč‡àž•àčˆàž­àč€àžĄàž·àčˆàž­àž„àžžàž“àč€àžŠàž·àčˆàž­àž–àž·àž­àžœàžčàč‰àžžàž±àž’àž™àžČàž­àžąàčˆàžČàž‡àč€àž•àč‡àžĄàž—àž”àčˆàč€àž—àčˆàžČàž™àž±àč‰àž™ àž‚àž­àčƒàž«àč‰àžžàž§àžàč€àž‚àžČàž„àž”àžȘàžŽàž—àž˜àžŽàčŒàž„àž‡àčàž—àž™ àž›àžŽàž”àž«àž™àč‰àžČàž™àž”àč‰àž«àžČàžàč„àžĄàčˆàčàž™àčˆàčƒàžˆ" +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "àč€àžšàžŁàžČàž§àčŒàč€àž‹àž­àžŁàčŒàž™àž”àč‰àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž„àžŁàž­àžšàž•àž±àž”àč„àžŸàž„àčŒ {avifFormatLabel} àčàžšàžšàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àč„àž”àč‰ àč‚àž›àžŁàž”àž­àž±àž›àč‚àž«àž„àž”àč„àžŸàž„àčŒ GIF àž«àžŁàž·àž­ WebP àčàž—àž™" + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "àž„àž­àž™àč‚àž‹àž„àž‚àž­àž‡àč€àžšàžŁàžČàž§àčŒàč€àž‹àž­àžŁàčŒàž™àž”àč‰àč€àž›àč‡àž™àč€àž„àžŁàž·àčˆàž­àž‡àžĄàž·àž­àžȘàžłàž«àžŁàž±àžšàž™àž±àžàžžàž±àž’àž™àžČ" +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "àč€àžšàžŁàžČàž§àčŒàč€àž‹àž­àžŁàčŒàž™àž”àč‰àž›àžŽàž”àčƒàžŠàč‰àž‡àžČàž™ WebAssembly àž­àžąàžčàčˆ àžˆàž¶àž‡àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž„àžŁàž­àžšàž•àž±àž”àžŁàžčàž›àž àžČàžžàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§àč„àž”àč‰" + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "àžàž„àžžàčˆàžĄàž™àž”àč‰àč€àž•àč‡àžĄàčàž„àč‰àž§ àž™àžłàžȘàžĄàžČàžŠàžŽ msgid "This handoff code has expired. Generate a new one to continue." msgstr "àžŁàž«àž±àžȘàžȘàčˆàž‡àž•àčˆàž­àž™àž”àč‰àž«àžĄàž”àž­àžČàžąàžžàčàž„àč‰àž§ àžȘàžŁàč‰àžČàž‡àžŁàž«àž±àžȘàčƒàž«àžĄàčˆàč€àžžàž·àčˆàž­àž”àžłàč€àž™àžŽàž™àžàžČàžŁàž•àčˆàž­" +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àž­àčˆàžČàž™àžŁàžčàž›àž àžČàžžàž™àž”àč‰àč„àž”àč‰ àžŁàžčàž›àž àžČàžžàž­àžČàžˆàč€àžȘàž”àžąàž«àžČàžą" + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "àž­àž±àž›àč‚àž«àž„àž”" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "àž­àž±àž›àč‚àž«àž„àž”àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàžȘàžłàž«àžŁàž±àžšàž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "àž­àž±àž›àč‚àž«àž„àž”àčàžšàž™àč€àž™àž­àžŁàčŒàžȘàžłàž«àžŁàž±àžšàž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰" @@ -36155,10 +36163,10 @@ msgstr "àž­àž±àž›àč‚àž«àž„àž”àč„àžŸàž„àčŒàčàž„àž°àžȘàž·àčˆàž­àčƒàž™àž‚àč‰àž­àž„ msgid "Upload files and media in this channel." msgstr "àž­àž±àž›àč‚àž«àž„àž”àč„àžŸàž„àčŒàčàž„àž°àžȘàž·àčˆàž­àčƒàž™àžŠàčˆàž­àž‡àž™àž”àč‰" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "àž­àž±àž›àč‚àž«àž„àž”àč„àž­àž„àž­àž™" @@ -36401,8 +36409,8 @@ msgstr "àčƒàžŠàč‰àž˜àž”àžĄàž–àčˆàžČàž™àž«àžŽàž™ (àžžàž·àč‰àž™àžœàžŽàž§àžȘàž”àž” #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "àčƒàžŠàč‰àžŁàžčàž›àž àžČàžžàž—àž”àčˆàžàžłàž«àž™àž”àč€àž­àž‡" @@ -36462,8 +36470,8 @@ msgstr "àčƒàžŠàč‰àž•àž±àž§àžàžŁàž­àž‡àž«àžŁàž·àž­àž›àč‰àž­àž™àž„àž”àžąàčŒàč€àž§ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "àčƒàžŠàč‰àč‚àž›àžŁàč„àžŸàž„àčŒàžȘàčˆàž§àž™àžàž„àžČàž‡" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "àžœàžčàč‰àč€àž‚àč‰àžČàžŁàčˆàž§àžĄàžàžČàžŁàč‚àž—àžŁàž”àč‰àž§àžąàč€àžȘàž”àžąàž‡" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "àžàžČàžŁàž›àžŁàž°àžĄàž§àž„àžœàž„àč€àžȘàž”àžąàž‡" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "àž§àžŽàžȘàž„àž­àž™àž‹àžŽàž™" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "àč€àžĄàž·àčˆàž­àž„àžžàž“àžĄàž” {PREMIUM_PRODUCT_NAME} àž„àžžàž“àžȘàžČàžĄàžČàžŁàž–àčƒàžŠàč‰àžŁàžčàž›àč‚àž›àžŁàč„àžŸàž„àčŒàč€àž„àž„àž·àčˆàž­àž™àč„àž«àž§ ({ANIMATED_AVATAR_FORMATS}) àčàžšàž™àč€àž™àž­àžŁàčŒàč‚àž›àžŁàč„àžŸàž„àčŒ àž›àžŁàž±àžšàčàž•àčˆàž‡àčàž—àč‡àžàž‚àž­àž‡àž„àžžàž“ àčàž„àž°àž›àž„àž”àž„àč‡àž­àžàžȘàžŽàž—àž˜àžŽàž›àžŁàž°àč‚àžąàžŠàž™àčŒàž­àž·àčˆàž™àč† àž­àž”àžàžĄàžČàžàžĄàžČàžąàž‚àž­àž‡ {PREMIUM_PRODUCT_NAME}" @@ -39334,8 +39342,8 @@ msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžĄàž”àžȘàžŽàž—àž˜àžŽàčŒ \"{permissionLabel}\" àč€ msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžĄàž”àžȘàžŽàž—àž˜àžŽàčŒ \"{permissionLabel}\" àč€àžžàž·àčˆàž­àčƒàžŠàč‰àžȘàž•àžŽàžàč€àžàž­àžŁàčŒàžˆàžČàžàž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž­àž·àčˆàž™àž—àž”àčˆàž™àž”àčˆ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžąàž·àž™àžąàž±àž™àžšàž±àžàžŠàž”àžàčˆàž­àž™àžˆàž¶àž‡àžˆàž°àžȘàžŁàč‰àžČàž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àč„àž”àč‰" @@ -39356,8 +39364,8 @@ msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžąàž·àž™àžąàž±àž™àžšàž±àžàžŠàž”àžàčˆàž­àž™àžˆàž¶ msgid "You need to verify a phone number to send messages in this community." msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžąàž·àž™àžąàž±àž™àč€àžšàž­àžŁàčŒàč‚àž—àžŁàžšàž±àžžàž—àčŒàč€àžžàž·àčˆàž­àžȘàčˆàž‡àž‚àč‰àž­àž„àž§àžČàžĄàčƒàž™àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àž™àž”àč‰" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "àž„àžžàž“àž•àč‰àž­àž‡àžąàž·àž™àžąàž±àž™àž­àž”àč€àžĄàž„àžàčˆàž­àž™àžˆàž¶àž‡àžˆàž°àžȘàžŁàč‰àžČàž‡àž„àž­àžĄàžĄàžčàž™àžŽàž•àž”àč‰àč„àž”àč‰" @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "àž„àžžàž“àž àžČàžžàž—àž”àčˆàžšàž±àž™àž—àž¶àžàč„àž§àč‰àž‚àž­àž‡àž„àžžàž“àž—àž”àčˆ {savedResolution} àž—àž”àčˆ {savedFrameRate} FPS àž•àč‰àž­àž‡àčƒàžŠàč‰ {premiumProductName} àž”àž±àž‡àž™àž±àč‰àž™àžàžČàžŁàčàžŠàžŁàčŒàžˆàž°àčƒàžŠàč‰ {resolution} àž—àž”àčˆ {frameRate} FPS" #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "àč„àžĄàčˆàžȘàžČàžĄàžČàžŁàž–àč€àžœàžąàčàžžàžŁàčˆàžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­àž‚àž­àž‡àž„àžžàž“àž”àč‰àž§àžąàž•àž±àž§àčàž›àž„àž‡àžȘàž±àžàžàžČàž“àž§àžŽàž”àž”àč‚àž­àž—àž”àčˆàžŁàž­àž‡àžŁàž±àžšàč„àž”àč‰ àžˆàž¶àž‡àž«àžąàžžàž”àžàžČàžŁàčàžŠàžŁàčŒàž„àž‡ àž„àž­àž‡àčàžŠàžŁàčŒàž­àž”àžàž„àžŁàž±àč‰àž‡" @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "URL àž—àž”àčˆàžàžłàž«àž™àž”àč€àž­àž‡àž‚àž­àž‡àž„àžžàž“àž–àžčàžàž•àž±àč‰àž‡àž„àčˆàžČàč€àž›àč‡àž™ {inviteEndpoint}/{vanitySlug} àčàž„àč‰àž§" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "àž•àž±àž§àč€àž‚àč‰àžČàžŁàž«àž±àžȘàž§àžŽàž”àž”àč‚àž­àž‚àž­àž‡àž„àžžàž“àž«àžąàžžàž”àžàžČàžŁàč€àž‚àč‰àžČàžŁàž«àž±àžȘàč€àžŸàžŁàžĄ àžˆàž¶àž‡àž«àžąàžžàž”àžàžČàžŁàčàžŠàžŁàčŒàž«àž™àč‰àžČàžˆàž­àž‚àž­àž‡àž„àžžàž“àčàž„àč‰àž§ àž„àž­àž‡àčàžŠàžŁàčŒàž­àž”àžàž„àžŁàž±àč‰àž‡" @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "àž‹àžčàžĄ" diff --git a/fluxer_app/src/features/i18n/locales/tr/messages.po b/fluxer_app/src/features/i18n/locales/tr/messages.po index 6e303c4b5..03e18f38a 100644 --- a/fluxer_app/src/features/i18n/locales/tr/messages.po +++ b/fluxer_app/src/features/i18n/locales/tr/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, yakında" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} boyutları bu alan için uygun değil. Farklı bir görsel seçin veya kırpabileceğiniz statik bir görsel yĂŒkleyin." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} dosyası çok bĂŒyĂŒk. {maxSizeLabel} değerinden kĂŒĂ§ĂŒk bir dosya seçin." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} görselleri animasyonlu olamaz. Statik bir görsel kullanın." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Etkinlik paylaßımı" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "Etkinlik eßiği" @@ -3566,11 +3561,11 @@ msgstr "{everyoneMention} ve {hereMention} etiketlerine izin ver" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "{PRODUCT_NAME} uygulamasının kameranıza erißmesine izin vermek için {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME} yolunu izleyin." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "{PRODUCT_NAME} uygulamasının mikrofonunuza erißmesine izin vermek için {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME} yolunu izleyin." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "{PRODUCT_NAME} uygulamasının mikrofonunuza erißmesine izin verin. Tarayıcınızın adres çubuğunu veya ayarlarını kontrol edin." @@ -3673,7 +3668,7 @@ msgstr "{readMessageHistoryPermissionLabel} izni olmayan ĂŒyelerin belirli bir t msgid "Allow mentions for this role" msgstr "Bu rolden bahsedilmesine izin ver" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Mikrofona izin ver" @@ -3942,25 +3937,21 @@ msgstr "ve {remainingCount} tane daha" msgid "Animate on interaction" msgstr "Etkileßimde canlandır" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "Hareketli {AVIF_FORMAT_LABEL} dosyaları desteklenmiyor. Bunun yerine statik bir {AVIF_FORMAT_LABEL} dosyası yĂŒkleyin." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "Hareketli {avifFormatLabel} desteklenmiyor" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "Hareketli avatarlar ({ANIMATED_AVATAR_FORMATS}), yalnızca {PREMIUM_PRODUCT_NAME} abonelerine özeldir." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "Hareketli avatarlar ({ANIMATED_AVATAR_FORMATS}) bu kurulumda kullanılamıyor. Bunun yerine statik bir görsel yĂŒkleyin." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Hareketli avatarlar ({animatedAvatarFormats}), {premiumProductName} gerektirir." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "Hareketli avatarlar ve profil banner'ları" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "Hareketli avatarlar kullanılamıyor" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Hareketli avatarlar için {premiumProductName} gerekir" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Hareketli görsel önizlemesi" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "Hareketli görseller bu öge için desteklenmiyor." @@ -4947,7 +4938,7 @@ msgstr "Dili otomatik algıla" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Etkinlik eßiğini otomatik ayarla" @@ -5127,15 +5118,15 @@ msgstr "MasaĂŒstĂŒ uygulamasında mevcut." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "Avatar" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Avatar dosyası çok bĂŒyĂŒk. {imageMaxSizeLabel} değerinden kĂŒĂ§ĂŒk bir dosya seçin." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "Avatar çok bĂŒyĂŒk. {imageMaxSizeLabel} boyutundan kĂŒĂ§ĂŒk bir tane seçin." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Avatar modu seçimi" @@ -5187,11 +5178,11 @@ msgstr "ƞu an uzakta" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Yasaklı kullanıcılar" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Banner" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Banner dosyası çok bĂŒyĂŒk. {imageMaxSizeLabel} değerinden kĂŒĂ§ĂŒk bir dosya seçin." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Banner modu seçimi" @@ -6107,8 +6098,8 @@ msgstr "Arkadaßlarınızla paylaßmak için {premiumProductName} sekmesinden bi msgid "Buy gift" msgstr "Hediye satın al" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Bir topluluk olußturarak <0>{PRODUCT_NAME} Topluluk Kurallarına uymayı ve bunları sĂŒrdĂŒrmeyi kabul etmiß olursunuz." @@ -6361,7 +6352,7 @@ msgstr "Buraya dosya yĂŒklenemiyor" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Ortalanmıß" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Avatarı değißtir" @@ -6627,9 +6618,9 @@ msgstr "Arka planı değißtir" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Banner'ı değißtir" @@ -6668,13 +6659,13 @@ msgstr "Grup takma adını değißtir" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Simgeyi değißtir" @@ -7669,8 +7660,8 @@ msgstr "Hediyeyi al" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Hesabınızı sahiplenin" @@ -8518,8 +8509,8 @@ msgstr "Topluluk, toplu saldırıları veya hedefli kötĂŒye kullanımı kolayla msgid "Community filter" msgstr "Topluluk filtresi" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Topluluk simgesi" @@ -8763,6 +8754,11 @@ msgstr "Yazma alanı dĂŒÄŸmeleri" msgid "Composer focus" msgstr "Yazma alanı odağı" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Sıkıßtırılıyor" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Bir kamera veya sanal yakalama cihazı bağlayın, ardından tekrar dene msgid "Connect a display, then try again." msgstr "Bir ekran bağlayın, sonra tekrar deneyin." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Mikrofon bağlayıp tekrar deneyin." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "Bu çıkartma olußturulamadı" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "Görsel kırpılamadı" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "Ses etkinliği paylaßımı ßu anda gĂŒncellenemedi" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "Avatar yĂŒklenemedi" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "Banner yĂŒklenemedi" @@ -10230,7 +10226,7 @@ msgstr "Olußtur ve paylaß" msgid "Create a community" msgstr "Topluluk olußtur" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "Sizin ve arkadaßlarınızın sohbet edebileceği bir topluluk olußturun." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "Davet arka planını kırp" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Kırpma önizlemesi" @@ -10500,30 +10496,15 @@ msgstr "Profil banner'ını kırp" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "Kırpılan görsel çok bĂŒyĂŒk. Daha kĂŒĂ§ĂŒk bir alan veya daha kĂŒĂ§ĂŒk bir dosya seçin (maks. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Hareketli {formatLabel} dosyalarını kırpma henĂŒz desteklenmiyor. Orijinal görsel kullanılacak." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Hareketli {formatLabel} dosyalarını kırpma henĂŒz desteklenmiyor. Orijinal yĂŒkleme kullanılacak." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Hareketli dosyaları kırpma henĂŒz desteklenmiyor. Orijinal görsel kullanılacak." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Hareketli dosyaları kırpma henĂŒz desteklenmiyor. Orijinal yĂŒkleme kullanılacak." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "{percent}% kırpılıyor" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Hesabınız yok mu?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "Gösterme" @@ -16560,8 +16541,8 @@ msgstr "Grup DM avatarları, yığılmıß dĂŒzenler ve yazma durumları dahil o msgid "Group DMs" msgstr "Grup DM'leri" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "Grup simgesi" @@ -16624,8 +16605,8 @@ msgstr "Grup ayarları" msgid "Group typing states" msgstr "Grup yazma durumları" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Grup gĂŒncellendi" @@ -16803,7 +16784,7 @@ msgstr "Kalp" msgid "Hebrew" msgstr "İbranice" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "YĂŒkseklik" @@ -17510,7 +17491,7 @@ msgstr "Görsel panoya kopyalandı" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "Görsel kullanılamadı" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "GörĂŒnĂŒm ve his" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "{0} kullanıyor gibisiniz. Bunun ĂŒzerine bir de {PRODUCT_NAME} ses ißlemesi eklemek ses dalgalanmasına veya bozulmaya neden olabilir. Doğrudan giriß, sesinizi olduğu gibi iletir." @@ -22577,7 +22558,7 @@ msgstr "Eßleßme bulunamadı" msgid "No mentions yet" msgstr "HenĂŒz bahsetme yok" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "Mikrofon bulunamadı" @@ -23806,7 +23787,7 @@ msgstr "Sistem DM'ini aç" msgid "Open system picker" msgstr "Sistem seçiciyi aç" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "ƞablon JSON'ını aç" @@ -23820,7 +23801,7 @@ msgstr "Bu topluluk için yasaklama iletißim kutusunu açın." msgid "Open the context menu" msgstr "Bağlam menĂŒsĂŒnĂŒ aç" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Aßağıdaki bağlantıyı tarayıcınızda açın, ardından JSON yanıtının tamamını kopyalayıp kutuya yapıßtırın." @@ -24331,7 +24312,7 @@ msgstr "Son 7 gĂŒn" msgid "Paste" msgstr "Yapıßtır" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "Yapısını yeni bir topluluğa aktarmak için bir {theOtherPlatform} ßablon URL'si yapıßtırın." @@ -25191,6 +25172,11 @@ msgstr "Premium tĂŒrĂŒ" msgid "Premium until date" msgstr "Premium bitiß tarihi" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Hazırlanıyor" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Profil" msgid "Profile badge" msgstr "Profil rozeti" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Profil banner'ları bir {PREMIUM_PRODUCT_NAME} özelliğidir. Profilinize banner eklemek için {PREMIUM_PRODUCT_NAME} edinin." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Bu kurulumda profil banner'ları etkin değil." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Profil banner'ları için {premiumProductName} gerekir" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Profil banner'ları için {premiumProductName} gerekir." @@ -25838,7 +25824,7 @@ msgstr "Bas konuß" msgid "Push-to-talk (limited)" msgstr "Bas konuß (sınırlı)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Bas konuß özelliği doğrudan girißte yok sayılır. Kullanmak için odaklanmıß sese veya özel seçeneğine geçin." @@ -26551,8 +26537,8 @@ msgstr "Eki kaldır" msgid "Remove authenticator app" msgstr "Kimlik doğrulayıcı uygulamayı kaldır" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "Profil fotoğrafını kaldır" @@ -26561,8 +26547,8 @@ msgstr "Profil fotoğrafını kaldır" msgid "Remove background" msgstr "Arka planı kaldır" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "Banner'ı kaldır" @@ -26625,10 +26611,10 @@ msgstr "Üstte kalmayı bırak" msgid "Remove from URL-only GIF favorites" msgstr "Yalnızca URL'den kaydedilen GIF favorilerinden kaldır" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "Simgeyi kaldır" @@ -27331,7 +27317,7 @@ msgstr "Tekrar gönderildi" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Sıfırla" @@ -28074,7 +28060,7 @@ msgstr "Romence" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Saat yönĂŒnde döndĂŒr" @@ -28153,8 +28139,8 @@ msgstr "Doygunluk" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Ekran paylaßımı kodlayıcı ayarları" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Ekran paylaßımı sona erdi" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Okunmamıß mesajlarınız olduğunda uygulama simgesinde kırmızı bir rozet göster" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Genel profilinizi yok sayarak yalnızca vurgu rengini göster" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "İfade otomatik tamamlama özelliğinde özel emojileri göster" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Genel profilinizi yok sayarak varsayılan avatarı göster" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Sessize alınmıß kanallarda okunmamıß göstergesini göster" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Genel profil avatarınızı bu toplulukta gösterin" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Genel profil banner'ınızı bu toplulukta gösterin" @@ -30720,7 +30706,7 @@ msgstr "Atla" msgid "Skip \"Mark all as read\" confirmation" msgstr "\"TĂŒmĂŒnĂŒ okundu olarak ißaretle\" onayını atla" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Kırpmayı atla" @@ -32346,7 +32332,7 @@ msgstr "Rahat dĂŒzene geç" msgid "Switch to dense layout" msgstr "Yoğun dĂŒzene geç" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Doğrudan giriße geç" @@ -32734,7 +32720,7 @@ msgstr "Görevler" msgid "Teleporting you to another voice region..." msgstr "Sizi baßka bir ses bölgesine ıßınlıyoruz..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ƞablon" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Rol ßunları verdi: {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Ekran paylaßımı kaynağı video göndermeyi durdurdu, bu nedenle ekran paylaßımınız durduruldu." @@ -33453,6 +33439,11 @@ msgstr "Bu hesap engellenemez." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Bu eylem geri alınamaz. Bot kullanıcısı dahil olmak ĂŒzere ilgili tĂŒm veriler kalıcı olarak silinecek." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Bu animasyon kırpılamayacak kadar uzun veya bĂŒyĂŒk. Daha kısa veya daha kĂŒĂ§ĂŒk bir dosya deneyin." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Bu bot herkese açık değil ve diğer kullanıcılar tarafından eklene msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Bu bot yönetici izni istiyor. Yalnızca gelißtiriciye tamamen gĂŒveniyorsanız izin verin. Bunun yerine daha az izin istemesini rica edin. Emin değilseniz bu sayfayı kapatın." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "Bu tarayıcı animasyonlu {avifFormatLabel} dosyalarını kırpamaz. Bunun yerine GIF veya WebP yĂŒkleyin." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "Bu tarayıcı konsolu bir gelißtirici aracıdır." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "Bu tarayıcıda WebAssembly kapalı olduğundan hareketli resimler kırpılamaz." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Bu grup dolu. Daha fazla kißi eklemeden önce birini çıkarın." msgid "This handoff code has expired. Generate a new one to continue." msgstr "Bu aktarım kodunun sĂŒresi doldu. Devam etmek için yeni bir tane olußturun." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "Bu resim okunamadı. Bozuk olabilir." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "YĂŒkle" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "Bu topluluk için özel bir avatar yĂŒkle" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "Bu topluluk için özel bir banner yĂŒkle" @@ -36155,10 +36163,10 @@ msgstr "Mesajlarda dosya ve medya yĂŒkleyin." msgid "Upload files and media in this channel." msgstr "Bu kanalda dosya ve medya yĂŒkleyin." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "Simge yĂŒkle" @@ -36401,8 +36409,8 @@ msgstr "KömĂŒr temasını kullan (zifiri siyah yĂŒzeyler)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "Özel görsel kullan" @@ -36462,8 +36470,8 @@ msgstr "Mesajları bulmak için filtreleri kullanın veya anahtar kelimeler giri #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "Genel profili kullan" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Sesli sohbete katılanlar" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Ses ißleme" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "{PREMIUM_PRODUCT_NAME} ile hareketli avatarlar ({ANIMATED_AVATAR_FORMATS}) ve profil banner'ları kullanabilir, etiketinizi özelleßtirebilir ve diğer birçok {PREMIUM_PRODUCT_NAME} avantajının kilidini açabilirsiniz." @@ -39334,8 +39342,8 @@ msgstr "Burada diğer topluluklardan emoji kullanmak için \"{permissionLabel}\" msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Burada diğer topluluklardan çıkartma kullanmak için \"{permissionLabel}\" iznine sahip olmanız gerekir." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Topluluk olußturmadan önce hesabınızı sahiplenmeniz gerekiyor." @@ -39356,8 +39364,8 @@ msgstr "Bu toplulukta mesaj göndermek için hesabınızı sahiplenmeniz gerekiy msgid "You need to verify a phone number to send messages in this community." msgstr "Bu toplulukta mesaj göndermek için bir telefon numarası doğrulamanız gerekiyor." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Bir topluluk olußturmadan önce e-posta adresinizi doğrulamanız gerekiyor." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Kaydedilen {savedResolution} ({savedFrameRate} FPS) ayarlarınız {premiumProductName} gerektiriyor, bu nedenle paylaßımlar {resolution} ({frameRate} FPS) kullanıyor." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "Ekran paylaßımınız uyumlu bir video kodeğiyle yayınlanamadı, bu nedenle durduruldu. Tekrar paylaßmayı deneyin." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Özel URL'niz {inviteEndpoint}/{vanitySlug} olarak ayarlandı" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Video kodlayıcınız kare kodlamayı durdurduğu için ekran paylaßımınız durduruldu. Tekrar paylaßmayı deneyin." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Yakınlaßtır" diff --git a/fluxer_app/src/features/i18n/locales/uk/messages.po b/fluxer_app/src/features/i18n/locales/uk/messages.po index 532ed9f8d..d269ef7af 100644 --- a/fluxer_app/src/features/i18n/locales/uk/messages.po +++ b/fluxer_app/src/features/i18n/locales/uk/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, ĐœĐ”Đ·Đ°Đ±Đ°Ń€ĐŸĐŒ" msgid "{kilobits} kbps" msgstr "{kilobits} Đșбіт/с" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "Đ ĐŸĐ·ĐŒŃ–Ń€Đž {label} ĐœĐ” ĐČŃ–ĐŽĐżĐŸĐČіЮають Ń†ŃŒĐŸĐŒŃƒ Ń€Đ”ŃŃƒŃ€ŃŃƒ. Đ’ĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ Ń–ĐœŃˆĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ Đ°Đ±ĐŸ заĐČĐ°ĐœŃ‚Đ°Đ¶Ń‚Đ” ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ, яĐșĐ” ĐŒĐŸĐ¶ĐœĐ° ĐŸĐ±Ń€Ń–Đ·Đ°Ń‚Đž." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "ЀаĐčĐ» {label} заĐČДлОĐșĐžĐč. Đ’ĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ фаĐčĐ», ĐŒĐ”ĐœŃˆĐžĐč за {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "Đ—ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ {label} ĐœĐ” ĐŒĐŸĐ¶ŃƒŃ‚ŃŒ Đ±ŃƒŃ‚Đž Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžĐŒĐž. ВоĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐčтД ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "ĐŸĐŸŃˆĐžŃ€Đ”ĐœĐœŃ Ń–ĐœŃ„ĐŸŃ€ĐŒĐ°Ń†Ń–Ń— ĐżŃ€ĐŸ аĐșтоĐČĐœŃ–ŃŃ‚ŃŒ" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "ĐŸĐŸŃ€Ń–Đł аĐșтоĐČĐœĐŸŃŃ‚Ń–" @@ -3566,11 +3561,11 @@ msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ĐžŃ‚Đž згаЎĐșĐž {everyoneMention} та {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ŃŒŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż ĐŽĐŸ ĐșĐ°ĐŒĐ”Ń€Đž ĐČ Â«{MACOS_SYSTEM_SETTINGS_NAME}» → «{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}» → «{MACOS_CAMERA_PERMISSION_NAME}»." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ŃŒŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż ĐŽĐŸ ĐŒŃ–ĐșŃ€ĐŸŃ„ĐŸĐœĐ° ĐČ Â«{MACOS_SYSTEM_SETTINGS_NAME}» → «{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}» → «{MACOS_MICROPHONE_PERMISSION_NAME}»." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ŃŒŃ‚Đ” {PRODUCT_NAME} ĐŽĐŸŃŃ‚ŃƒĐż ĐŽĐŸ ĐŒŃ–ĐșŃ€ĐŸŃ„ĐŸĐœĐ°. ĐŸĐ”Ń€Đ”ĐČіртД Đ°ĐŽŃ€Đ”ŃĐœĐžĐč Ń€ŃĐŽĐŸĐș Đ°Đ±ĐŸ ĐœĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ сĐČĐŸĐłĐŸ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ°." @@ -3673,7 +3668,7 @@ msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ĐžŃ‚Đž ŃƒŃ‡Đ°ŃĐœĐžĐșĐ°ĐŒ бДз ĐŽĐŸĐ·ĐČĐŸĐ»Ńƒ «{readMessa msgid "Allow mentions for this role" msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ĐžŃ‚Đž згаЎĐșĐž ĐŽĐ»Ń цієї Ń€ĐŸĐ»Ń–" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Đ”ĐŸĐ·ĐČĐŸĐ»ĐžŃ‚Đž ĐŒŃ–ĐșŃ€ĐŸŃ„ĐŸĐœ" @@ -3942,25 +3937,21 @@ msgstr "та щД {remainingCount}" msgid "Animate on interaction" msgstr "ĐĐœŃ–ĐŒŃƒĐČато піЮ час ĐČĐ·Đ°Ń”ĐŒĐŸĐŽŃ–Ń—" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– фаĐčлО {AVIF_FORMAT_LABEL} ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃŽŃ‚ŃŒŃŃ. Đ—Đ°ĐŒŃ–ŃŃ‚ŃŒ Ń†ŃŒĐŸĐłĐŸ заĐČĐ°ĐœŃ‚Đ°Đ¶Ń‚Đ” ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐžĐč фаĐčĐ» {AVIF_FORMAT_LABEL}." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžĐč {avifFormatLabel} ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃ”Ń‚ŃŒŃŃ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– аĐČатаро ({ANIMATED_AVATAR_FORMATS}) ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ– лОшД ĐŽĐ»Ń ĐżŃ–ĐŽĐżĐžŃĐœĐžĐșіĐČ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– аĐČатаро ({ANIMATED_AVATAR_FORMATS}) ĐœĐ”ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ– ĐČ Ń†ŃŒĐŸĐŒŃƒ Đ”ĐșĐ·Đ”ĐŒĐżĐ»ŃŃ€Ń–. Đ—Đ°ĐŒŃ–ŃŃ‚ŃŒ Ń†ŃŒĐŸĐłĐŸ заĐČĐ°ĐœŃ‚Đ°Đ¶Ń‚Đ” ŃŃ‚Đ°Ń‚ĐžŃ‡ĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "Đ”Đ»Ń Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… аĐČатаріĐČ ({animatedAvatarFormats}) ĐżĐŸŃ‚Ń€Ń–Đ±Đ”Đœ {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– аĐČатаро та Đ±Đ°ĐœĐ”Ń€Đž ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– аĐČатаро ĐœĐ”ĐŽĐŸŃŃ‚ŃƒĐżĐœŃ–" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "Đ”Đ»Ń Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… аĐČатаріĐČ ĐżĐŸŃ‚Ń€Ń–Đ±Đ”Đœ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ĐŸĐŸĐżĐ”Ń€Đ”ĐŽĐœŃ–Đč ĐżĐ”Ń€Đ”ĐłĐ»ŃĐŽ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐŸĐłĐŸ Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "ĐĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃŽŃ‚ŃŒŃŃ ĐŽĐ»Ń Ń†ŃŒĐŸĐłĐŸ Ń€Đ”ŃŃƒŃ€ŃŃƒ." @@ -4947,7 +4938,7 @@ msgstr "АĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡ĐœĐŸ ĐČĐžĐ·ĐœĐ°Ń‡Đ°Ń‚Đž ĐŒĐŸĐČу" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "АĐČŃ‚ĐŸĐŒĐ°Ń‚ĐžŃ‡ĐœĐŸ ĐČŃŃ‚Đ°ĐœĐŸĐČлюĐČато ĐżĐŸŃ€Ń–Đł аĐșтоĐČĐœĐŸŃŃ‚Ń–" @@ -5127,15 +5118,15 @@ msgstr "Đ”ĐŸŃŃ‚ŃƒĐżĐœĐŸ ĐČ ĐŽĐ”ŃĐșŃ‚ĐŸĐżĐœĐŸĐŒŃƒ Đ·Đ°ŃŃ‚ĐŸŃŃƒĐœĐșу." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "АĐČатар" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčĐ» аĐČатара заĐČДлОĐșĐžĐč. Đ’ĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ фаĐčĐ», Ń€ĐŸĐ·ĐŒŃ–Ń€ яĐșĐŸĐłĐŸ ĐŒĐ”ĐœŃˆĐžĐč за {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "АĐČатар заĐČДлОĐșĐžĐč — ĐČĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ ĐŒĐ”ĐœŃˆĐžĐč за {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "ВОбір Ń€Đ”Đ¶ĐžĐŒŃƒ аĐČатара" @@ -5187,11 +5178,11 @@ msgstr "Зараз ĐČŃ–ĐŽŃŃƒŃ‚ĐœŃ–Đč(-я)" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Đ—Đ°Đ±Đ»ĐŸĐșĐŸĐČĐ°ĐœŃ– ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČачі" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "Đ‘Đ°ĐœĐ”Ń€" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ЀаĐčĐ» Đ±Đ°ĐœĐ”Ń€Đ° заĐČДлОĐșĐžĐč. Đ’ĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ фаĐčĐ», ĐŒĐ”ĐœŃˆĐžĐč за {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "ВОбір Ń€Đ”Đ¶ĐžĐŒŃƒ Đ±Đ°ĐœĐ”Ń€Đ°" @@ -6107,8 +6098,8 @@ msgstr "ĐŸŃ€ĐžĐŽĐ±Đ°ĐčтД ĐżĐŸĐŽĐ°Ń€ŃƒĐœĐŸĐș {premiumProductName} ĐœĐ° ĐČĐșла msgid "Buy gift" msgstr "Купото ĐżĐŸĐŽĐ°Ń€ŃƒĐœĐŸĐș" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "СтĐČĐŸŃ€ŃŽŃŽŃ‡Đž ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ, ĐČĐž ĐżĐŸĐłĐŸĐŽĐ¶ŃƒŃ”Ń‚Đ”ŃŃ ĐŽĐŸŃ‚Ń€ĐžĐŒŃƒĐČатося <0>праĐČОл ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đž {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "СюЮо ĐœĐ” ĐŒĐŸĐ¶ĐœĐ° заĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž фаĐčлО" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ĐŸĐŸ Ń†Đ”ĐœŃ‚Ń€Ńƒ" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Đ—ĐŒŃ–ĐœĐžŃ‚Đž аĐČатар" @@ -6627,9 +6618,9 @@ msgstr "Đ—ĐŒŃ–ĐœĐžŃ‚Đž Ń„ĐŸĐœ" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Đ—ĐŒŃ–ĐœĐžŃ‚Đž Đ±Đ°ĐœĐ”Ń€" @@ -6668,13 +6659,13 @@ msgstr "Đ—ĐŒŃ–ĐœĐžŃ‚Đž псДĐČĐŽĐŸĐœŃ–ĐŒ у групі" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Đ—ĐŒŃ–ĐœĐžŃ‚Đž іĐșĐŸĐœĐșу" @@ -7669,8 +7660,8 @@ msgstr "ĐžŃ‚Ń€ĐžĐŒĐ°Ń‚Đž ĐżĐŸĐŽĐ°Ń€ŃƒĐœĐŸĐș" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "Đ—Đ°Ń€Đ”Ń”ŃŃ‚Ń€ŃƒĐčтД сĐČіĐč ĐŸĐ±Đ»Ń–ĐșĐŸĐČĐžĐč запОс" @@ -8518,8 +8509,8 @@ msgstr "ĐĄĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đ° спрояє цьĐșуĐČĐ°ĐœĐœŃŽ Đ°Đ±ĐŸ цілДспр msgid "Community filter" msgstr "Đ€Ń–Đ»ŃŒŃ‚Ń€ ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đž" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ІĐșĐŸĐœĐșа ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đž" @@ -8763,6 +8754,11 @@ msgstr "ĐšĐœĐŸĐżĐșĐž рДЎаĐșŃ‚ĐŸŃ€Đ°" msgid "Composer focus" msgstr "Đ€ĐŸĐșус ĐœĐ° ĐżĐŸĐ»Ń– ĐČĐČĐ”ĐŽĐ”ĐœĐœŃ" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "СтосĐșĐ°Ń”ĐŒĐŸ" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "ПіЮĐșĐ»ŃŽŃ‡Ń–Ń‚ŃŒ ĐșĐ°ĐŒĐ”Ń€Ńƒ Đ°Đ±ĐŸ ĐČŃ–Ń€Ń‚ŃƒĐ°Đ»ŃŒĐœĐžĐč прос msgid "Connect a display, then try again." msgstr "ПіЮĐșĐ»ŃŽŃ‡Ń–Ń‚ŃŒ ЎОсплДĐč, а ĐżĐŸŃ‚Ń–ĐŒ ŃĐżŃ€ĐŸĐ±ŃƒĐčтД щД раз." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "ПіЮĐșĐ»ŃŽŃ‡Ń–Ń‚ŃŒ ĐŒŃ–ĐșŃ€ĐŸŃ„ĐŸĐœ і ŃĐżŃ€ĐŸĐ±ŃƒĐčтД щД раз." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ стĐČĐŸŃ€ĐžŃ‚Đž цДĐč стіĐșДр" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ ĐŸĐ±Ń€Ń–Đ·Đ°Ń‚Đž Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ĐĐ°Ń€Đ°Đ·Ń– ĐœĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ ĐŸĐœĐŸĐČото ŃĐżŃ–Đ»ŃŒĐœĐžĐč ĐŽĐŸŃŃ‚ŃƒĐż ĐŽĐŸ ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸŃ— аĐșтоĐČĐœĐŸŃŃ‚Ń–" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ заĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž аĐČатар" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ заĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž Đ±Đ°ĐœĐ”Ń€" @@ -10230,7 +10226,7 @@ msgstr "СтĐČĐŸŃ€ĐžŃ‚Đž Đč ĐżĐŸĐŽŃ–Đ»ĐžŃ‚ĐžŃŃ" msgid "Create a community" msgstr "СтĐČĐŸŃ€ĐžŃ‚Đž ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "СтĐČĐŸŃ€Ń–Ń‚ŃŒ ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ ĐŽĐ»Ń спілĐșуĐČĐ°ĐœĐœŃ Đ· ĐŽŃ€ŃƒĐ·ŃĐŒĐž." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "ОбрізатО Ń„ĐŸĐœ Đ·Đ°ĐżŃ€ĐŸŃˆĐ”ĐœĐœŃ" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "ĐŸĐŸĐżĐ”Ń€Đ”ĐŽĐœŃ–Đč ĐżĐ”Ń€Đ”ĐłĐ»ŃĐŽ ĐŸĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ" @@ -10500,30 +10496,15 @@ msgstr "ОбрізатО Đ±Đ°ĐœĐ”Ń€ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ заĐČДлОĐșĐ”. Đ’ĐžĐ±Đ”Ń€Ń–Ń‚ŃŒ ĐŒĐ”ĐœŃˆŃƒ ĐŸĐ±Đ»Đ°ŃŃ‚ŃŒ Đ°Đ±ĐŸ ĐŒĐ”ĐœŃˆĐžĐč фаĐčĐ» (ĐŒĐ°Đșс. {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… фаĐčліĐČ Ń„ĐŸŃ€ĐŒĐ°Ń‚Ńƒ {formatLabel} ĐżĐŸĐșĐž Ń‰ĐŸ ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃ”Ń‚ŃŒŃŃ. Đ‘ŃƒĐŽĐ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°ĐœĐŸ ĐŸŃ€ĐžĐłŃ–ĐœĐ°Đ»ŃŒĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… фаĐčліĐČ Ń„ĐŸŃ€ĐŒĐ°Ń‚Ńƒ {formatLabel} ĐżĐŸĐșĐž Ń‰ĐŸ ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃ”Ń‚ŃŒŃŃ. Đ‘ŃƒĐŽĐ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°ĐœĐŸ ĐŸŃ€ĐžĐłŃ–ĐœĐ°Đ»ŃŒĐœĐžĐč фаĐčĐ»." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… фаĐčліĐČ ĐżĐŸĐșĐž Ń‰ĐŸ ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃ”Ń‚ŃŒŃŃ. Đ‘ŃƒĐŽĐ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°ĐœĐŸ ĐŸŃ€ĐžĐłŃ–ĐœĐ°Đ»ŃŒĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœĐžŃ… фаĐčліĐČ ĐżĐŸĐșĐž Ń‰ĐŸ ĐœĐ” ĐżŃ–ĐŽŃ‚Ń€ĐžĐŒŃƒŃ”Ń‚ŃŒŃŃ. Đ‘ŃƒĐŽĐ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°ĐœĐŸ ĐŸŃ€ĐžĐłŃ–ĐœĐ°Đ»ŃŒĐœĐžĐč фаĐčĐ»." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "ĐžĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "ĐĐ” ĐŒĐ°Ń”Ń‚Đ” ĐŸĐ±Đ»Ń–ĐșĐŸĐČĐŸĐłĐŸ запОсу?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "ĐĐ” ĐżĐŸĐșазуĐČато" @@ -16560,8 +16541,8 @@ msgstr "АĐČатаро ĐłŃ€ŃƒĐżĐŸĐČох чатіĐČ ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČують msgid "Group DMs" msgstr "Đ“Ń€ŃƒĐżĐŸĐČі чато" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "ІĐșĐŸĐœĐșа групо" @@ -16624,8 +16605,8 @@ msgstr "ĐĐ°Đ»Đ°ŃˆŃ‚ŃƒĐČĐ°ĐœĐœŃ групо" msgid "Group typing states" msgstr "ĐĄŃ‚Đ°ĐœĐž ĐœĐ°Đ±ĐŸŃ€Ńƒ ĐČ ĐłŃ€ŃƒĐżŃ–" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Групу ĐŸĐœĐŸĐČĐ»Đ”ĐœĐŸ" @@ -16803,7 +16784,7 @@ msgstr "ХДрцД" msgid "Hebrew" msgstr "ІĐČрот" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Đ’ĐžŃĐŸŃ‚Đ°" @@ -17510,7 +17491,7 @@ msgstr "Đ—ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ сĐșĐŸĐżŃ–ĐčĐŸĐČĐ°ĐœĐŸ ĐČ Đ±ŃƒŃ„Đ”Ń€ ĐŸĐ±ĐŒŃ–ĐœŃƒ" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ ĐČĐžĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚Đž Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Đ—ĐŸĐČĐœŃ–ŃˆĐœŃ–Đč ĐČĐžĐłĐ»ŃĐŽ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "ĐĄŃ…ĐŸĐ¶Đ”, ĐČĐž ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČŃƒŃ”Ń‚Đ” {0}. НаĐșĐ»Đ°ĐŽĐ°ĐœĐœŃ ĐŸĐ±Ń€ĐŸĐ±ĐșĐž {PRODUCT_NAME} ĐŒĐŸĐ¶Đ” ŃĐżŃ€ĐžŃ‡ĐžĐœĐžŃ‚Đž ĐœĐ°ĐșачуĐČĐ°ĐœĐœŃ Đ°Đ±ĐŸ ŃĐżĐŸŃ‚ĐČĐŸŃ€Đ”ĐœĐœŃ. ĐŸŃ€ŃĐŒĐžĐč ĐČхіЮ пДрДЎає ĐČаш Đ·ĐČуĐș бДз Đ·ĐŒŃ–Đœ." @@ -22577,7 +22558,7 @@ msgstr "ĐŃ–Ń‡ĐŸĐłĐŸ ĐœĐ” Đ·ĐœĐ°ĐčĐŽĐ”ĐœĐŸ" msgid "No mentions yet" msgstr "Đ—ĐłĐ°ĐŽĐŸĐș ĐżĐŸĐșĐž ĐœĐ”ĐŒĐ°Ń”" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "МіĐșŃ€ĐŸŃ„ĐŸĐœ ĐœĐ” Đ·ĐœĐ°ĐčĐŽĐ”ĐœĐŸ" @@ -23806,7 +23787,7 @@ msgstr "ВіЮĐșрото ŃĐžŃŃ‚Đ”ĐŒĐœĐžĐč проĐČĐ°Ń‚ĐœĐžĐč чат" msgid "Open system picker" msgstr "ВіЮĐșрото ŃĐžŃŃ‚Đ”ĐŒĐœĐ” ĐČіĐșĐœĐŸ ĐČĐžĐ±ĐŸŃ€Ńƒ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "ВіЮĐșрото JSON ŃˆĐ°Đ±Đ»ĐŸĐœŃƒ" @@ -23820,7 +23801,7 @@ msgstr "ВіЮĐșрото ĐŽŃ–Đ°Đ»ĐŸĐł Đ±Đ»ĐŸĐșуĐČĐ°ĐœĐœŃ ĐŽĐ»Ń цієї сп msgid "Open the context menu" msgstr "ВіЮĐșрото ĐșĐŸĐœŃ‚Đ”ĐșŃŃ‚ĐœĐ” ĐŒĐ”ĐœŃŽ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "ВіЮĐșроĐčтД ĐżĐŸŃĐžĐ»Đ°ĐœĐœŃ ĐœĐžĐ¶Ń‡Đ” у сĐČĐŸŃ”ĐŒŃƒ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Ń–, ĐżĐŸŃ‚Ń–ĐŒ сĐșĐŸĐżŃ–ŃŽĐčтД ĐČсю ĐČŃ–ĐŽĐżĐŸĐČіЮь JSON і ĐČстаĐČтД її ĐČ ĐżĐŸĐ»Đ”." @@ -24331,7 +24312,7 @@ msgstr "ĐžŃŃ‚Đ°ĐœĐœŃ– 7 ĐŽĐœŃ–ĐČ" msgid "Paste" msgstr "ВстаĐČото" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "ВстаĐČтД URL ŃˆĐ°Đ±Đ»ĐŸĐœŃƒ {theOtherPlatform}, Ń‰ĐŸĐ± Ń–ĐŒĐżĐŸŃ€Ń‚ŃƒĐČато ĐčĐŸĐłĐŸ струĐșтуру ĐČ ĐœĐŸĐČу ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ." @@ -25191,6 +25172,11 @@ msgstr "йОп ĐżŃ€Đ”ĐŒŃ–ŃƒĐŒŃƒ" msgid "Premium until date" msgstr "Дата заĐČĐ”Ń€ŃˆĐ”ĐœĐœŃ ĐżŃ€Đ”ĐŒŃ–ŃƒĐŒŃƒ" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "ĐŸŃ–ĐŽĐłĐŸŃ‚ĐŸĐČĐșа" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "ĐŸŃ€ĐŸŃ„Ń–Đ»ŃŒ" msgid "Profile badge" msgstr "Đ—ĐœĐ°Ń‡ĐŸĐș ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "Đ‘Đ°ĐœĐ”Ń€Đž ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ — цД Ń„ŃƒĐœĐșція {PREMIUM_PRODUCT_NAME}. ĐžŃ‚Ń€ĐžĐŒĐ°ĐčтД {PREMIUM_PRODUCT_NAME}, Ń‰ĐŸĐ± ĐŽĐŸĐŽĐ°Ń‚Đž Đ±Đ°ĐœĐ”Ń€ ĐŽĐŸ сĐČĐŸĐłĐŸ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "Đ‘Đ°ĐœĐ”Ń€Đž ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ ĐœĐ° Ń†ŃŒĐŸĐŒŃƒ Đ”ĐșĐ·Đ”ĐŒĐżĐ»ŃŃ€Ń–." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "Đ”Đ»Ń Đ±Đ°ĐœĐ”Ń€Ń–ĐČ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ ĐżĐŸŃ‚Ń€Ń–Đ±Đ”Đœ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "Đ”Đ»Ń Đ±Đ°ĐœĐ”Ń€Ń–ĐČ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ ĐżĐŸŃ‚Ń€Ń–Đ±Đ”Đœ {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "ĐĐ°Ń‚ĐžŃĐœĐž і ĐłĐŸĐČĐŸŃ€Đž" msgid "Push-to-talk (limited)" msgstr "ĐĐ°Ń‚ĐžŃĐœĐž і ĐłĐŸĐČĐŸŃ€Đž (ĐŸĐ±ĐŒĐ”Đ¶Đ”ĐœĐŸ)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Đ Đ”Đ¶ĐžĐŒ Â«ĐĐ°Ń‚ĐžŃĐœĐž і ĐłĐŸĐČĐŸŃ€ĐžÂ» ĐœĐ” Юіє, ĐșĐŸĐ»Đž ĐČĐžĐ±Ń€Đ°ĐœĐŸ ĐŸĐ±Ń€ĐŸĐ±Đșу ĐłĐŸĐ»ĐŸŃŃƒ Â«ĐŸŃ€ŃĐŒĐžĐč ĐČхіЎ». ĐŸĐ”Ń€Đ”ĐčЮіть ĐœĐ° «ЧітĐșĐžĐč ĐłĐŸĐ»ĐŸŃÂ» Đ°Đ±ĐŸ Â«Đ’Đ»Đ°ŃĐœĐ°Â», Ń‰ĐŸĐ± сĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚ĐžŃŃ ĐœĐžĐŒ." @@ -26551,8 +26537,8 @@ msgstr "ВОЎалОтО ĐČĐșĐ»Đ°ĐŽĐ”ĐœĐœŃ" msgid "Remove authenticator app" msgstr "ВОЎалОтО Đ·Đ°ŃŃ‚ĐŸŃŃƒĐœĐŸĐș аĐČŃ‚Đ”ĐœŃ‚ĐžŃ„Ń–Đșації" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ВОЎалОтО аĐČатар" @@ -26561,8 +26547,8 @@ msgstr "ВОЎалОтО аĐČатар" msgid "Remove background" msgstr "ВОЎалОтО Ń„ĐŸĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "ВОЎалОтО Đ±Đ°ĐœĐ”Ń€" @@ -26625,10 +26611,10 @@ msgstr "Đ—ĐœŃŃ‚Đž заĐșŃ€Ń–ĐżĐ»Đ”ĐœĐœŃ" msgid "Remove from URL-only GIF favorites" msgstr "ВОЎалОтО Đ· ĐČĐžĐ±Ń€Đ°ĐœĐžŃ… GIF за URL-Đ°ĐŽŃ€Đ”ŃĐŸŃŽ" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ВОЎалОтО іĐșĐŸĐœĐșу" @@ -27331,7 +27317,7 @@ msgstr "ĐĐ°ĐŽŃ–ŃĐ»Đ°ĐœĐŸ ĐżĐŸĐČŃ‚ĐŸŃ€ĐœĐŸ" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "ĐĄĐșĐžĐœŃƒŃ‚Đž" @@ -28074,7 +28060,7 @@ msgstr "Đ ŃƒĐŒŃƒĐœŃŃŒĐșа" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "ĐŸĐŸĐČĐ”Ń€ĐœŃƒŃ‚Đž за ĐłĐŸĐŽĐžĐœĐœĐžĐșĐŸĐČĐŸŃŽ стрілĐșĐŸŃŽ" @@ -28153,8 +28139,8 @@ msgstr "ĐĐ°ŃĐžŃ‡Đ”ĐœŃ–ŃŃ‚ŃŒ" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ĐšĐ”Ń€ŃƒĐČĐ°ĐœĐœŃ ĐșĐŸĐŽŃƒĐČĐ°Đ»ŃŒĐœĐžĐșĐŸĐŒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–Ń— Đ”ĐșŃ€Đ°ĐœĐ°" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Đ”Đ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ Đ”ĐșŃ€Đ°ĐœĐ° заĐČĐ”Ń€ŃˆĐ”ĐœĐŸ" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "ĐŸĐŸĐșазуĐČато чДрĐČĐŸĐœĐžĐč Đ·ĐœĐ°Ń‡ĐŸĐș ĐœĐ° іĐșĐŸĐœŃ†Ń– Đ·Đ°ŃŃ‚ĐŸŃŃƒĐœĐșу, ĐșĐŸĐ»Đž є ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœŃ– ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "ĐŸĐŸĐșазуĐČато лОшД аĐșŃ†Đ”ĐœŃ‚ĐœĐžĐč ĐșĐŸĐ»Ń–Ń€, Ń–ĐłĐœĐŸŃ€ŃƒŃŽŃ‡Đž ĐČаш ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐžĐč ĐżŃ€ĐŸŃ„Ń–Đ»ŃŒ" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "ĐŸĐŸĐșазуĐČато ĐČĐ»Đ°ŃĐœŃ– Đ”ĐŒĐŸĐŽĐ¶Ń– ĐČ Đ°ĐČŃ‚ĐŸĐ·Đ°ĐżĐŸĐČĐœĐ”ĐœĐœŃ– ĐČОразіĐČ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "ĐŸĐŸĐșазуĐČато Ń‚ĐžĐżĐŸĐČĐžĐč аĐČатар, Ń–ĐłĐœĐŸŃ€ŃƒŃŽŃ‡Đž ĐČаш ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐžĐč ĐżŃ€ĐŸŃ„Ń–Đ»ŃŒ" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "ĐŸĐŸĐșазуĐČато Ń–ĐœĐŽĐžĐșĐ°Ń‚ĐŸŃ€ ĐœĐ”ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœĐžŃ… ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœŃŒ ĐœĐ° ĐșĐ°ĐœĐ°Đ»Đ°Ń… Ń–Đ· ĐČĐžĐŒĐșĐœĐ”ĐœĐžĐŒĐž ŃĐżĐŸĐČŃ–Ń‰Đ”ĐœĐœŃĐŒĐž" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ĐŸĐŸĐșазуĐČато аĐČатар ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐŸĐłĐŸ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ ĐČ Ń†Ń–Đč ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ń–" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ĐŸĐŸĐșазуĐČато Đ±Đ°ĐœĐ”Ń€ ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐŸĐłĐŸ ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ ĐČ Ń†Ń–Đč ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ń–" @@ -30720,7 +30706,7 @@ msgstr "ĐŸŃ€ĐŸĐżŃƒŃŃ‚ĐžŃ‚Đž" msgid "Skip \"Mark all as read\" confirmation" msgstr "ĐŸŃ€ĐŸĐżŃƒŃĐșато піЮтĐČĐ”Ń€ĐŽĐ¶Đ”ĐœĐœŃ Â«ĐŸĐŸĐ·ĐœĐ°Ń‡ĐžŃ‚Đž ĐČсі яĐș ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°ĐœŃ–Â»" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "ĐŸŃ€ĐŸĐżŃƒŃŃ‚ĐžŃ‚Đž ĐŸĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ" @@ -32346,7 +32332,7 @@ msgstr "ĐŸĐ”Ń€Đ”Đčто ĐŽĐŸ Đ·Ń€ŃƒŃ‡ĐœĐŸĐłĐŸ ĐČĐžĐłĐ»ŃĐŽŃƒ" msgid "Switch to dense layout" msgstr "ĐŸĐ”Ń€Đ”Đčто ĐŽĐŸ Ń‰Ń–Đ»ŃŒĐœĐŸĐłĐŸ ĐČĐžĐłĐ»ŃĐŽŃƒ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ĐŸĐ”Ń€Đ”Đčто ĐœĐ° ĐżŃ€ŃĐŒĐžĐč ĐČхіЮ" @@ -32734,7 +32720,7 @@ msgstr "ЗаĐČĐŽĐ°ĐœĐœŃ" msgid "Teleporting you to another voice region..." msgstr "ĐŸĐ”Ń€Đ”ĐŒŃ–Ń‰ŃƒŃ”ĐŒĐŸ ĐČас ĐŽĐŸ Ń–ĐœŃˆĐŸĐłĐŸ ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐłĐŸ Ń€Đ”ĐłŃ–ĐŸĐœŃƒ..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "ĐšĐ°Đ±Đ»ĐŸĐœ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Đ ĐŸĐ»ŃŒ ĐœĐ°ĐŽĐ°ĐČала {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Đ”Đ¶Đ”Ń€Đ”Đ»ĐŸ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–Ń— Đ”ĐșŃ€Đ°ĐœĐ° ĐżŃ€ĐžĐżĐžĐœĐžĐ»ĐŸ ĐœĐ°ĐŽŃĐžĐ»Đ°Ń‚Đž ĐČŃ–ĐŽĐ”ĐŸ, Ń‚ĐŸĐŒŃƒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ ĐČĐ°ŃˆĐŸĐłĐŸ Đ”ĐșŃ€Đ°ĐœĐ° Đ·ŃƒĐżĐžĐœĐ”ĐœĐŸ." @@ -33453,6 +33439,11 @@ msgstr "ĐŠĐ”Đč ĐŸĐ±Đ»Ń–ĐșĐŸĐČĐžĐč запОс ĐœĐ” ĐŒĐŸĐ¶ĐœĐ° Đ·Đ°Đ±Đ»ĐŸĐșуĐČа msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Щю Юію ĐœĐ” ĐŒĐŸĐ¶ĐœĐ° сĐșасуĐČато. Усі ĐżĐŸĐČ'ŃĐ·Đ°ĐœŃ– ĐŽĐ°ĐœŃ–, ĐČĐșĐ»ŃŽŃ‡ĐœĐŸ Đ· ĐșĐŸŃ€ĐžŃŃ‚ŃƒĐČĐ°Ń‡Đ”ĐŒ-Đ±ĐŸŃ‚ĐŸĐŒ, буЎД ĐČĐžĐŽĐ°Đ»Đ”ĐœĐŸ ĐœĐ°Đ·Đ°ĐČжЎО." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "Щя Đ°ĐœŃ–ĐŒĐ°Ń†Ń–Ń Đ·Đ°ĐœĐ°ĐŽŃ‚ĐŸ ĐŽĐŸĐČга Đ°Đ±ĐŸ Đ·Đ°ĐœĐ°ĐŽŃ‚ĐŸ ĐČДлОĐșа ĐŽĐ»Ń ĐŸĐ±Ń€Ń–Đ·Đ°ĐœĐœŃ. ĐĄĐżŃ€ĐŸĐ±ŃƒĐčтД ĐșĐŸŃ€ĐŸŃ‚ŃˆĐžĐč Đ°Đ±ĐŸ ĐŒĐ”ĐœŃˆĐžĐč фаĐčĐ»." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "ĐŠĐ”Đč Đ±ĐŸŃ‚ ĐœĐ” є ĐżŃƒĐ±Đ»Ń–Ń‡ĐœĐžĐŒ, і ĐčĐŸĐłĐŸ ĐœĐ” ĐŒĐŸĐ¶ŃƒŃ‚ŃŒ msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "ĐŠĐ”Đč Đ±ĐŸŃ‚ Đ·Đ°ĐżĐžŃ‚ŃƒŃ” ĐŽĐŸĐ·ĐČŃ–Đ» Đ°ĐŽĐŒŃ–ĐœŃ–ŃŃ‚Ń€Đ°Ń‚ĐŸŃ€Đ°. НаЮаĐČаĐčтД ĐčĐŸĐłĐŸ, лОшД яĐșŃ‰ĐŸ ĐČĐž ĐżĐŸĐČĐœŃ–ŃŃ‚ŃŽ ĐŽĐŸĐČŃ–Ń€ŃŃ”Ń‚Đ” Ń€ĐŸĐ·Ń€ĐŸĐ±ĐœĐžĐșу. ĐĐ°Ń‚ĐŸĐŒŃ–ŃŃ‚ŃŒ ĐżĐŸĐżŃ€ĐŸŃŃ–Ń‚ŃŒ ĐčĐŸĐłĐŸ Đ·Đ°ĐżĐžŃ‚ŃƒĐČато ĐŒĐ”ĐœŃˆĐ” ĐŽĐŸĐ·ĐČĐŸĐ»Ń–ĐČ. ЗаĐșроĐčтД цю ŃŃ‚ĐŸŃ€Ń–ĐœĐșу, яĐșŃ‰ĐŸ ĐœĐ” ĐČпДĐČĐœĐ”ĐœŃ–." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "ĐŠĐ”Đč Đ±Ń€Đ°ŃƒĐ·Đ”Ń€ ĐœĐ” ĐŒĐŸĐ¶Đ” ĐŸĐ±Ń€Ń–Đ·Đ°Ń‚Đž Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– фаĐčлО {avifFormatLabel}. ĐĐ°Ń‚ĐŸĐŒŃ–ŃŃ‚ŃŒ заĐČĐ°ĐœŃ‚Đ°Đ¶Ń‚Đ” GIF Đ°Đ±ĐŸ WebP." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "ĐšĐŸĐœŃĐŸĐ»ŃŒ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Đ° — цД Ń–ĐœŃŃ‚Ń€ŃƒĐŒĐ”ĐœŃ‚ Ń€ĐŸĐ·Ń€ĐŸĐ±ĐœĐžĐșа." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "ĐŁ Ń†ŃŒĐŸĐŒŃƒ Đ±Ń€Đ°ŃƒĐ·Đ”Ń€Ń– ĐČĐžĐŒĐșĐœĐ”ĐœĐŸ WebAssembly, Ń‚ĐŸĐŒŃƒ Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ ĐœĐ” ĐŒĐŸĐ¶ĐœĐ° ĐŸĐ±Ń€Ń–Đ·Đ°Ń‚Đž." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "Щя група Đ·Đ°ĐżĐŸĐČĐœĐ”ĐœĐ°. Đ’ĐžĐŽĐ°Đ»Ń–Ń‚ŃŒ ĐșĐŸĐłĐŸŃŃŒ, пД msgid "This handoff code has expired. Generate a new one to continue." msgstr "ĐąĐ”Ń€ĐŒŃ–Đœ Юії Ń†ŃŒĐŸĐłĐŸ ĐșĐŸĐŽŃƒ пДрДЎачі заĐșŃ–ĐœŃ‡ĐžĐČся. СтĐČĐŸŃ€Ń–Ń‚ŃŒ ĐœĐŸĐČĐžĐč, Ń‰ĐŸĐ± ĐżŃ€ĐŸĐŽĐŸĐČжОтО." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ ĐżŃ€ĐŸŃ‡ĐžŃ‚Đ°Ń‚Đž цД Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ. ĐœĐŸĐ¶Đ»ĐžĐČĐŸ, ĐČĐŸĐœĐŸ ĐżĐŸŃˆĐșĐŸĐŽĐ¶Đ”ĐœĐ”." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž ĐČĐ»Đ°ŃĐœĐžĐč аĐČатар ĐŽĐ»Ń цієї ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đž" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž ĐČĐ»Đ°ŃĐœĐžĐč Đ±Đ°ĐœĐ”Ń€ ĐŽĐ»Ń цієї ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Đž" @@ -36155,10 +36163,10 @@ msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ŃƒĐČато фаĐčлО та ĐŒĐ”ĐŽŃ–Đ° ĐČ ĐżĐŸĐČŃ–ĐŽĐŸĐŒ msgid "Upload files and media in this channel." msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ŃƒĐČато фаĐčлО та ĐŒĐ”ĐŽŃ–Đ° ĐČ Ń†ŃŒĐŸĐŒŃƒ ĐșĐ°ĐœĐ°Đ»Ń–." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "ЗаĐČĐ°ĐœŃ‚Đ°Đ¶ĐžŃ‚Đž іĐșĐŸĐœĐșу" @@ -36401,8 +36409,8 @@ msgstr "ВоĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато ĐČŃƒĐłŃ–Đ»ŃŒĐœŃƒ Ń‚Đ”ĐŒŃƒ (Đ°Đ±ŃĐŸĐ»ŃŽŃ‚ #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "ВоĐșĐŸŃ€ĐžŃŃ‚Đ°Ń‚Đž ĐČĐ»Đ°ŃĐœĐ” Đ·ĐŸĐ±Ń€Đ°Đ¶Đ”ĐœĐœŃ" @@ -36462,8 +36470,8 @@ msgstr "ВоĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐčтД Ń„Ń–Đ»ŃŒŃ‚Ń€Đž Đ°Đ±ĐŸ ĐČĐČĐŸĐŽŃŒŃ‚Đ” Đșлю #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "ВоĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато ĐłĐ»ĐŸĐ±Đ°Đ»ŃŒĐœĐžĐč ĐżŃ€ĐŸŃ„Ń–Đ»ŃŒ" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "ĐŁŃ‡Đ°ŃĐœĐžĐșĐž ĐłĐŸĐ»ĐŸŃĐŸĐČĐŸĐłĐŸ чату" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "ĐžĐ±Ń€ĐŸĐ±Đșа ĐłĐŸĐ»ĐŸŃŃƒ" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ВісĐșĐŸĐœŃĐžĐœ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "ЗаĐČЮяĐșĐž {PREMIUM_PRODUCT_NAME} ĐČĐž ĐŒĐŸĐ¶Đ”Ń‚Đ” ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато Đ°ĐœŃ–ĐŒĐŸĐČĐ°ĐœŃ– аĐČатаро ({ANIMATED_AVATAR_FORMATS}) та Đ±Đ°ĐœĐ”Ń€Đž ĐżŃ€ĐŸŃ„Ń–Đ»ŃŽ, ĐœĐ°Đ»Đ°ŃˆŃ‚ĐŸĐČуĐČато сĐČіĐč тДг і ĐŸŃ‚Ń€ĐžĐŒŃƒĐČато Đ±Đ°ĐłĐ°Ń‚ĐŸ Ń–ĐœŃˆĐžŃ… пДрДĐČаг {PREMIUM_PRODUCT_NAME}." @@ -39334,8 +39342,8 @@ msgstr "Đ©ĐŸĐ± ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато тут Đ”ĐŒĐŸĐŽĐ·Ń– Đ· Ń–ĐœŃˆĐžŃ… msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "Đ©ĐŸĐ± ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČуĐČато тут стіĐșДрО Đ· Ń–ĐœŃˆĐžŃ… ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚, ĐČĐ°ĐŒ ĐżĐŸŃ‚Ń€Ń–Đ±Đ”Đœ ĐŽĐŸĐ·ĐČŃ–Đ» «{permissionLabel}»." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "Đ©ĐŸĐ± стĐČĐŸŃ€ĐžŃ‚Đž ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ, ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ Đ·Đ°Ń€Đ”Ń”ŃŃ‚Ń€ŃƒĐČато сĐČіĐč ĐŸĐ±Đ»Ń–ĐșĐŸĐČĐžĐč запОс." @@ -39356,8 +39364,8 @@ msgstr "Đ©ĐŸĐ± ĐœĐ°ĐŽŃĐžĐ»Đ°Ń‚Đž ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ ĐČ Ń†Ń–Đč ŃĐżŃ–Đ»ŃŒ msgid "You need to verify a phone number to send messages in this community." msgstr "Đ©ĐŸĐ± ĐœĐ°ĐŽŃĐžĐ»Đ°Ń‚Đž ĐżĐŸĐČŃ–ĐŽĐŸĐŒĐ»Đ”ĐœĐœŃ ĐČ Ń†Ń–Đč ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ń–, ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ піЮтĐČДрЎОтО ĐœĐŸĐŒĐ”Ń€ Ń‚Đ”Đ»Đ”Ń„ĐŸĐœŃƒ." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "Đ©ĐŸĐ± стĐČĐŸŃ€ĐžŃ‚Đž ŃĐżŃ–Đ»ŃŒĐœĐŸŃ‚Ńƒ, ĐżĐŸŃ‚Ń€Ń–Đ±ĐœĐŸ піЮтĐČДрЎОтО сĐČĐŸŃŽ ДлДĐșŃ‚Ń€ĐŸĐœĐœŃƒ Đ°ĐŽŃ€Đ”ŃŃƒ." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Ваша Đ·Đ±Đ”Ń€Đ”Đ¶Đ”ĐœĐ° яĐșість {savedResolution} Ń–Đ· Ń‡Đ°ŃŃ‚ĐŸŃ‚ĐŸŃŽ {savedFrameRate} ĐșаЮріĐČ ĐœĐ° сДĐșŃƒĐœĐŽŃƒ ĐżĐŸŃ‚Ń€Đ”Đ±ŃƒŃ” {premiumProductName}, Ń‚ĐŸĐŒŃƒ ŃĐżŃ–Đ»ŃŒĐœĐžĐč ĐŽĐŸŃŃ‚ŃƒĐż ĐČĐžĐșĐŸŃ€ĐžŃŃ‚ĐŸĐČує {resolution} Ń–Đ· Ń‡Đ°ŃŃ‚ĐŸŃ‚ĐŸŃŽ {frameRate} ĐșаЮріĐČ ĐœĐ° сДĐșŃƒĐœĐŽŃƒ." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ĐĐ” ĐČĐŽĐ°Đ»ĐŸŃŃ ĐŸĐżŃƒĐ±Đ»Ń–ĐșуĐČато ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ Đ”ĐșŃ€Đ°ĐœĐ° Đ· ŃŃƒĐŒŃ–ŃĐœĐžĐŒ ĐČŃ–ĐŽĐ”ĐŸĐșĐŸĐŽĐ”ĐșĐŸĐŒ, Ń‚ĐŸĐŒŃƒ її Đ·ŃƒĐżĐžĐœĐ”ĐœĐŸ. ĐĄĐżŃ€ĐŸĐ±ŃƒĐčтД ĐżĐŸŃ‡Đ°Ń‚Đž ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ Đ·ĐœĐŸĐČу." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "Вашу ĐżĐ”Ń€ŃĐŸĐœĐ°Đ»Ń–Đ·ĐŸĐČĐ°ĐœŃƒ URL-Đ°ĐŽŃ€Đ”ŃŃƒ ĐČŃŃ‚Đ°ĐœĐŸĐČĐ»Đ”ĐœĐŸ ĐœĐ° {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Ваш ĐČŃ–ĐŽĐ”ĐŸĐșĐŸĐŽĐ”Ń€ пДрДстаĐČ ĐșĐŸĐŽŃƒĐČато ĐșаЮро, Ń‚ĐŸĐŒŃƒ ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ Đ”ĐșŃ€Đ°ĐœĐ° Đ·ŃƒĐżĐžĐœĐ”ĐœĐŸ. ĐĄĐżŃ€ĐŸĐ±ŃƒĐčтД ĐżĐŸŃ‡Đ°Ń‚Đž ĐŽĐ”ĐŒĐŸĐœŃŃ‚Ń€Đ°Ń†Ń–ŃŽ Đ·ĐœĐŸĐČу." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "ĐœĐ°ŃŃˆŃ‚Đ°Đ±" diff --git a/fluxer_app/src/features/i18n/locales/vi/messages.po b/fluxer_app/src/features/i18n/locales/vi/messages.po index 683ac9d2f..78477e496 100644 --- a/fluxer_app/src/features/i18n/locales/vi/messages.po +++ b/fluxer_app/src/features/i18n/locales/vi/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}, sáșŻp ra máșŻt" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "KĂ­ch thước cá»§a {label} khĂŽng khớp với tĂ i nguyĂȘn nĂ y. Chọn hĂŹnh áșŁnh khĂĄc hoáș·c táșŁi lĂȘn hĂŹnh áșŁnh tÄ©nh mĂ  báșĄn cĂł thể cáșŻt." - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "Tệp {label} quĂĄ lớn. Vui lĂČng chọn tệp nhỏ hÆĄn {maxSizeLabel}." #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "KhĂŽng thể sá»­ dỄng áșŁnh động cho {label}. Vui lĂČng sá»­ dỄng áșŁnh tÄ©nh." @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "Chia sáș» hoáșĄt động" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "NgÆ°á»Ąng hoáșĄt động" @@ -3566,11 +3561,11 @@ msgstr "Cho phĂ©p {everyoneMention} vĂ  {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "Cho phĂ©p {PRODUCT_NAME} truy cáș­p camera cá»§a báșĄn trong {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "Cho phĂ©p {PRODUCT_NAME} truy cáș­p micrĂŽ cá»§a báșĄn trong {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "Cho phĂ©p {PRODUCT_NAME} truy cáș­p micrĂŽ cá»§a báșĄn. Kiểm tra thanh địa chỉ hoáș·c cĂ i đáș·t trĂŹnh duyệt cá»§a báșĄn." @@ -3673,7 +3668,7 @@ msgstr "Cho phĂ©p thĂ nh viĂȘn khĂŽng cĂł quyền {readMessageHistoryPermissionL msgid "Allow mentions for this role" msgstr "Cho phĂ©p nháșŻc đáșżn vai trĂČ nĂ y" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "Cho phĂ©p truy cáș­p micro" @@ -3942,25 +3937,21 @@ msgstr "vĂ  {remainingCount} cộng đồng khĂĄc" msgid "Animate on interaction" msgstr "PhĂĄt áșŁnh động khi tÆ°ÆĄng tĂĄc" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "KhĂŽng hỗ trợ tệp {AVIF_FORMAT_LABEL} động. Vui lĂČng táșŁi lĂȘn tệp {AVIF_FORMAT_LABEL} tÄ©nh thay tháșż." - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "KhĂŽng hỗ trợ {avifFormatLabel} động" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "áșąnh đáșĄi diện động ({ANIMATED_AVATAR_FORMATS}) chỉ dĂ nh riĂȘng cho người đăng kĂœ {PREMIUM_PRODUCT_NAME}." -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "áșąnh đáșĄi diện động ({ANIMATED_AVATAR_FORMATS}) khĂŽng kháșŁ dỄng trĂȘn mĂĄy chá»§ nĂ y. Vui lĂČng táșŁi lĂȘn áșŁnh tÄ©nh." #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "áșąnh đáșĄi diện động ({animatedAvatarFormats}) yĂȘu cáș§u {premiumProductName}." @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "áșąnh đáșĄi diện & áșŁnh bĂŹa động" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "áșąnh đáșĄi diện động khĂŽng kháșŁ dỄng" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "áșąnh đáșĄi diện động yĂȘu cáș§u {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "Xem trước áșŁnh động" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "áșąnh động khĂŽng Ä‘Æ°á»Łc hỗ trợ cho nội dung nĂ y." @@ -4947,7 +4938,7 @@ msgstr "Tá»± động phĂĄt hiện ngĂŽn ngữ" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "Tá»± động đáș·t ngÆ°á»Ąng hoáșĄt động" @@ -5127,15 +5118,15 @@ msgstr "CĂł sáș”n trong ứng dỄng dĂ nh cho mĂĄy tĂ­nh." #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "áșąnh đáșĄi diện" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Tệp áșŁnh đáșĄi diện quĂĄ lớn. Vui lĂČng chọn tệp nhỏ hÆĄn {imageMaxSizeLabel}." @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "áșąnh đáșĄi diện quĂĄ lớn. HĂŁy chọn áșŁnh cĂł kĂ­ch thước dưới {imageMaxSizeLabel}." #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "Chọn cháșż độ áșŁnh đáșĄi diện" @@ -5187,11 +5178,11 @@ msgstr "Đang váșŻng máș·t" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "Người dĂčng bị cáș„m" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "áșąnh bĂŹa" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "Tệp áșŁnh bĂŹa quĂĄ lớn. Vui lĂČng chọn tệp nhỏ hÆĄn {imageMaxSizeLabel}." #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "Chọn cháșż độ áșŁnh bĂŹa" @@ -6107,8 +6098,8 @@ msgstr "Mua quĂ  {premiumProductName} từ tab {premiumProductName} để chia s msgid "Buy gift" msgstr "Mua quĂ  táș·ng" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "Báș±ng cĂĄch táșĄo cộng đồng, báșĄn đồng Ăœ tuĂąn thá»§ vĂ  duy trĂŹ <0>nguyĂȘn táșŻc cộng đồng {PRODUCT_NAME}." @@ -6361,7 +6352,7 @@ msgstr "KhĂŽng thể táșŁi tệp lĂȘn ở đñy" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "Căn giữa" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "Đổi áșŁnh đáșĄi diện" @@ -6627,9 +6618,9 @@ msgstr "Đổi hĂŹnh nền" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "Đổi áșŁnh bĂŹa" @@ -6668,13 +6659,13 @@ msgstr "Đổi biệt danh nhĂłm" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "Đổi biểu tÆ°á»Łng" @@ -7669,8 +7660,8 @@ msgstr "Nháș­n quĂ " #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "XĂĄc nháș­n tĂ i khoáșŁn" @@ -8518,8 +8509,8 @@ msgstr "Cộng đồng táșĄo điều kiện cho hĂ nh vi cĂŽng kĂ­ch táș­p thể msgid "Community filter" msgstr "Bộ lọc cộng đồng" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "Biểu tÆ°á»Łng cộng đồng" @@ -8763,6 +8754,11 @@ msgstr "NĂșt soáșĄn tin" msgid "Composer focus" msgstr "Táș­p trung vĂ o trĂŹnh soáșĄn tháșŁo" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "Đang nĂ©n" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "Káșżt nối camera hoáș·c thiáșżt bị ghi hĂŹnh áșŁo, rồi thá»­ láșĄi msgid "Connect a display, then try again." msgstr "Káșżt nối một mĂ n hĂŹnh, rồi thá»­ láșĄi." -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "Káșżt nối micrĂŽ vĂ  thá»­ láșĄi." @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "KhĂŽng thể táșĄo nhĂŁn dĂĄn nĂ y" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "KhĂŽng thể cáșŻt áșŁnh" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "KhĂŽng thể cáș­p nháș­t chia sáș» hoáșĄt động thoáșĄi ngay bĂąy giờ" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "KhĂŽng thể táșŁi áșŁnh đáșĄi diện lĂȘn" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "KhĂŽng thể táșŁi áșŁnh bĂŹa lĂȘn" @@ -10230,7 +10226,7 @@ msgstr "TáșĄo & chia sáș»" msgid "Create a community" msgstr "TáșĄo cộng đồng" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "TáșĄo một cộng đồng để báșĄn vĂ  báșĄn bĂš trĂČ chuyện." @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "CáșŻt áșŁnh nền lời mời" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "Xem trước vĂčng cáșŻt" @@ -10500,30 +10496,15 @@ msgstr "CáșŻt áșŁnh bĂŹa hồ sÆĄ" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "áșąnh đã cáșŻt quĂĄ lớn. Chọn vĂčng nhỏ hÆĄn hoáș·c tệp nhỏ hÆĄn (tối đa {maxSizeLabel})." -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "Chưa hỗ trợ cáșŻt áșŁnh động định dáșĄng {formatLabel}. áșąnh gốc sáșœ Ä‘Æ°á»Łc dĂčng." - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "Chưa hỗ trợ cáșŻt áșŁnh động định dáșĄng {formatLabel}. áșąnh gốc sáșœ Ä‘Æ°á»Łc dĂčng." - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "Chưa hỗ trợ cáșŻt áșŁnh động. áșąnh gốc sáșœ Ä‘Æ°á»Łc dĂčng." - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "Chưa hỗ trợ cáșŻt áșŁnh động. áșąnh gốc sáșœ Ä‘Æ°á»Łc dĂčng." +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "Đang cáșŻt {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "Chưa cĂł tĂ i khoáșŁn?" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "KhĂŽng hiển thị" @@ -16560,8 +16541,8 @@ msgstr "áșąnh đáșĄi diện tin nháșŻn nhĂłm sá»­ dỄng cĂčng máș·t náșĄ tráșĄn msgid "Group DMs" msgstr "Tin nháșŻn nhĂłm" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "áșąnh nhĂłm" @@ -16624,8 +16605,8 @@ msgstr "CĂ i đáș·t nhĂłm" msgid "Group typing states" msgstr "TráșĄng thĂĄi đang nháș­p cá»§a nhĂłm" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "Đã cáș­p nháș­t nhĂłm" @@ -16803,7 +16784,7 @@ msgstr "TrĂĄi tim" msgid "Hebrew" msgstr "Tiáșżng Do ThĂĄi" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "Chiều cao" @@ -17510,7 +17491,7 @@ msgstr "Đã sao chĂ©p áșŁnh vĂ o báșŁng nhớ táșĄm" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "KhĂŽng thể sá»­ dỄng hĂŹnh áșŁnh" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "Giao diện người dĂčng" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "CĂł váș» như báșĄn đang dĂčng {0}. Việc xáșżp chồng xá»­ lĂœ cá»§a {PRODUCT_NAME} lĂȘn trĂȘn cĂł thể gĂąy ra hiện tÆ°á»Łng bÆĄm tiáșżng hoáș·c mĂ©o tiáșżng. Đáș§u vĂ o trá»±c tiáșżp sáșœ truyền Ăąm thanh cá»§a báșĄn mĂ  khĂŽng bị thay đổi." @@ -22577,7 +22558,7 @@ msgstr "KhĂŽng tĂŹm tháș„y káșżt quáșŁ nĂ o" msgid "No mentions yet" msgstr "Chưa cĂł lÆ°á»Łt nháșŻc đáșżn nĂ o" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "KhĂŽng tĂŹm tháș„y micrĂŽ" @@ -23806,7 +23787,7 @@ msgstr "Mở tin nháșŻn trá»±c tiáșżp cá»§a hệ thống" msgid "Open system picker" msgstr "Mở trĂŹnh chọn cá»§a hệ thống" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "Mở JSON máș«u" @@ -23820,7 +23801,7 @@ msgstr "Mở hộp thoáșĄi cáș„m cho cộng đồng nĂ y." msgid "Open the context menu" msgstr "Mở menu ngữ cáșŁnh" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "Mở liĂȘn káșżt bĂȘn dưới trong trĂŹnh duyệt, sau đó sao chĂ©p toĂ n bộ pháșŁn hồi JSON vĂ  dĂĄn vĂ o ĂŽ." @@ -24331,7 +24312,7 @@ msgstr "7 ngĂ y qua" msgid "Paste" msgstr "DĂĄn" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "DĂĄn URL máș«u cá»§a {theOtherPlatform} để nháș­p cáș„u trĂșc cá»§a máș«u đó vĂ o một cộng đồng mới." @@ -25191,6 +25172,11 @@ msgstr "LoáșĄi Premium" msgid "Premium until date" msgstr "Premium đáșżn ngĂ y" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "Đang chuáș©n bị" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "Hồ sÆĄ" msgid "Profile badge" msgstr "Huy hiệu hồ sÆĄ" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "áșąnh bĂŹa hồ sÆĄ lĂ  tĂ­nh năng {PREMIUM_PRODUCT_NAME}. NĂąng cáș„p lĂȘn {PREMIUM_PRODUCT_NAME} để thĂȘm áșŁnh bĂŹa vĂ o hồ sÆĄ cá»§a báșĄn." #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "áșąnh bĂŹa hồ sÆĄ khĂŽng Ä‘Æ°á»Łc báș­t trĂȘn mĂĄy chá»§ nĂ y." #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "áșąnh bĂŹa hồ sÆĄ yĂȘu cáș§u {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "áșąnh bĂŹa hồ sÆĄ yĂȘu cáș§u {premiumProductName}." @@ -25838,7 +25824,7 @@ msgstr "Nháș„n để nĂłi" msgid "Push-to-talk (limited)" msgstr "Nháș„n để nĂłi (giới háșĄn)" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "Nháș„n để nĂłi sáșœ bị bỏ qua ở cháșż độ đáș§u vĂ o trá»±c tiáșżp. Chuyển sang giọng nĂłi táș­p trung hoáș·c tĂčy chỉnh để sá»­ dỄng." @@ -26551,8 +26537,8 @@ msgstr "XĂła tệp đính kĂšm" msgid "Remove authenticator app" msgstr "Gụ ứng dỄng xĂĄc thá»±c" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "XĂła áșŁnh đáșĄi diện" @@ -26561,8 +26547,8 @@ msgstr "XĂła áșŁnh đáșĄi diện" msgid "Remove background" msgstr "XĂła áșŁnh nền" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "XĂła áșŁnh bĂŹa" @@ -26625,10 +26611,10 @@ msgstr "Bỏ hiển thị trĂȘn cĂčng" msgid "Remove from URL-only GIF favorites" msgstr "XĂła khỏi GIF yĂȘu thĂ­ch lưu theo URL" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "XĂła biểu tÆ°á»Łng" @@ -27331,7 +27317,7 @@ msgstr "Đã gá»­i láșĄi" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "Đáș·t láșĄi" @@ -28074,7 +28060,7 @@ msgstr "Tiáșżng Romania" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "Xoay theo chiều kim đồng hồ" @@ -28153,8 +28139,8 @@ msgstr "Độ bĂŁo hĂČa" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "Điều khiển bộ mĂŁ hĂła chia sáș» mĂ n hĂŹnh" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "Chia sáș» mĂ n hĂŹnh đã káșżt thĂșc" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "Hiển thị huy hiệu đỏ trĂȘn biểu tÆ°á»Łng ứng dỄng khi cĂł tin nháșŻn chưa đọc" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "Chỉ hiển thị mĂ u nháș„n, bỏ qua hồ sÆĄ chung cá»§a báșĄn" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "Hiển thị biểu tÆ°á»Łng cáșŁm xĂșc tĂčy chỉnh trong tá»± động hoĂ n táș„t biểu cáșŁm" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "Hiển thị áșŁnh đáșĄi diện máș·c định, bỏ qua hồ sÆĄ chung cá»§a báșĄn" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "Hiển thị chỉ bĂĄo chưa đọc trĂȘn cĂĄc kĂȘnh đã táșŻt tiáșżng" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "Hiển thị áșŁnh đáșĄi diện hồ sÆĄ chung cá»§a báșĄn trong cộng đồng nĂ y" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "Hiển thị áșŁnh bĂŹa hồ sÆĄ chung cá»§a báșĄn trong cộng đồng nĂ y" @@ -30720,7 +30706,7 @@ msgstr "Bỏ qua" msgid "Skip \"Mark all as read\" confirmation" msgstr "Bỏ qua xĂĄc nháș­n \"Đånh dáș„u táș„t cáșŁ Ä‘ĂŁ đọc\"" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "Bỏ qua cáșŻt áșŁnh" @@ -32346,7 +32332,7 @@ msgstr "Chuyển sang bố cỄc thoáșŁi mĂĄi" msgid "Switch to dense layout" msgstr "Chuyển sang bố cỄc dĂ y đáș·c" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "Chuyển sang nháș­p trá»±c tiáșżp" @@ -32734,7 +32720,7 @@ msgstr "TĂĄc vỄ" msgid "Teleporting you to another voice region..." msgstr "Đang chuyển báșĄn sang khu vá»±c thoáșĄi khĂĄc..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "Máș«u" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "Vai trĂČ Ä‘ĂŁ cáș„p {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "Nguồn chia sáș» mĂ n hĂŹnh đã ngừng gá»­i video, vĂŹ váș­y quĂĄ trĂŹnh chia sáș» mĂ n hĂŹnh cá»§a báșĄn đã dừng." @@ -33453,6 +33439,11 @@ msgstr "KhĂŽng thể cháș·n tĂ i khoáșŁn nĂ y." msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "Thao tĂĄc nĂ y khĂŽng thể hoĂ n tĂĄc. ToĂ n bộ dữ liệu liĂȘn quan, bao gồm cáșŁ người dĂčng bot, sáșœ bị xĂła vÄ©nh viễn." +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "áșąnh động nĂ y quĂĄ dĂ i hoáș·c quĂĄ lớn để cáșŻt. HĂŁy thá»­ một tệp ngáșŻn hÆĄn hoáș·c nhỏ hÆĄn." + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "Bot nĂ y khĂŽng cĂŽng khai nĂȘn người dĂčng khĂĄc khĂŽng thể thĂȘm. msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "Bot nĂ y yĂȘu cáș§u quyền quáșŁn trị viĂȘn. Chỉ cáș„p quyền náșżu báșĄn hoĂ n toĂ n tin tưởng nhĂ  phĂĄt triển. Thay vĂ o đó, hĂŁy đề nghị họ xin Ă­t quyền hÆĄn. Đóng trang nĂ y náșżu báșĄn khĂŽng cháșŻc cháșŻn." +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "TrĂŹnh duyệt nĂ y khĂŽng thể cáșŻt tệp {avifFormatLabel} động. Vui lĂČng táșŁi lĂȘn GIF hoáș·c WebP thay tháșż." + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "BáșŁng điều khiển trĂŹnh duyệt nĂ y lĂ  cĂŽng cỄ dĂ nh cho nhĂ  phĂĄt triển." +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "TrĂŹnh duyệt nĂ y đã táșŻt WebAssembly, nĂȘn khĂŽng thể cáșŻt áșŁnh động." + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "NhĂłm nĂ y đã đáș§y. HĂŁy xĂła bớt một người trước khi thĂȘ msgid "This handoff code has expired. Generate a new one to continue." msgstr "MĂŁ chuyển giao nĂ y đã háșżt háșĄn. TáșĄo mĂŁ mới để tiáșżp tỄc." +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "áșąnh nĂ y khĂŽng thể đọc Ä‘Æ°á»Łc. áșąnh cĂł thể đã bị hỏng." + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "TáșŁi lĂȘn" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "TáșŁi lĂȘn áșŁnh đáșĄi diện tĂčy chỉnh cho cộng đồng nĂ y" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "TáșŁi lĂȘn áșŁnh bĂŹa tĂčy chỉnh cho cộng đồng nĂ y" @@ -36155,10 +36163,10 @@ msgstr "TáșŁi tệp vĂ  phÆ°ÆĄng tiện lĂȘn tin nháșŻn." msgid "Upload files and media in this channel." msgstr "TáșŁi tệp vĂ  phÆ°ÆĄng tiện lĂȘn kĂȘnh nĂ y." -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "TáșŁi biểu tÆ°á»Łng lĂȘn" @@ -36401,8 +36409,8 @@ msgstr "DĂčng giao diện Than (nền đen tuyền)" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "DĂčng áșŁnh tĂčy chỉnh" @@ -36462,8 +36470,8 @@ msgstr "DĂčng bộ lọc hoáș·c nháș­p từ khĂła để tĂŹm tin nháșŻn" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "DĂčng hồ sÆĄ chung" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "Người tham gia trĂČ chuyện thoáșĄi" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "Xá»­ lĂœ giọng nĂłi" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "Wisconsin" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "Với {PREMIUM_PRODUCT_NAME}, báșĄn cĂł thể sá»­ dỄng áșŁnh đáșĄi diện động ({ANIMATED_AVATAR_FORMATS}), áșŁnh bĂŹa hồ sÆĄ, tĂčy chỉnh tháș» cá»§a mĂŹnh vĂ  mở khĂła nhiều đáș·c quyền {PREMIUM_PRODUCT_NAME} khĂĄc." @@ -39334,8 +39342,8 @@ msgstr "BáșĄn cáș§n cĂł quyền \"{permissionLabel}\" để sá»­ dỄng biểu t msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "BáșĄn cáș§n cĂł quyền \"{permissionLabel}\" để sá»­ dỄng nhĂŁn dĂĄn từ cĂĄc cộng đồng khĂĄc táșĄi đñy." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "BáșĄn cáș§n xĂĄc nháș­n tĂ i khoáșŁn trước khi táșĄo cộng đồng." @@ -39356,8 +39364,8 @@ msgstr "BáșĄn cáș§n xĂĄc nháș­n tĂ i khoáșŁn để gá»­i tin nháșŻn trong cộng msgid "You need to verify a phone number to send messages in this community." msgstr "BáșĄn cáș§n xĂĄc minh số điện thoáșĄi để gá»­i tin nháșŻn trong cộng đồng nĂ y." -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "BáșĄn cáș§n xĂĄc minh địa chỉ email trước khi táșĄo cộng đồng." @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "Cháș„t lÆ°á»Łng đã lưu cá»§a báșĄn {savedResolution} ở tốc độ {savedFrameRate} FPS yĂȘu cáș§u {premiumProductName}, vĂŹ váș­y cĂĄc lÆ°á»Łt chia sáș» sáșœ sá»­ dỄng {resolution} ở tốc độ {frameRate} FPS." #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "KhĂŽng thể phĂĄt lÆ°á»Łt chia sáș» mĂ n hĂŹnh cá»§a báșĄn báș±ng codec video tÆ°ÆĄng thĂ­ch, vĂŹ váș­y lÆ°á»Łt chia sáș» đã bị dừng. HĂŁy thá»­ chia sáș» láșĄi." @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "URL tĂčy chỉnh cá»§a báșĄn đã Ä‘Æ°á»Łc đáș·t thĂ nh {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "Bộ mĂŁ hĂła video cá»§a báșĄn đã ngừng mĂŁ hĂła khung hĂŹnh, vĂŹ váș­y lÆ°á»Łt chia sáș» mĂ n hĂŹnh cá»§a báșĄn đã bị dừng. HĂŁy thá»­ chia sáș» láșĄi." @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "Thu phĂłng" diff --git a/fluxer_app/src/features/i18n/locales/zh-CN/messages.po b/fluxer_app/src/features/i18n/locales/zh-CN/messages.po index 7afe4080b..bda56a93b 100644 --- a/fluxer_app/src/features/i18n/locales/zh-CN/messages.po +++ b/fluxer_app/src/features/i18n/locales/zh-CN/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}ïŒŒćłć°†æŽšć‡ș" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} 的ć°șćŻžäžŽæ­€è”„æșäžćŒčé…ă€‚èŻ·é€‰æ‹©ć…¶ä»–ć›Ÿç‰‡ïŒŒæˆ–äžŠäŒ ćŻèŁć‰Șçš„é™æ€ć›Ÿç‰‡ă€‚" - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} æ–‡ä»¶èż‡ć€§ă€‚èŻ·é€‰æ‹©ć°äșŽ {maxSizeLabel} çš„æ–‡ä»¶ă€‚" #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} ć›Ÿç‰‡äžæ”ŻæŒćŠšć›Ÿă€‚èŻ·äœżç”šé™æ€ć›Ÿç‰‡ă€‚" @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "æŽ»ćŠšć…±äș«" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "æŽ»ćŠšé˜ˆć€Œ" @@ -3566,11 +3561,11 @@ msgstr "ć…èźžæćŠ{everyoneMention}撌{hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "èŻ·ćœšâ€œ{MACOS_SYSTEM_SETTINGS_NAME}”→“{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}”→“{MACOS_CAMERA_PERMISSION_NAME}â€äž­ć…èźž {PRODUCT_NAME} èźżé—źäœ çš„æ‘„ćƒć€Žă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "èŻ·ćœšâ€œ{MACOS_SYSTEM_SETTINGS_NAME}”→“{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}”→“{MACOS_MICROPHONE_PERMISSION_NAME}â€äž­ć…èźž {PRODUCT_NAME} èźżé—źäœ çš„éșŠć…‹éŁŽă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "ć…èźž {PRODUCT_NAME} èźżé—źäœ çš„éșŠć…‹éŁŽă€‚èŻ·æŁ€æŸ„æ”è§ˆć™šćœ°ć€æ æˆ–èźŸçœźă€‚" @@ -3673,7 +3668,7 @@ msgstr "ć…èźžæČĄæœ‰ {readMessageHistoryPermissionLabel} æƒé™çš„æˆć‘˜æŸ„çœ‹ msgid "Allow mentions for this role" msgstr "ć…èźžæćŠæ­€èș«ä»œç»„" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ć…èźžäœżç”šéșŠć…‹éŁŽ" @@ -3942,25 +3937,21 @@ msgstr "èż˜æœ‰ {remainingCount} äžȘ" msgid "Animate on interaction" msgstr "äș’ćŠšæ—¶æ’­æ”ŸćŠšç”»" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "äžæ”ŻæŒćŠšæ€ {AVIF_FORMAT_LABEL} æ–‡ä»¶ă€‚èŻ·æ”čäžș䞊䌠静态 {AVIF_FORMAT_LABEL} æ–‡ä»¶ă€‚" - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "äžæ”ŻæŒćŠšæ€ {avifFormatLabel}" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ćŠšæ€ć€ŽćƒïŒˆ{ANIMATED_AVATAR_FORMATS}仅䟛 {PREMIUM_PRODUCT_NAME} èźąé˜…ç”šæˆ·äœżç”šă€‚" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "æ­€ćźžäŸ‹äžæ”ŻæŒćŠšæ€ć€ŽćƒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ă€‚èŻ·äžŠäŒ é™æ€ć›Ÿç‰‡ă€‚" #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ćŠšæ€ć€ŽćƒïŒˆ{animatedAvatarFormats}需芁 {premiumProductName}。" @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ćŠšæ€ć€Žćƒć’ŒäžȘäșș蔄料æšȘćč…" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ćŠšæ€ć€ŽćƒäžćŻç”š" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ćŠšæ€ć€Žćƒéœ€èŠ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ćŠšć›Ÿéą„è§ˆ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "æ­€çŽ æäžæ”ŻæŒćŠšć›Ÿă€‚" @@ -4947,7 +4938,7 @@ msgstr "è‡ȘćŠšæŁ€æ”‹èŻ­èš€" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "è‡ȘćŠšèźŸçœźæŽ»ćŠšé˜ˆć€Œ" @@ -5127,15 +5118,15 @@ msgstr "ćŻćœšæĄŒéąćș”ç”šäž­äœżç”šă€‚" #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "ć€Žćƒ" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "ć€Žćƒæ–‡ä»¶èż‡ć€§ă€‚èŻ·é€‰æ‹©ć°äșŽ {imageMaxSizeLabel} çš„æ–‡ä»¶ă€‚" @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "ć€Žćƒèż‡ć€§ïŒŒèŻ·é€‰æ‹©ć°äșŽ {imageMaxSizeLabel} çš„ć›Ÿç‰‡ă€‚" #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "é€‰æ‹©ć€ŽćƒæšĄćŒ" @@ -5187,11 +5178,11 @@ msgstr "ćœ“ć‰çŠ»ćŒ€" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "ć·Čć°çŠç”šæˆ·" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "æšȘćč…" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "æšȘćč…æ–‡ä»¶èż‡ć€§ă€‚èŻ·é€‰æ‹©ć°äșŽ {imageMaxSizeLabel} çš„æ–‡ä»¶ă€‚" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "选择æšȘćč…æšĄćŒ" @@ -6107,8 +6098,8 @@ msgstr "朹{premiumProductName}æ ‡ç­ŸéĄ”èŽ­äč°{premiumProductName}瀌物然 msgid "Buy gift" msgstr "莭äč°ç€Œç‰©" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "戛ć»ș瀟ćŒșćłèĄšç€șäœ ćŒæ„é”ćźˆćč¶ç»ŽæŠ€<0>{PRODUCT_NAME}瀟ćŒș懆戙。" @@ -6361,7 +6352,7 @@ msgstr "æ— æł•ćœšæ­€äžŠäŒ æ–‡ä»¶" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "ć±…äž­" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "æ›Žæąć€Žćƒ" @@ -6627,9 +6618,9 @@ msgstr "æ›ŽæąèƒŒæ™Ż" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "æ›ŽæąæšȘćč…" @@ -6668,13 +6659,13 @@ msgstr "äżźæ”č矀昔称" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "曎æ”čć›Ÿæ ‡" @@ -7669,8 +7660,8 @@ msgstr "éą†ć–ç€Œç‰©" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "èź€éą†äœ çš„èŽŠć·" @@ -8518,8 +8509,8 @@ msgstr "èŻ„ç€ŸćŒșćŠ©é•żçŸ€è”·æ”»ć‡»æˆ–é’ˆćŻč性éȘšæ‰°ă€‚" msgid "Community filter" msgstr "瀟ćŒș筛选" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "瀟ćŒșć›Ÿæ ‡" @@ -8763,6 +8754,11 @@ msgstr "èŸ“ć…„æĄ†æŒ‰é’ź" msgid "Composer focus" msgstr "èŸ“ć…„æĄ†èšç„Š" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "æ­ŁćœšćŽ‹çŒ©" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "èżžæŽ„æ‘„ćƒć€Žæˆ–è™šæ‹Ÿæ•æ‰èźŸć€‡ćŽé‡èŻ•ă€‚" msgid "Connect a display, then try again." msgstr "èżžæŽ„æ˜Ÿç€șć™šćŽé‡èŻ•ă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "èżžæŽ„éșŠć…‹éŁŽćŽé‡èŻ•ă€‚" @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "æ— æł•ćˆ›ć»ș歀莎çșž" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "æ— æł•èŁć‰Șć›Ÿç‰‡" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "æš‚æ—¶æ— æł•æ›Žæ–°èŻ­éŸłæŽ»ćŠšćˆ†äș«èźŸçœź" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "æ— æł•äžŠäŒ ć€Žćƒ" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "æ— æł•äžŠäŒ æšȘćč…" @@ -10230,7 +10226,7 @@ msgstr "戛ć»șćč¶ćˆ†äș«" msgid "Create a community" msgstr "戛ć»ș瀟ćŒș" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "戛ć»ș瀟ćŒșïŒŒć’Œć„œć‹äž€è”·ç•…èŠă€‚" @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "èŁć‰Șé‚€èŻ·èƒŒæ™Ż" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "èŁć‰Șéą„è§ˆ" @@ -10500,30 +10496,15 @@ msgstr "èŁć‰ȘäžȘäșș蔄料æšȘćč…" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "èŁć‰ȘćŽçš„ć›Ÿç‰‡èż‡ć€§ă€‚èŻ·é€‰æ‹©èŸƒć°çš„ćŒșćŸŸæˆ–æ–‡ä»¶ïŒˆæœ€ć€§ {maxSizeLabel}ïŒ‰ă€‚" -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "æš‚äžæ”ŻæŒèŁć‰ȘćŠšæ€ {formatLabel} æ–‡ä»¶ă€‚ć°†äœżç”šćŽŸć§‹ć›Ÿç‰‡ă€‚" - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "æš‚äžæ”ŻæŒèŁć‰ȘćŠšæ€ {formatLabel} æ–‡ä»¶ă€‚ć°†äœżç”šćŽŸć§‹äžŠäŒ æ–‡ä»¶ă€‚" - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "æš‚äžæ”ŻæŒèŁć‰ȘćŠšć›Ÿă€‚ć°†äœżç”šćŽŸć›Ÿă€‚" - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "æš‚äžæ”ŻæŒèŁć‰ȘćŠšć›Ÿă€‚ć°†äœżç”šćŽŸć§‹äžŠäŒ æ–‡ä»¶ă€‚" +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "æ­ŁćœšèŁć‰Ș {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "èż˜æČĄæœ‰èŽŠć·ïŒŸ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "䞍星ç€ș" @@ -16560,8 +16541,8 @@ msgstr "çŸ€èŠć€Žćƒäœżç”šäžŽæ™źé€šć€Žćƒç›žćŒçš„çŠ¶æ€è’™ç‰ˆïŒŒćŒ…æ‹Źć †ć ćžƒ msgid "Group DMs" msgstr "矀聊" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "çŸ€ć›Ÿæ ‡" @@ -16624,8 +16605,8 @@ msgstr "çŸ€èźŸçœź" msgid "Group typing states" msgstr "çŸ€èŠèŸ“ć…„çŠ¶æ€" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "矀聊ć·Č曎新" @@ -16803,7 +16784,7 @@ msgstr "ćżƒćœą" msgid "Hebrew" msgstr "ćžŒäŒŻæ„èŻ­" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "高ćșŠ" @@ -17510,7 +17491,7 @@ msgstr "ć›Ÿç‰‡ć·Čć€ćˆ¶ćˆ°ć‰ȘèŽŽæż" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "æ— æł•äœżç”šć›Ÿç‰‡" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "ć€–è§‚éŁŽæ Œ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "çœ‹è”·æ„äœ æ­Łćœšäœżç”š {0}ă€‚ćœšæ­€ćŸș础侊憍揠抠 {PRODUCT_NAME} çš„éŸłéą‘ć€„ç†ćŻèƒœäŒšćŻŒè‡ŽæŠœćžæˆ–ć€±çœŸă€‚ç›ŽæŽ„èŸ“ć…„äŒšćŽŸæ ·äŒ é€’äœ çš„éŸłéą‘ă€‚" @@ -22577,7 +22558,7 @@ msgstr "æœȘæ‰Ÿćˆ°ćŒč配éĄč" msgid "No mentions yet" msgstr "æš‚æ— æćŠ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "æœȘæ‰Ÿćˆ°éșŠć…‹éŁŽ" @@ -23806,7 +23787,7 @@ msgstr "æ‰“ćŒ€çł»ç»Ÿç§äżĄ" msgid "Open system picker" msgstr "æ‰“ćŒ€çł»ç»Ÿé€‰æ‹©ć™š" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "æ‰“ćŒ€æšĄæż JSON" @@ -23820,7 +23801,7 @@ msgstr "æ‰“ćŒ€æ­€ç€ŸćŒș的氁穁ćŻčèŻæĄ†ă€‚" msgid "Open the context menu" msgstr "æ‰“ćŒ€äžŠäž‹æ–‡èœć•" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "ćœšæ”è§ˆć™šäž­æ‰“ćŒ€äž‹æ–čé“ŸæŽ„ïŒŒç„¶ćŽć€ćˆ¶ćźŒæ•Žçš„ JSON 操ćș”ćč¶çČ˜èŽŽćˆ°æĄ†äž­ă€‚" @@ -24331,7 +24312,7 @@ msgstr "èż‡ćŽ» 7 怩" msgid "Paste" msgstr "çČ˜èŽŽ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "çČ˜èŽŽ {theOtherPlatform} æšĄæż URL ä»„ć°†ć…¶ç»“æž„ćŻŒć…„æ–°ç€ŸćŒș。" @@ -25191,6 +25172,11 @@ msgstr "äŒšć‘˜ç±»ćž‹" msgid "Premium until date" msgstr "äŒšć‘˜ćˆ°æœŸæ—„æœŸ" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "懆怇䞭" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "äžȘäșș蔄料" msgid "Profile badge" msgstr "äžȘäșșè”„æ–™ćŸœç« " -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "äžȘäșș蔄料æšȘćč…æ˜Ż {PREMIUM_PRODUCT_NAME} ćŠŸèƒœă€‚èŽ·ć– {PREMIUM_PRODUCT_NAME} 捳揯äžș䜠的äžȘäșșè”„æ–™æ·»ćŠ æšȘćč…。" #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "æ­€ćźžäŸ‹æœȘ搯甹äžȘäșș蔄料æšȘćč…。" #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "äžȘäșș蔄料æšȘćč…éœ€èЁ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "äžȘäșș蔄料æšȘćč…éœ€èЁ {premiumProductName}。" @@ -25838,7 +25824,7 @@ msgstr "æŒ‰äœèŻŽèŻ" msgid "Push-to-talk (limited)" msgstr "æŒ‰äœèŻŽèŻïŒˆćŠŸèƒœć—é™ïŒ‰" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "ç›ŽæŽ„èŸ“ć…„æšĄćŒäž‹äŒšćżœç•„æŒ‰äœèŻŽèŻă€‚èŻ·ćˆ‡æąćˆ°äșșćŁ°äŒ˜ćŒ–æˆ–è‡Ș漚ä艿šĄćŒćŽäœżç”šă€‚" @@ -26551,8 +26537,8 @@ msgstr "移陀附件" msgid "Remove authenticator app" msgstr "移陀èș«ä»œéȘŒèŻć™šćș”甚" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "ç§»é™€ć€Žćƒ" @@ -26561,8 +26547,8 @@ msgstr "ç§»é™€ć€Žćƒ" msgid "Remove background" msgstr "ç§»é™€èƒŒæ™Ż" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "移陀æšȘćč…" @@ -26625,10 +26611,10 @@ msgstr "ć–æ¶ˆçœźéĄ¶" msgid "Remove from URL-only GIF favorites" msgstr "从仅限 URL 的 GIF 收藏ć€č䞭移陀" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ç§»é™€ć›Ÿæ ‡" @@ -27331,7 +27317,7 @@ msgstr "ć·Čé‡æ–°ć‘é€" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "é‡çœź" @@ -28074,7 +28060,7 @@ msgstr "çœ—é©Źć°ŒäșšèŻ­" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "éĄșæ—¶é’ˆæ—‹èœŹ" @@ -28153,8 +28139,8 @@ msgstr "é„±ć’ŒćșŠ" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "ć±ćč•ć…±äș«çŒ–ç ć™šèźŸçœź" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "ć±ćč•ć…±äș«ć·Č结束" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "有æœȘèŻ»æ¶ˆæŻæ—¶ïŒŒćœšćș”ç”šć›Ÿæ ‡äžŠæ˜Ÿç€șçșąç‚č" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "仅星ç€ș䞻鹘è‰ČïŒŒćżœç•„äœ çš„ć…šć±€äžȘäșș蔄料" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "ćœšèĄšæƒ…è‡ȘćŠšèĄ„ć…šäž­æ˜Ÿç€șè‡Ș漚äč‰èĄšæƒ…" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "星ç€șé»˜èź€ć€ŽćƒïŒŒćżœç•„äœ çš„ć…šć±€äžȘäșș蔄料" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "朹ć·Čé™éŸłçš„éą‘é“äžŠæ˜Ÿç€șæœȘèŻ»æ ‡èź°" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ćœšæ­€ç€ŸćŒș䞭星ç€șäœ çš„ć…šć±€äžȘäșșè”„æ–™ć€Žćƒ" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ćœšæ­€ç€ŸćŒș䞭星ç€șäœ çš„ć…šć±€äžȘäșș蔄料æšȘćč…" @@ -30720,7 +30706,7 @@ msgstr "è·łèż‡" msgid "Skip \"Mark all as read\" confirmation" msgstr "è·łèż‡â€œć…šéƒšæ ‡äžșć·ČèŻ»â€çĄźèź€" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "è·łèż‡èŁć‰Ș" @@ -32346,7 +32332,7 @@ msgstr "ćˆ‡æąäžșèˆ’é€‚ćžƒć±€" msgid "Switch to dense layout" msgstr "ćˆ‡æąäžșçŽ§ć‡‘ćžƒć±€" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ćˆ‡æąćˆ°ç›ŽæŽ„èŸ“ć…„" @@ -32734,7 +32720,7 @@ msgstr "任报" msgid "Teleporting you to another voice region..." msgstr "æ­ŁćœšæŠŠäœ äŒ é€ćˆ°ć…¶ä»–èŻ­éŸłćŒș柟
" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "æšĄæż" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "èŻ„èș«ä»œç»„授äșˆäș† {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "ć±ćč•ć…±äș«æșć·Čćœæ­ąć‘é€è§†éą‘ïŒŒć› æ­€äœ çš„ć±ćč•ć…±äș«ć·Čćœæ­ąă€‚" @@ -33453,6 +33439,11 @@ msgstr "æ­€èŽŠć·æ— æł•èą«ć±è”œă€‚" msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "æ­€æ“äœœæ— æł•æ’€é”€ă€‚æ‰€æœ‰ç›žć…łæ•°æźïŒŒćŒ…æ‹Źæœș晹äșșç”šæˆ·ïŒŒéƒœć°†èą«æ°žäč…ćˆ é™€ă€‚" +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "æ­€ćŠšç”»èż‡é•żæˆ–èż‡ć€§ïŒŒæ— æł•èŁć‰Șă€‚èŻ·ć°èŻ•äœżç”šæ›ŽçŸ­æˆ–æ›Žć°çš„æ–‡ä»¶ă€‚" + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "æ­€æœș晹äșșæœȘć…ŹćŒ€ïŒŒć…¶ä»–ç”šæˆ·æ— æł•æ·»ćŠ ă€‚" msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "æ­€æœș晹äșșèŻ·æ±‚çźĄç†ć‘˜æƒé™ă€‚èŻ·ä»…ćœšćźŒć…šäżĄä»»ćŒ€ć‘è€…çš„æƒ…ć†”äž‹æŽˆäșˆă€‚äčŸćŻä»„èŻ·ćŒ€ć‘è€…æ”čäžșç”łèŻ·æ›Žć°‘çš„æƒé™ă€‚ćŠ‚æžœäžçĄźćźšïŒŒèŻ·ć…łé—­æ­€éĄ”éąă€‚" +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "æ­€æ”è§ˆć™šæ— æł•èŁć‰ȘćŠšæ€ {avifFormatLabel} æ–‡ä»¶ă€‚èŻ·æ”č甹 GIF 或 WebP。" + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "æ­€æ”è§ˆć™šæŽ§ćˆ¶ć°æ˜ŻćŒ€ć‘è€…ć·„ć…·ă€‚" +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "æ­€æ”è§ˆć™šć·Č慳闭 WebAssemblyïŒŒć› æ­€æ— æł•èŁć‰ȘćŠšæ€ć›Ÿćƒă€‚" + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "矀聊ć·Čæ»Ąă€‚èŻ·ć…ˆç§»é™€äž€äș›æˆć‘˜ïŒŒć†æ·»ćŠ ć…¶ä»–äșș。" msgid "This handoff code has expired. Generate a new one to continue." msgstr "æ­€ćˆ‡æąç ć·Čèż‡æœŸă€‚èŻ·ç”Ÿæˆæ–°ćˆ‡æąç ä»„ç»§ç»­ă€‚" +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "æ— æł•èŻ»ć–æ­€ć›Ÿç‰‡ă€‚ćźƒćŻèƒœć·ČæŸćă€‚" + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "䞊䌠" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "äžșæœŹç€ŸćŒș䞊䌠è‡Ș漚äč‰ć€Žćƒ" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "äžșæœŹç€ŸćŒș䞊䌠è‡Ș漚ä艿šȘćč…" @@ -36155,10 +36163,10 @@ msgstr "ćœšæ¶ˆæŻäž­äžŠäŒ æ–‡ä»¶ć’ŒćȘ’äœ“ă€‚" msgid "Upload files and media in this channel." msgstr "ćœšæ­€éą‘é“äžŠäŒ æ–‡ä»¶ć’ŒćȘ’äœ“ă€‚" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "äžŠäŒ ć›Ÿæ ‡" @@ -36401,8 +36409,8 @@ msgstr "äœżç”šç…€ç‚­äž»éą˜ïŒˆçșŻé»‘ç•ŒéąïŒ‰" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "äœżç”šè‡Ș漚äč‰ć›Ÿç‰‡" @@ -36462,8 +36470,8 @@ msgstr "äœżç”šç­›é€‰æĄä»¶æˆ–èŸ“ć…„ć…łé”źèŻæŸ„æ‰Ÿæ¶ˆæŻ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "äœżç”šć…šć±€äžȘäșș蔄料" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "èŻ­éŸłć‚äžŽè€…" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "èŻ­éŸłć€„ç†" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ćšæ–Żćș·æ˜Ÿć·ž" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "有äș† {PREMIUM_PRODUCT_NAME}ïŒŒäœ ćŻä»„äœżç”šćŠšæ€ć€ŽćƒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ć’ŒäžȘäșș蔄料æšȘćč…、è‡Ș漚äč‰äœ çš„æ ‡ç­ŸïŒŒćč¶è§Łé”èźžć€šć…¶ä»– {PREMIUM_PRODUCT_NAME} çŠćˆ©ă€‚" @@ -39334,8 +39342,8 @@ msgstr "䜠需芁“{permissionLabel}â€æƒé™æ‰èƒœćœšæ­€ć€„äœżç”šć…¶ä»–ç€ŸćŒș msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "䜠需芁“{permissionLabel}â€æƒé™æ‰èƒœćœšæ­€ć€„äœżç”šć…¶ä»–ç€ŸćŒș的莎çșžă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "äœ éœ€èŠć…ˆèź€éą†èŽŠć·ïŒŒæ‰èƒœćˆ›ć»ș瀟ćŒș。" @@ -39356,8 +39364,8 @@ msgstr "äœ éœ€èŠć…ˆèź€éą†èŽŠć·ïŒŒæ‰èƒœćœšæ­€ç€ŸćŒșäž­ć‘é€æ¶ˆæŻă€‚" msgid "You need to verify a phone number to send messages in this community." msgstr "䜠需芁éȘŒèŻæ‰‹æœșć·æ‰èƒœćœšæ­€ç€ŸćŒșäž­ć‘é€æ¶ˆæŻă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "äœ éœ€èŠć…ˆéȘŒèŻé‚źçź±ćœ°ć€ïŒŒæ‰èƒœćˆ›ć»ș瀟ćŒș。" @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "äœ äżć­˜çš„ {savedResolution} ({savedFrameRate} FPS) 需芁 {premiumProductName}ïŒŒć› æ­€ć…±äș«ć°†äœżç”š {resolution} ({frameRate} FPS)。" #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "äœ çš„ć±ćč•ć…±äș«æ— æł•äœżç”šć…Œćźčçš„è§†éą‘çŒ–è§Łç ć™šć‘ćžƒïŒŒć› æ­€ć·Čćœæ­ąă€‚èŻ·é‡æ–°ć…±äș«ă€‚" @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "䜠的è‡Ș漚äč‰é‚€èŻ·é“ŸæŽ„ć·ČèźŸçœźäžș {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "äœ çš„è§†éą‘çŒ–ç ć™šć·Čćœæ­ąçŒ–ç ćž§ïŒŒć› æ­€ć±ćč•ć…±äș«ć·Čćœæ­ąă€‚èŻ·é‡æ–°ć…±äș«ă€‚" @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "猩攟" diff --git a/fluxer_app/src/features/i18n/locales/zh-TW/messages.po b/fluxer_app/src/features/i18n/locales/zh-TW/messages.po index 80cd4ebc4..4ce8c9a54 100644 --- a/fluxer_app/src/features/i18n/locales/zh-TW/messages.po +++ b/fluxer_app/src/features/i18n/locales/zh-TW/messages.po @@ -1405,18 +1405,13 @@ msgstr "{itemLabel}ïŒŒćłć°‡æŽšć‡ș" msgid "{kilobits} kbps" msgstr "{kilobits} kbps" -#. Error modal body shown when a non-croppable community image has dimensions that do not fit the target asset. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:72 -msgid "{label} dimensions do not match this asset. Choose a different image or upload a static image you can crop." -msgstr "{label} 的ć°șćŻžèˆ‡æ­€çŽ æäžçŹŠă€‚è«‹éžæ“‡ć…¶ä»–ćœ–ç‰‡ïŒŒæˆ–äžŠć‚łćŻèŁćˆ‡çš„éœæ…‹ćœ–ç‰‡ă€‚" - #. Error modal body shown when a community image upload exceeds the size limit. {label} names the image field and {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:44 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:33 msgid "{label} file is too large. Choose a file smaller than {maxSizeLabel}." msgstr "{label} æȘ”æĄˆéŽć€§ă€‚è«‹éžæ“‡ć°æ–Œ {maxSizeLabel} 的æȘ”æĄˆă€‚" #. Error modal body shown when a community image field does not allow animation. {label} names the image field. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:49 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:38 msgid "{label} images cannot be animated. Use a static image." msgstr "{label} ćœ–ç‰‡äžæ”ŻæŽć‹•ç•«ă€‚è«‹äœżç”šéœæ…‹ćœ–ç‰‡ă€‚" @@ -2829,7 +2824,7 @@ msgid "Activity sharing" msgstr "æŽ»ć‹•ćˆ†äș«" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:478 #: src/features/user/components/settings_utils/section_registry/VoiceVideoSections.ts:102 msgid "Activity threshold" msgstr "èȘžéŸłć”æžŹéˆæ•ćșŠ" @@ -3566,11 +3561,11 @@ msgstr "ć…èš± {everyoneMention} 撌 {hereMention}" msgid "Allow {PRODUCT_NAME} to access your camera in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_CAMERA_PERMISSION_NAME}." msgstr "朹「{MACOS_SYSTEM_SETTINGS_NAME}」→「{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}」→「{MACOS_CAMERA_PERMISSION_NAME}ă€äž­ć…èš± {PRODUCT_NAME} ć­˜ć–æ‚šçš„ç›žæ©Ÿă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:533 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:535 msgid "Allow {PRODUCT_NAME} to access your microphone in {MACOS_SYSTEM_SETTINGS_NAME} → {MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME} → {MACOS_MICROPHONE_PERMISSION_NAME}." msgstr "è«‹ćœšă€Œ{MACOS_SYSTEM_SETTINGS_NAME}」→「{MACOS_PRIVACY_AND_SECURITY_SETTINGS_NAME}」→「{MACOS_MICROPHONE_PERMISSION_NAME}ă€äž­ć…èš± {PRODUCT_NAME} ć­˜ć–æ‚šçš„éș„態鱹。" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:538 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:540 msgid "Allow {PRODUCT_NAME} to access your microphone. Check your browser's address bar or settings." msgstr "ć…èš± {PRODUCT_NAME} ć­˜ć–æ‚šçš„éș„ć…‹éąšă€‚è«‹æȘ࿟„ç€èŠœć™šçš„ç¶Čć€ćˆ—æˆ–èš­ćźšă€‚" @@ -3673,7 +3668,7 @@ msgstr "ć…èš±æČ’æœ‰ă€Œ{readMessageHistoryPermissionLabel}ă€æŹŠé™çš„æˆć“ĄæŸ„ msgid "Allow mentions for this role" msgstr "ć…èš±æćŠæ­€èș«ćˆ†ç”„" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:558 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:560 msgid "Allow microphone" msgstr "ć…èš±éș„態鱹" @@ -3942,25 +3937,21 @@ msgstr "ćŠć…¶ä»– {remainingCount} 䜍" msgid "Animate on interaction" msgstr "äș’ć‹•æ™‚æ’­æ”Ÿć‹•ç•«" -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:26 -msgid "Animated {AVIF_FORMAT_LABEL} files aren't supported. Upload a static {AVIF_FORMAT_LABEL} file instead." -msgstr "äžæ”ŻæŽć‹•ç•« {AVIF_FORMAT_LABEL} æȘ”æĄˆă€‚è«‹æ”čç‚șäžŠć‚łéœæ…‹ {AVIF_FORMAT_LABEL} æȘ”æĄˆă€‚" - #. Modal title shown when an animated AVIF upload is rejected by the client. -#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:11 +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:10 msgid "Animated {avifFormatLabel} not supported" msgstr "äžæ”ŻæŽć‹•ç•« {avifFormatLabel}" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:206 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:192 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are exclusively available to {PREMIUM_PRODUCT_NAME} subscribers." msgstr "ć‹•æ…‹é ­ćƒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ćƒ…äŸ› {PREMIUM_PRODUCT_NAME} èš‚é–±è€…äœżç”šă€‚" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:240 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:226 msgid "Animated avatars ({ANIMATED_AVATAR_FORMATS}) are not available on this instance. Upload a static image instead." msgstr "æ­€ćŻŠäŸ‹äžæ”ŻæŽć‹•æ…‹é ­ćƒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ă€‚è«‹æ”čç‚șäžŠć‚łéœæ…‹ćœ–ç‰‡ă€‚" #. Extra note in the avatar asset upload source modal. Preserve {animatedAvatarFormats} and {premiumProductName}; they are inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:115 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:102 msgid "Animated avatars ({animatedAvatarFormats}) require {premiumProductName}." msgstr "ć‹•æ…‹é ­ćƒïŒˆ{animatedAvatarFormats}需芁 {premiumProductName}。" @@ -3970,12 +3961,12 @@ msgid "Animated avatars & profile banners" msgstr "ć‹•æ…‹é ­ćƒèˆ‡ć€‹äșșæȘ”æĄˆæ©«ćč…" #. Error message in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:91 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 msgid "Animated avatars not available" msgstr "ç„Ąæł•äœżç”šć‹•æ…‹é ­ćƒ" #. Label in the avatar uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:81 msgid "Animated avatars require {premiumProductName}" msgstr "ć‹•æ…‹é ­ćƒéœ€èŠ {premiumProductName}" @@ -4046,7 +4037,7 @@ msgid "Animated image preview" msgstr "ć‹•æ…‹ćœ–ç‰‡é èŠœ" #. Confirmation modal body shown before using a non-croppable animated community image. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:54 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:43 msgid "Animated images are not supported for this asset." msgstr "æ­€çŽ æäžæ”ŻæŽć‹•æ…‹ćœ–ç‰‡ă€‚" @@ -4947,7 +4938,7 @@ msgstr "è‡Șć‹•ć”æžŹèȘžèš€" #. Short label in the voice tab. Keep it concise. #: src/features/user/components/modals/tabs/UserVoiceTab.tsx:116 -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:452 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:465 msgid "Auto-set activity threshold" msgstr "è‡Șć‹•èš­ćźšæŽ»ć‹•é–€æȘ»" @@ -5127,15 +5118,15 @@ msgstr "ćŻćœšæĄŒéąç‰ˆæ‡‰ç”šçš‹ćŒäž­äœżç”šă€‚" #. Form label for a webhook avatar image. #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/ui/components/BaseAvatar.tsx:18 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:373 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:421 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:345 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:393 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:13 #: src/features/webhook/components/WebhookListItem.tsx:252 msgid "Avatar" msgstr "性頭èČŒ" #. Error message in the avatar uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:82 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:77 msgid "Avatar file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "性頭èČŒæȘ”æĄˆéŽć€§ă€‚è«‹éžæ“‡ć°æ–Œ {imageMaxSizeLabel} 的æȘ”æĄˆă€‚" @@ -5145,7 +5136,7 @@ msgid "Avatar is too large — pick one under {imageMaxSizeLabel}." msgstr "性頭èČŒéŽć€§ïŒŒè«‹éžæ“‡ć°æ–Œ {imageMaxSizeLabel} 的朖片。" #. Short label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:103 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:90 msgid "Avatar mode selection" msgstr "éžæ“‡ć€§é ­èČŒæšĄćŒ" @@ -5187,11 +5178,11 @@ msgstr "盼才雱開侭" #: src/features/auth/flow/IpAuthorizationScreen.tsx:155 #: src/features/channel/components/channel_header/shared.ts:27 #: src/features/connection/components/modals/AddConnectionModal.tsx:397 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:165 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:164 #: src/features/guild/components/modals/add_guild_modal/GuildJoinForm.tsx:59 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:356 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:377 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:397 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:355 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:376 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:396 #: src/features/moderation/components/report_modal/IARModal.tsx:86 #: src/features/moderation/components/report/ReportStepDetails.tsx:312 #: src/features/user/components/modals/PhoneAddModal.tsx:420 @@ -5428,19 +5419,19 @@ msgstr "ć·ČćœæŹŠçš„äœżç”šè€…" #. Settings search entry label. Also used as a search synonym in the settings search bar. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:28 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:125 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:280 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:330 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:292 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 #: src/features/user/components/settings_utils/search_index/MyProfileIndex.ts:37 msgid "Banner" msgstr "æ©«ćč…" #. Error message in the banner uploader. Preserve {imageMaxSizeLabel}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:81 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:84 msgid "Banner file is too large. Choose a file smaller than {imageMaxSizeLabel}." msgstr "æ©«ćč…æȘ”æĄˆéŽć€§ă€‚è«‹éžæ“‡ć°æ–Œ {imageMaxSizeLabel} 的æȘ”æĄˆă€‚" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:86 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:89 msgid "Banner mode selection" msgstr "遞擇橫ćč…æšĄćŒ" @@ -6107,8 +6098,8 @@ msgstr "ćŸžă€Œ{premiumProductName}ă€ćˆ†é èłŒèČ· {premiumProductName} çŠźç‰©ïŒŒ msgid "Buy gift" msgstr "èłŒèȷ犟物" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:339 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:655 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:338 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:654 msgid "By creating a community, you agree to follow and uphold the <0>{PRODUCT_NAME} community guidelines." msgstr "ć»șç«‹ç€ŸçŸ€ćłèĄšç€șæ‚šćŒæ„é”ćźˆäžŠç¶­è­· <0>{PRODUCT_NAME} 瀟矀æș–扇。" @@ -6361,7 +6352,7 @@ msgstr "ç„Ąæł•ćœšé€™èŁĄäžŠć‚łæȘ”æĄˆ" #: src/features/messaging/components/modals/EditAltTextModal.tsx:190 #: src/features/messaging/components/modals/ExternalLinkWarningModal.tsx:111 #: src/features/messaging/components/modals/ForwardModal.tsx:650 -#: src/features/messaging/components/modals/ImageCropModal.tsx:944 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1025 #: src/features/messaging/components/modals/MessageHistoryThresholdModal.tsx:107 #: src/features/moderation/components/modals/BanMemberModal.tsx:262 #: src/features/moderation/components/modals/RemoveTimeoutModal.tsx:70 @@ -6614,9 +6605,9 @@ msgid "Centered" msgstr "çœźäž­" #. Title of the modal where the user picks an avatar source (file upload or GIF provider). Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:111 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:395 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:431 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:98 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:367 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:403 msgid "Change avatar" msgstr "æ›Žæ›ć€§é ­èČŒ" @@ -6627,9 +6618,9 @@ msgstr "èźŠæ›ŽèƒŒæ™Ż" #. Title of the modal where the user picks a banner source (file upload or GIF provider). Keep it concise. #. Title of the modal where the user picks a community banner source (file upload or GIF provider). Keep it concise. #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildBannerUploadField.tsx:43 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:94 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:303 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:342 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:97 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:315 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:354 msgid "Change banner" msgstr "æ›Žæ›ć°éą" @@ -6668,13 +6659,13 @@ msgstr "èźŠæ›ŽçŸ€ç”„æš±çš±" #. Title of the modal where the user picks a group icon source. Keep it concise. Keep the tone plain and specific. #. Title of the modal where the user picks an imported-template community icon source. Keep it concise. Keep the tone plain and specific. #: src/features/channel/components/modals/EditGroupBottomSheet.tsx:88 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 #: src/features/channel/components/modals/EditGroupModal.tsx:85 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:63 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:86 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:35 msgid "Change icon" msgstr "æ›Žæ›ćœ–ç€ș" @@ -7669,8 +7660,8 @@ msgstr "é ˜ć–çŠźç‰©" #: src/features/auth/components/modals/ClaimAccountModal.tsx:41 #: src/features/channel/components/direct_message/AddFriendForm.tsx:62 #: src/features/channel/utils/CreateDMModalUtils.tsx:43 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:214 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:440 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:213 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:439 #: src/features/user/components/modals/tabs/GiftInventoryTab.tsx:343 msgid "Claim your account" msgstr "èȘé ˜æ‚šçš„ćžłè™Ÿ" @@ -8518,8 +8509,8 @@ msgstr "ç€ŸçŸ€ćŠ©é•·çŸ€é«”ćœæ”»æˆ–é‡ć°æ€§éš·æ“Ÿă€‚" msgid "Community filter" msgstr "ç€ŸçŸ€çŻ©éžæąä»¶" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:272 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:593 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:271 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:592 msgid "Community icon" msgstr "ç€ŸçŸ€ćœ–ç€ș" @@ -8763,6 +8754,11 @@ msgstr "èŒžć…„æĄ†æŒ‰éˆ•" msgid "Composer focus" msgstr "èŒžć…„æĄ†è‡Ș拕氍焩" +#. Progress label on the save button while a cropped animated image is compressed. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:67 +msgid "Compressing" +msgstr "棓羼侭" + #. Button label that opens a dedicated advanced settings modal for configuring screen-share encoder controls. #. Button label that opens a dedicated advanced settings modal. #: src/features/user/components/modals/tabs/advanced_settings_tab/AdvancedChatControls.tsx:164 @@ -8917,7 +8913,7 @@ msgstr "è«‹é€ŁæŽ„ç›žæ©Ÿæˆ–è™›æ“Źæ“·ć–èŁçœźïŒŒç„¶ćŸŒć†è©Šäž€æŹĄă€‚" msgid "Connect a display, then try again." msgstr "è«‹é€ŁæŽ„éĄŻç€șć™šćŸŒć†è©Šäž€æŹĄă€‚" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:543 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:545 msgid "Connect a microphone and try again." msgstr "è«‹é€ŁæŽ„éș„ć…‹éąšćŸŒć†è©Šäž€æŹĄă€‚" @@ -9783,7 +9779,7 @@ msgid "Couldn't create this sticker" msgstr "ç„Ąæł•ć»șç«‹æ­€èČŒćœ–" #. Title of the error modal shown when image cropping fails. -#: src/features/messaging/components/modals/ImageCropModal.tsx:28 +#: src/features/messaging/components/modals/ImageCropModal.tsx:32 msgid "Couldn't crop image" msgstr "ç„Ąæł•èŁćˆ‡ćœ–ç‰‡" @@ -10159,12 +10155,12 @@ msgid "Couldn't update voice activity sharing right now" msgstr "ç›źć‰ç„Ąæł•æ›Žæ–°èȘžéŸłæŽ»ć‹•ćˆ†äș«èš­ćźš" #. Title of the error modal shown when uploading a profile avatar fails. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:107 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:94 msgid "Couldn't upload avatar" msgstr "ç„Ąæł•äžŠć‚łć€§é ­èČŒ" #. Title of the error modal shown when uploading a profile banner fails. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:90 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:93 msgid "Couldn't upload banner" msgstr "ç„Ąæł•äžŠć‚łæ©«ćč…" @@ -10230,7 +10226,7 @@ msgstr "ć»șç«‹äžŠćˆ†äș«" msgid "Create a community" msgstr "ć»ș立瀟矀" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:257 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:256 msgid "Create a community for you and your friends to chat." msgstr "ć»șç«‹ç€ŸçŸ€ïŒŒć’Œć„œć‹äž€è”·èŠć€©ă€‚" @@ -10489,7 +10485,7 @@ msgid "Crop invite background" msgstr "èŁćˆ‡é‚€è«‹èƒŒæ™Ż" #. Short label in the image crop modal. Keep it concise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:20 +#: src/features/messaging/components/modals/ImageCropModal.tsx:24 msgid "Crop preview" msgstr "èŁćˆ‡é èŠœ" @@ -10500,30 +10496,15 @@ msgstr "èŁćˆ‡ć€‹äșșæȘ”æĄˆæ©«ćč…" #. Error modal body shown when a cropped community image still exceeds the size limit. {maxSizeLabel} is a formatted file size. #. Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:67 -#: src/features/messaging/components/modals/ImageCropModal.tsx:32 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:47 +#: src/features/messaging/components/modals/ImageCropModal.tsx:36 msgid "Cropped image is too large. Choose a smaller area or a smaller file (max {maxSizeLabel})." msgstr "èŁćˆ‡ćŸŒçš„ćœ–ç‰‡éŽć€§ă€‚è«‹éžæ“‡èŒƒć°çš„ć€ćŸŸæˆ–èŒƒć°çš„æȘ”æĄˆïŒˆæœ€ć€§ {maxSizeLabel}ïŒ‰ă€‚" -#. Confirmation modal body shown before using an animated community image without cropping. {formatLabel} is the image format name. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:58 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original image will be used." -msgstr "ç›źć‰äžæ”ŻæŽèŁćˆ‡ć‹•ç•« {formatLabel} æȘ”æĄˆă€‚ć°‡æœƒäœżç”šćŽŸć§‹ćœ–ç‰‡ă€‚" - -#. Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:95 -msgid "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used." -msgstr "ç›źć‰äžæ”ŻæŽèŁćˆ‡ć‹•ç•« {formatLabel} æȘ”æĄˆă€‚ć°‡æœƒäœżç”šćŽŸć§‹äžŠć‚łçš„æȘ”æĄˆă€‚" - -#. Confirmation modal body shown before using an animated community image with an unknown format. -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:63 -msgid "Cropping animated files isn't supported yet. The original image will be used." -msgstr "ç›źć‰äžæ”ŻæŽèŁćˆ‡ć‹•ç•«æȘ”æĄˆă€‚ć°‡äœżç”šćŽŸć§‹ćœ–ç‰‡ă€‚" - -#. Description text in the avatar uploader when the animated image format is unknown. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:99 -msgid "Cropping animated files isn't supported yet. The original upload will be used." -msgstr "ç›źć‰äžæ”ŻæŽèŁćˆ‡ć‹•ç•«æȘ”æĄˆă€‚ć°‡äœżç”šćŽŸć§‹äžŠć‚łçš„æȘ”æĄˆă€‚" +#. Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:62 +msgid "Cropping {percent}%" +msgstr "æ­ŁćœšèŁćˆ‡ {percent}%" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:86 @@ -12597,8 +12578,8 @@ msgstr "還æČ’æœ‰ćžłè™Ÿć—ŽïŒŸ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:74 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:60 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:69 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:63 msgid "Don't show" msgstr "侍顯ç€ș" @@ -16560,8 +16541,8 @@ msgstr "çŸ€ç”„ç§èšŠçš„é ­ćƒæœƒäœżç”šèˆ‡äž€èˆŹé ­ćƒç›žćŒçš„ç‹€æ…‹éźçœ©ïŒŒćŒ… msgid "Group DMs" msgstr "矀甄私蚊" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:290 -#: src/features/channel/components/modals/EditGroupModal.tsx:248 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:289 +#: src/features/channel/components/modals/EditGroupModal.tsx:247 msgid "Group icon" msgstr "çŸ€ç”„ćœ–ç€ș" @@ -16624,8 +16605,8 @@ msgstr "çŸ€ç”„èš­ćźš" msgid "Group typing states" msgstr "çŸ€ç”„èŒžć…„ç‹€æ…‹" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:232 -#: src/features/channel/components/modals/EditGroupModal.tsx:223 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:231 +#: src/features/channel/components/modals/EditGroupModal.tsx:222 msgid "Group updated" msgstr "矀甄ć·Č曎新" @@ -16803,7 +16784,7 @@ msgstr "æ„›ćżƒ" msgid "Hebrew" msgstr "ćžŒäŒŻäŸ†æ–‡" -#: src/features/messaging/components/modals/ImageCropModal.tsx:872 +#: src/features/messaging/components/modals/ImageCropModal.tsx:958 msgid "Height" msgstr "高ćșŠ" @@ -17510,7 +17491,7 @@ msgstr "朖片ć·Čè€‡èŁœćˆ°ć‰ȘèČŒç°ż" #. Error modal title shown when a template-import community icon upload cannot be accepted or processed. #: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:59 #: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:155 -#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:78 +#: src/features/guild/components/modals/guild_tabs/guild_overview_tab/hooks/useGuildImageAssetField.tsx:52 msgid "Image couldn't be used" msgstr "ç„Ąæł•äœżç”šćœ–ç‰‡" @@ -19671,7 +19652,7 @@ msgid "Look and feel" msgstr "ć€–è§€ć’Œéąšæ Œ" #. placeholder {0}: externalProcessor.name -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:652 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:654 msgid "Looks like you're using {0}. Stacking {PRODUCT_NAME}'s processing on top can cause pumping or distortion. Direct input passes your audio through untouched." msgstr "çœ‹äŸ†æ‚šæ­Łćœšäœżç”š {0}ă€‚ćœšæ­€äč‹äžŠć†ç–ŠćŠ  {PRODUCT_NAME} çš„è™•ç†ïŒŒćŻèƒœæœƒć°Žè‡ŽéŸłé‡ćżœć€§ćżœć°æˆ–ć€±çœŸă€‚ç›ŽæŽ„èŒžć…„æœƒćŽŸć°äžć‹•ćœ°ć‚łé€æ‚šçš„éŸłèšŠă€‚" @@ -22577,7 +22558,7 @@ msgstr "æČ’æœ‰æ‰Ÿćˆ°çŹŠćˆçš„é …ç›ź" msgid "No mentions yet" msgstr "還æČ’有è૿ćŠçš„èšŠæŻ" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:528 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:530 msgid "No microphone found" msgstr "æ‰Ÿäžćˆ°éș„態鱹" @@ -23806,7 +23787,7 @@ msgstr "é–‹ć•Ÿçł»ç”±ç§èšŠ" msgid "Open system picker" msgstr "é–‹ć•Ÿçł»ç”±éžć–ć™š" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:528 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:527 msgid "Open template JSON" msgstr "é–‹ć•ŸçŻ„æœŹ JSON" @@ -23820,7 +23801,7 @@ msgstr "é–‹ć•Ÿæ­€ç€ŸçŸ€çš„ćœæŹŠć°è©±æĄ†ă€‚" msgid "Open the context menu" msgstr "é–‹ć•Ÿæ“äœœéžć–ź" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:511 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:510 msgid "Open the link below in your browser, then copy the entire JSON response and paste it into the box." msgstr "è«‹ćœšç€èŠœć™šäž­é–‹ć•Ÿäž‹æ–čé€Łç”ïŒŒç„¶ćŸŒè€‡èŁœćźŒæ•Žçš„ JSON ć›žæ‡‰äžŠèČŒćˆ°æ–č桊侭。" @@ -24331,7 +24312,7 @@ msgstr "過掻 7 怩" msgid "Paste" msgstr "èČŒäžŠ" -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:483 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:482 msgid "Paste a {theOtherPlatform} template URL to import its structure into a new community." msgstr "èČŒäžŠ {theOtherPlatform} çŻ„æœŹç¶Čć€ïŒŒćłćŻć°‡ć…¶ç”æ§‹ćŒŻć…„æ–°çš„ç€ŸçŸ€ă€‚" @@ -25191,6 +25172,11 @@ msgstr "é€Č階æ–čæĄˆéĄžćž‹" msgid "Premium until date" msgstr "é€Č階æ–čæĄˆç”æŸæ—„期" +#. Progress label on the save button while an animated image crop starts. Keep it concise. +#: src/features/messaging/components/modals/ImageCropModal.tsx:58 +msgid "Preparing" +msgstr "æș–悙䞭" + #. Setup wizard title while the instance configuration loads. #: src/features/app/components/setup/SetupWizardSteps.tsx:72 msgid "Preparing setup" @@ -25497,22 +25483,22 @@ msgstr "怋äșșæȘ”æĄˆ" msgid "Profile badge" msgstr "怋äșșæȘ”æĄˆćŸœç« " -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:163 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:166 msgid "Profile banners are a {PREMIUM_PRODUCT_NAME} feature. Get {PREMIUM_PRODUCT_NAME} to add a banner to your profile." msgstr "怋äșșæȘ”æĄˆæ©«ćč…æ˜Ż {PREMIUM_PRODUCT_NAME} çš„ćŠŸèƒœă€‚ć–ćŸ— {PREMIUM_PRODUCT_NAME}ç‚șæ‚šçš„ć€‹äșșæȘ”æĄˆæ–°ćąžæ©«ćč…。" #. Profile banner uploader notice shown when the instance configuration disables profile banners. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:68 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:71 msgid "Profile banners are not enabled on this instance." msgstr "æ­€ćŻŠäŸ‹æœȘ敟甹怋äșșæȘ”æĄˆæ©«ćč…。" #. Label in the banner uploader. Preserve {premiumProductName}; it is inserted by code. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:76 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:79 msgid "Profile banners require {premiumProductName}" msgstr "怋äșșæȘ”æĄˆæ©«ćč…éœ€èЁ {premiumProductName}" #. Profile banner uploader notice shown when profile banners require premium. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:64 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:67 msgid "Profile banners require {premiumProductName}." msgstr "怋äșșæȘ”æĄˆæ©«ćč…éœ€èЁ {premiumProductName}。" @@ -25838,7 +25824,7 @@ msgstr "按䜏èȘȘ話" msgid "Push-to-talk (limited)" msgstr "按䜏èȘȘè©±ïŒˆć—é™ïŒ‰" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:674 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:681 msgid "Push-to-talk is ignored in direct input. Switch to focused voice or custom to use it." msgstr "ç›ŽæŽ„èŒžć…„æšĄćŒæœƒćżœç•„æŒ‰äœèȘȘè©±ă€‚è«‹ćˆ‡æ›ç‚șèȘžéŸłèšç„Šæˆ–è‡Șèš‚æ‰èƒœäœżç”šă€‚" @@ -26551,8 +26537,8 @@ msgstr "移陀附件" msgid "Remove authenticator app" msgstr "ç§»é™€é©—è­‰ć™šæ‡‰ç”šçš‹ćŒ" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:405 -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:441 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:377 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:413 msgid "Remove avatar" msgstr "移陀性頭èČŒ" @@ -26561,8 +26547,8 @@ msgstr "移陀性頭èČŒ" msgid "Remove background" msgstr "ç§»é™€èƒŒæ™Ż" -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:314 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:353 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:326 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:365 msgid "Remove banner" msgstr "移陀橫ćč…" @@ -26625,10 +26611,10 @@ msgstr "ć–æ¶ˆçœźé ‚" msgid "Remove from URL-only GIF favorites" msgstr "ćŸžćƒ…é™ç¶Č杀的 GIF 最愛䞭移陀" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:338 -#: src/features/channel/components/modals/EditGroupModal.tsx:293 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:314 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:635 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:337 +#: src/features/channel/components/modals/EditGroupModal.tsx:292 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:313 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:634 msgid "Remove icon" msgstr "ç§»é™€ćœ–ç€ș" @@ -27331,7 +27317,7 @@ msgstr "ć·Čé‡æ–°ć‚łé€" #: src/features/app/components/dialogs/shared/UnsavedChangesBannerContent.tsx:51 #: src/features/app/components/floating/ColorPickerPopover.tsx:190 #: src/features/input/components/KeybindRecorder.tsx:459 -#: src/features/messaging/components/modals/ImageCropModal.tsx:936 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1022 msgid "Reset" msgstr "重蚭" @@ -28074,7 +28060,7 @@ msgstr "çŸ…éŠŹć°Œäșžæ–‡" #. Short label in the image crop modal. Keep it concise. #. Tooltip on the media viewer button that rotates the current media item 90 degrees clockwise. -#: src/features/messaging/components/modals/ImageCropModal.tsx:24 +#: src/features/messaging/components/modals/ImageCropModal.tsx:28 #: src/features/messaging/components/modals/media_modal/shared.ts:93 msgid "Rotate clockwise" msgstr "順時針旋蜉" @@ -28153,8 +28139,8 @@ msgstr "éŁœć’ŒćșŠ" #. Save button in the community-folder settings modal footer. #: src/features/app/components/dialogs/shared/MobileSettingsComponents.tsx:113 #: src/features/auth/components/modals/PasskeyNameModal.tsx:87 -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:367 -#: src/features/channel/components/modals/EditGroupModal.tsx:323 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:366 +#: src/features/channel/components/modals/EditGroupModal.tsx:322 #: src/features/channel/components/modals/RenameChannelModal.tsx:28 #: src/features/connection/components/modals/EditConnectionModal.tsx:108 #: src/features/emoji/components/emojis/EmojiListItem.tsx:328 @@ -28367,7 +28353,7 @@ msgid "Screen share encoder controls" msgstr "èžąćč•ćˆ†äș«ç·šçąŒć™šæŽ§ćˆ¶é …" #. Title of a modal shown when an active screen share stops unexpectedly. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:120 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:119 msgctxt "screen-share" msgid "Screen share ended" msgstr "èžąćč•ćˆ†äș«ć·Č甐束" @@ -30035,7 +30021,7 @@ msgid "Show a red badge on the app icon when you have unread messages" msgstr "當悚有æœȘèź€èšŠæŻæ™‚ïŒŒćœšæ‡‰ç”šçš‹ćŒćœ–ç€ș侊顯ç€ș箅è‰Č暙蚘" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:72 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:75 msgid "Show accent color only, ignoring your global profile" msgstr "ćȘ饯ç€șćŒ·èȘżè‰ČïŒŒćżœç•„æ‚šçš„ć…šćŸŸć€‹äșșæȘ”æĄˆèš­ćźš" @@ -30104,7 +30090,7 @@ msgid "Show custom emojis in expression autocomplete" msgstr "ćœšèĄšæƒ…çŹŠè™Ÿè‡Șć‹•ćźŒæˆäž­éĄŻç€șè‡Șèš‚èĄšæƒ…çŹŠè™Ÿ" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:78 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:73 msgid "Show default avatar, ignoring your global profile" msgstr "饯ç€șé èš­ć€§é ­èČŒïŒŒćżœç•„æ‚šçš„ć…šćŸŸć€‹äșșæȘ”æĄˆèš­ćźš" @@ -30443,12 +30429,12 @@ msgid "Show unread indicator on muted channels" msgstr "朹ć·ČéœéŸłçš„é »é“äžŠéĄŻç€șæœȘèź€æš™èš˜" #. Label in the avatar uploader. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:62 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:57 msgid "Show your global profile avatar in this community" msgstr "ćœšæ­€ç€ŸçŸ€äž­éĄŻç€șæ‚šçš„ć…šćŸŸć€‹äșșæȘ”æĄˆć€§é ­èČŒ" #. Label in the banner uploader. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:48 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:51 msgid "Show your global profile banner in this community" msgstr "ćœšæ­€ç€ŸçŸ€éĄŻç€șæ‚šçš„ć…šćŸŸć€‹äșșæȘ”æĄˆæ©«ćč…" @@ -30720,7 +30706,7 @@ msgstr "畄過" msgid "Skip \"Mark all as read\" confirmation" msgstr "ç•„éŽă€Œć…šéƒšæš™ç€șç‚șć·Čèź€ă€çš„çąșèȘæ­„驟" -#: src/features/messaging/components/modals/ImageCropModal.tsx:953 +#: src/features/messaging/components/modals/ImageCropModal.tsx:1034 msgid "Skip cropping" msgstr "ç•„éŽèŁćˆ‡" @@ -32346,7 +32332,7 @@ msgstr "ćˆ‡æ›æˆèˆ’é©ç‰ˆéąé…çœź" msgid "Switch to dense layout" msgstr "ćˆ‡æ›æˆç·ŠæčŠç‰ˆéąé…çœź" -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:647 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:649 msgid "Switch to direct input" msgstr "ćˆ‡æ›ç‚șç›ŽæŽ„èŒžć…„" @@ -32734,7 +32720,7 @@ msgstr "任拙" msgid "Teleporting you to another voice region..." msgstr "æ­Łćœšć°‡æ‚šć‚łé€è‡łćŠäž€ć€‹èȘžéŸłć€ćŸŸ..." -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:560 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:559 msgid "Template" msgstr "çŻ„æœŹ" @@ -33236,7 +33222,7 @@ msgid "The role granted {permissions}" msgstr "è©Čèș«ćˆ†ç”„曟授äșˆ {permissions}" #. Body of a modal shown when a browser screen share track ends outside the app, for example from the browser sharing controls. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:125 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:124 msgctxt "screen-share" msgid "The screen share source stopped sending video, so your screen share was stopped." msgstr "èžąćč•ćˆ†äș«äŸ†æșć·Čćœæ­ąć‚łé€èŠ–èšŠïŒŒć› æ­€æ‚šçš„èžąćč•ćˆ†äș«ć·Čćœæ­ąă€‚" @@ -33453,6 +33439,11 @@ msgstr "ç„Ąæł•ć°éŽ–æ­€ćžłè™Ÿă€‚" msgid "This action cannot be undone. All associated data, including the bot user, will be permanently deleted." msgstr "æ­€ć‹•äœœç„Ąæł•ćŸ©ćŽŸă€‚æ‰€æœ‰ç›žé—œèł‡æ–™ïŒŒćŒ…æ‹Źæ©Ÿć™šäșșäœżç”šè€…ïŒŒéƒœć°‡æ°žäč…ćˆȘ陀。" +#. Error modal body shown when an animated image has too many frames or pixels to crop in the browser. +#: src/features/messaging/components/modals/ImageCropModal.tsx:41 +msgid "This animation is too long or too large to crop. Try a shorter or smaller file." +msgstr "é€™æź”ć‹•ç•«ć€Ș長或ć€Șć€§ïŒŒç„Ąæł•èŁćˆ‡ă€‚è«‹ć˜—è©ŠèŒƒçŸ­æˆ–èŒƒć°çš„æȘ”æĄˆă€‚" + #. Short label in the authentication authorize flow. Keep the tone plain and specific. #: src/features/auth/components/pages/oauth_authorize_page/state/useAuthorizeFlow.ts:82 msgid "This application" @@ -33472,11 +33463,23 @@ msgstr "æ­€æ©Ÿć™šäșșéžć…Źé–‹ïŒŒć…¶ä»–äœżç”šè€…ç„Ąæł•æ–°ćąžă€‚" msgid "This bot requests the administrator permission. Only grant it if you fully trust the developer. Ask them to request fewer permissions instead. Close this page if unsure." msgstr "æ­€æ©Ÿć™šäșșèŠæ±‚çźĄç†ć“ĄæŹŠé™ă€‚è«‹ćȘćœšæ‚šćźŒć…šäżĄä»»é–‹ç™Œäșșć“Ąæ™‚æ‰æŽˆäșˆă€‚è«‹ä»–ć€‘æ”čç‚șèŠæ±‚èŒƒć°‘æŹŠé™ă€‚ćŠ‚æžœäžçąșćźšïŒŒè«‹é—œé–‰æ­€é éąă€‚" +#. Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name. +#. Modal body shown when an animated AVIF upload is rejected because this browser cannot crop it. +#: src/features/expressions/utils/AnimatedAvifModalUtils.tsx:14 +#: src/features/messaging/components/modals/ImageCropModal.tsx:49 +msgid "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead." +msgstr "é€™ć€‹ç€èŠœć™šç„Ąæł•èŁćˆ‡ć‹•æ…‹çš„ {avifFormatLabel} æȘ”æĄˆă€‚è«‹æ”čç‚ș侊悳 GIF 或 WebP æȘ”æĄˆă€‚" + #. Console warning line explaining that the browser console is meant for developers. #: src/features/devtools/utils/SelfXssNotice.ts:16 msgid "This browser console is a developer tool." msgstr "é€™ć€‹ç€èŠœć™šäž»æŽ§ć°æ˜Żé–‹ç™Œäșș擥淄慷。" +#. Error modal body shown when WebAssembly is unavailable, which animated image cropping needs. +#: src/features/messaging/components/modals/ImageCropModal.tsx:54 +msgid "This browser has WebAssembly turned off, so animated images can't be cropped." +msgstr "é€™ć€‹ç€èŠœć™šć·Č關閉 WebAssemblyïŒŒć› æ­€ç„Ąæł•èŁćˆ‡ć‹•æ…‹ćœ–ç‰‡ă€‚" + #. Pre-join indicator shown beneath the Join button on a DM or group DM call where every connected participant supports E2EE. #: src/features/voice/utils/VoiceMessageDescriptors.ts:320 msgid "This call is end-to-end encrypted." @@ -33758,6 +33761,11 @@ msgstr "歀矀甄ć·Čæ»żă€‚è«‹ć…ˆç§»é™€æˆć“ĄïŒŒæ‰èƒœć†æ–°ćąžæˆć“Ąă€‚" msgid "This handoff code has expired. Generate a new one to continue." msgstr "æ­€äș€æŽ„çąŒć·ČéŽæœŸă€‚è«‹ç”ąç”Ÿæ–°çš„äș€æŽ„çąŒä»„çčŒçșŒă€‚" +#. Error modal body shown when an animated image fails to decode during cropping. +#: src/features/messaging/components/modals/ImageCropModal.tsx:45 +msgid "This image couldn't be read. It may be damaged." +msgstr "é€™ćŒ”ćœ–ç‰‡ç„Ąæł•èź€ć–ïŒŒćŻèƒœć·ČææŻ€ă€‚" + #. Desktop updater modal body for managed package builds such as Flatpak. productName is the app name. #: src/features/updater/commands/UpdaterModalCommands.tsx:75 msgid "This install is managed by your system. Update {productName} from your software center or package manager." @@ -36078,12 +36086,12 @@ msgid "Upload" msgstr "侊悳" #. Button or menu action label in the avatar uploader. Keep it concise. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:70 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:65 msgid "Upload a custom avatar for this community" msgstr "äžŠć‚łé€™ć€‹ç€ŸçŸ€çš„è‡Șèš‚ć€§é ­èČŒ" #. Button or menu action label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:56 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:59 msgid "Upload a custom banner for this community" msgstr "äžŠć‚łæ­€ç€ŸçŸ€çš„è‡Ș蚂橫ćč…" @@ -36155,10 +36163,10 @@ msgstr "ćœšèšŠæŻäž­äžŠć‚łæȘ”æĄˆć’ŒćȘ’體。" msgid "Upload files and media in this channel." msgstr "ćœšæ­€é »é“äžŠć‚łæȘ”æĄˆć’ŒćȘ’體。" -#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:329 -#: src/features/channel/components/modals/EditGroupModal.tsx:284 -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:305 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:626 +#: src/features/channel/components/modals/EditGroupBottomSheet.tsx:328 +#: src/features/channel/components/modals/EditGroupModal.tsx:283 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:304 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:625 #: src/features/guild/components/modals/guild_tabs/guild_overview_tab/fields/GuildIconUploadField.tsx:130 msgid "Upload icon" msgstr "侊悳朖ç€ș" @@ -36401,8 +36409,8 @@ msgstr "äœżç”šç…€ç‚­äž»éĄŒïŒˆçŽ”é»‘ä»‹éąïŒ‰" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:66 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:52 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:61 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:55 msgid "Use custom image" msgstr "äœżç”šè‡Șèš‚ćœ–ç‰‡" @@ -36462,8 +36470,8 @@ msgstr "äœżç”šçŻ©éžæąä»¶æˆ–èŒžć…„é—œé”ć­—äŸ†ć°‹æ‰ŸèšŠæŻ" #. Short label in the avatar uploader. Keep it concise. #. Short label in the banner uploader. Keep it concise. Keep the tone plain and specific. -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:58 -#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:44 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:53 +#: src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx:47 msgid "Use global profile" msgstr "äœżç”šć…šćŸŸć€‹äșșæȘ”æĄˆ" @@ -37826,7 +37834,7 @@ msgid "Voice participants" msgstr "èȘžéŸłćƒèˆ‡è€…" #. Voice settings radio group label for microphone processing profile. -#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:642 +#: src/features/user/components/modals/tabs/UserVoiceTab.tsx:644 #: src/features/voice/components/voice_connection_status/AudioProcessingModal.tsx:55 msgid "Voice processing" msgstr "èȘžéŸłè™•理" @@ -38684,7 +38692,7 @@ msgctxt "us-state" msgid "Wisconsin" msgstr "ćšæ–Żćș·èŸ›ć·ž" -#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:215 +#: src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx:201 msgid "With {PREMIUM_PRODUCT_NAME}, you can use animated avatars ({ANIMATED_AVATAR_FORMATS}) and profile banners, customize your tag, and unlock many other {PREMIUM_PRODUCT_NAME} perks." msgstr "有äș† {PREMIUM_PRODUCT_NAME}ïŒŒæ‚šćŻä»„äœżç”šć‹•æ…‹é ­ćƒïŒˆ{ANIMATED_AVATAR_FORMATS}ïŒ‰ć’Œć€‹äșșæȘ”æĄˆæ©«ćč…、è‡Șèš‚æ‚šçš„æš™ç±€ïŒŒäžŠè§ŁéŽ–èš±ć€šć…¶ä»– {PREMIUM_PRODUCT_NAME} çŠćˆ©ă€‚" @@ -39334,8 +39342,8 @@ msgstr "æ‚šéœ€èŠă€Œ{permissionLabel}ă€æŹŠé™æ‰èƒœćœšé€™èŁĄäœżç”šäŸ†è‡Șć…¶ä»– msgid "You need the \"{permissionLabel}\" permission to use stickers from other communities here." msgstr "æ‚šéœ€èŠă€Œ{permissionLabel}ă€æŹŠé™æ‰èƒœćœšé€™èŁĄäœżç”šäŸ†è‡Șć…¶ä»–ç€ŸçŸ€çš„èČŒćœ–ă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:208 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:434 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:207 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:433 msgid "You need to claim your account before you can create a community." msgstr "æ‚šćż…é ˆć…ˆèȘé ˜ćžłè™ŸïŒŒæ‰èƒœć»șç«‹ç€ŸçŸ€ă€‚" @@ -39356,8 +39364,8 @@ msgstr "æ‚šćż…é ˆć…ˆèȘé ˜ćžłè™ŸïŒŒæ‰èƒœćœšé€™ć€‹ç€ŸçŸ€ć‚łé€èšŠæŻă€‚" msgid "You need to verify a phone number to send messages in this community." msgstr "æ‚šéœ€èŠé©—è­‰é›»è©±è™ŸçąŒæ‰èƒœćœšé€™ć€‹ç€ŸçŸ€ć‚łé€èšŠæŻă€‚" -#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:233 -#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:459 +#: src/features/guild/components/modals/add_guild_modal/GuildCreateForm.tsx:232 +#: src/features/guild/components/modals/add_guild_modal/TemplateImportForm.tsx:458 msgid "You need to verify your email address before you can create a community." msgstr "æ‚šćż…é ˆć…ˆé©—è­‰é›»ć­éƒ”ä»¶ćœ°ć€ïŒŒæ‰èƒœć»șç«‹ç€ŸçŸ€ă€‚" @@ -39980,7 +39988,7 @@ msgid "Your saved {savedResolution} at {savedFrameRate} FPS needs {premiumProduc msgstr "䜠ć„Č歘的 {savedResolution} @ {savedFrameRate} FPS 需芁 {premiumProductName}ïŒŒć› æ­€ćˆ†äș«æœƒäœżç”š {resolution} @ {frameRate} FPS。" #. Body of a modal shown when the video codec the browser negotiated for an active screen share is outside the codecs the app allows and no allowed codec could be published, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:131 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:130 msgctxt "screen-share" msgid "Your screen share could not be published with a compatible video codec, so it was stopped. Try sharing again." msgstr "ç”±æ–Œç„Ąæł•äœżç”šç›žćźčçš„èŠ–èšŠç·šè§ŁçąŒć™šç™Œćžƒæ‚šçš„èžąćč•ç•«éąïŒŒć› æ­€ć·Čćœæ­ąćˆ†äș«ă€‚è«‹ć†è©Šäž€æŹĄă€‚" @@ -40079,7 +40087,7 @@ msgid "Your vanity URL has been set to {inviteEndpoint}/{vanitySlug}" msgstr "悚的è‡Șèš‚ç¶Č杀ć·Čèš­ç‚ș {inviteEndpoint}/{vanitySlug}" #. Body of a modal shown when the local video encoder produces no frames for an active screen share, which forces the share to stop. -#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:138 +#: src/features/voice/engine/v2/VoiceEngineV2AppScreenShareExecutionAdapter.tsx:137 msgctxt "screen-share" msgid "Your video encoder stopped encoding frames, so your screen share was stopped. Try sharing again." msgstr "æ‚šçš„èŠ–èšŠç·šçąŒć™šćœæ­ąç·šçąŒćœ±æ ŒïŒŒć› æ­€æ‚šçš„èžąćč•ćˆ†äș«ć·Čćœæ­ąă€‚è«‹é‡æ–°ć˜—è©Šćˆ†äș«ă€‚" @@ -40100,7 +40108,7 @@ msgid "YubiKey" msgstr "YubiKey" #. Settings search synonym. Used to match this term when the user types it in the settings search bar. -#: src/features/messaging/components/modals/ImageCropModal.tsx:831 +#: src/features/messaging/components/modals/ImageCropModal.tsx:917 #: src/features/user/components/settings_utils/section_registry/AppearanceSections.ts:182 msgid "Zoom" msgstr "çžźæ”Ÿ" diff --git a/fluxer_app/src/features/messaging/components/modals/ImageCropModal.tsx b/fluxer_app/src/features/messaging/components/modals/ImageCropModal.tsx index 993f3d060..4e5e272c7 100644 --- a/fluxer_app/src/features/messaging/components/modals/ImageCropModal.tsx +++ b/fluxer_app/src/features/messaging/components/modals/ImageCropModal.tsx @@ -1,15 +1,19 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import * as Modal from '@app/features/app/components/dialogs/Modal'; -import {cropAnimatedImageWithWorkerPool} from '@app/features/expressions/workers/AnimatedImageCropWorkerManager'; +import {AVIF_FORMAT_LABEL} from '@app/features/app/config/I18nDisplayConstants'; +import {inspectImageBytes} from '@app/features/expressions/utils/AnimatedImageUtils'; +import type {AnimatedCropSourceFormat, CropParams} from '@app/features/expressions/workers/AnimatedImageCropMessages'; +import {CropPipelineError, cropAnimatedImage} from '@app/features/expressions/workers/AnimatedImageCropWorkerManager'; import {showMessagingErrorModal} from '@app/features/messaging/components/alerts/MessagingErrorModalUtils'; import styles from '@app/features/messaging/components/modals/ImageCropModal.module.css'; import {formatFileSize} from '@app/features/messaging/utils/FileUtils'; import {Logger} from '@app/features/platform/utils/AppLogger'; import {Button} from '@app/features/ui/button/Button'; -import * as ModalCommands from '@app/features/ui/commands/ModalCommands'; import {Slider} from '@app/features/ui/components/Slider'; import FocusRing from '@app/features/ui/focus_ring/FocusRing'; +import {usePopOwningModal} from '@app/features/ui/utils/ModalUtils'; +import type {I18n} from '@lingui/core'; import {msg} from '@lingui/core/macro'; import {Trans, useLingui} from '@lingui/react/macro'; import {ArrowClockwiseIcon, ImageSquareIcon} from '@phosphor-icons/react'; @@ -34,6 +38,36 @@ const CROPPED_IMAGE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR = msg({ comment: 'Error modal body shown when a cropped image still exceeds the size limit. {maxSizeLabel} is a formatted file size.', }); +const ANIMATION_TOO_LONG_OR_TOO_LARGE_DESCRIPTOR = msg({ + message: 'This animation is too long or too large to crop. Try a shorter or smaller file.', + comment: 'Error modal body shown when an animated image has too many frames or pixels to crop in the browser.', +}); +const IMAGE_COULDN_T_BE_READ_DESCRIPTOR = msg({ + message: "This image couldn't be read. It may be damaged.", + comment: 'Error modal body shown when an animated image fails to decode during cropping.', +}); +const BROWSER_CAN_T_CROP_ANIMATED_AVIF_DESCRIPTOR = msg({ + message: "This browser can't crop animated {avifFormatLabel} files. Upload a GIF or WebP instead.", + comment: + 'Error modal body shown when the browser cannot decode animated AVIF for cropping. {avifFormatLabel} is the AVIF format name.', +}); +const WEBASSEMBLY_TURNED_OFF_DESCRIPTOR = msg({ + message: "This browser has WebAssembly turned off, so animated images can't be cropped.", + comment: 'Error modal body shown when WebAssembly is unavailable, which animated image cropping needs.', +}); +const CROP_PROGRESS_PREPARING_DESCRIPTOR = msg({ + message: 'Preparing', + comment: 'Progress label on the save button while an animated image crop starts. Keep it concise.', +}); +const CROP_PROGRESS_CROPPING_DESCRIPTOR = msg({ + message: 'Cropping {percent}%', + comment: + 'Progress label on the save button while animated image frames are cropped. {percent} is a whole number. Keep it concise.', +}); +const CROP_PROGRESS_COMPRESSING_DESCRIPTOR = msg({ + message: 'Compressing', + comment: 'Progress label on the save button while a cropped animated image is compressed. Keep it concise.', +}); const logger = new Logger('ImageCropModal'); interface Point { @@ -63,22 +97,19 @@ class CropSizeLimitError extends Error { } } -interface AnimatedImageCropOptions { - x: number; - y: number; - width: number; - height: number; - imageRotation?: number; - resizeWidth?: number | null; - resizeHeight?: number | null; +interface CropProgress { + phase: 'init' | 'crop' | 'compress'; + fraction: number; } -async function cropAnimatedImageWithWorker( - imageBytes: Uint8Array, - format: 'gif' | 'webp' | 'avif' | 'apng', - options: AnimatedImageCropOptions, -): Promise { - return cropAnimatedImageWithWorkerPool(imageBytes, format, options); +function isAnimatedCropSourceFormat(format: string): format is AnimatedCropSourceFormat { + return format === 'gif' || format === 'png' || format === 'webp' || format === 'avif'; +} + +function toCropRotation(rotationDeg: number): CropParams['rotation'] { + const rot = ((rotationDeg % 360) + 360) % 360; + if (rot === 90 || rot === 180 || rot === 270) return rot; + return 0; } function clamp(value: number, min: number, max: number): number { @@ -315,8 +346,10 @@ async function exportAnimatedImage( maxW: number, maxH: number, maxBytes: number, - src: string, - mimeType: string, + bytes: ArrayBuffer, + format: AnimatedCropSourceFormat, + signal: AbortSignal, + onProgress: (progress: CropProgress) => void, ): Promise { const scale = image.naturalWidth / displayDimensions.width; const cropNativeWidth = cropDimensions.width * scale; @@ -330,31 +363,18 @@ async function exportAnimatedImage( maxDimensions: {width: targetW, height: targetH}, rotationDeg, }); - const response = await fetch(src); - if (!response.ok) { - throw new Error('Failed to fetch animated image data'); - } - const buffer = await response.arrayBuffer(); - const imageBytes = new Uint8Array(buffer); - const format = mimeType.toLowerCase().includes('gif') - ? 'gif' - : mimeType.toLowerCase().includes('webp') - ? 'webp' - : mimeType.toLowerCase().includes('avif') - ? 'avif' - : 'apng'; - const cropOptions = { + const crop: CropParams = { x: Math.max(0, Math.floor(geom.sourceX)), y: Math.max(0, Math.floor(geom.sourceY)), width: Math.max(1, Math.floor(geom.sourceWidth)), height: Math.max(1, Math.floor(geom.sourceHeight)), - imageRotation: rotationDeg, - resizeWidth: Math.floor(targetW), - resizeHeight: Math.floor(targetH), + rotation: toCropRotation(rotationDeg), + outputWidth: Math.max(1, Math.floor(targetW)), + outputHeight: Math.max(1, Math.floor(targetH)), }; - snapCropOptionsToImageBounds(cropOptions, image); - const resultBytes = await cropAnimatedImageWithWorker(imageBytes, format, cropOptions); - const resultBlob = new Blob([new Uint8Array(resultBytes)], {type: mimeType}); + snapCropToImageBounds(crop, image); + const result = await cropAnimatedImage({bytes, format, crop, sizeLimitBytes: maxBytes}, {signal, onProgress}); + const resultBlob = new Blob([new Uint8Array(result.bytes)], {type: result.mime}); if (resultBlob.size === 0) { throw new Error('Empty animated image blob returned'); } @@ -364,7 +384,7 @@ async function exportAnimatedImage( return resultBlob; } -function snapCropOptionsToImageBounds(options: AnimatedImageCropOptions, image: HTMLImageElement): void { +function snapCropToImageBounds(options: CropParams, image: HTMLImageElement): void { const EPS = 2; const naturalWidth = image.naturalWidth; const naturalHeight = image.naturalHeight; @@ -388,11 +408,58 @@ function snapCropOptionsToImageBounds(options: AnimatedImageCropOptions, image: if (options.y === 0 && Math.abs(options.height - naturalHeight) <= EPS) { options.height = naturalHeight; } - if (options.resizeWidth != null && Math.abs(options.resizeWidth - naturalWidth) <= EPS) { - options.resizeWidth = naturalWidth; + if (Math.abs(options.outputWidth - naturalWidth) <= EPS) { + options.outputWidth = naturalWidth; } - if (options.resizeHeight != null && Math.abs(options.resizeHeight - naturalHeight) <= EPS) { - options.resizeHeight = naturalHeight; + if (Math.abs(options.outputHeight - naturalHeight) <= EPS) { + options.outputHeight = naturalHeight; + } +} + +function getCropErrorMessage( + i18n: I18n, + error: unknown, + fallbackMessage: string, + sizeLimitBytes: number, +): string | null { + if (error instanceof CropSizeLimitError) { + return i18n._(CROPPED_IMAGE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR, { + maxSizeLabel: formatFileSize(i18n.locale, error.maxBytes), + }); + } + if (!(error instanceof CropPipelineError)) { + return fallbackMessage; + } + switch (error.code) { + case 'aborted': + return null; + case 'too_large': + return i18n._(CROPPED_IMAGE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR, { + maxSizeLabel: formatFileSize(i18n.locale, sizeLimitBytes), + }); + case 'budget_exceeded': + return i18n._(ANIMATION_TOO_LONG_OR_TOO_LARGE_DESCRIPTOR); + case 'decode_failed': + return i18n._(IMAGE_COULDN_T_BE_READ_DESCRIPTOR); + case 'animated_avif_unsupported': + return i18n._(BROWSER_CAN_T_CROP_ANIMATED_AVIF_DESCRIPTOR, {avifFormatLabel: AVIF_FORMAT_LABEL}); + case 'wasm_unavailable': + return i18n._(WEBASSEMBLY_TURNED_OFF_DESCRIPTOR); + default: + return fallbackMessage; + } +} + +function getCropProgressLabel(i18n: I18n, progress: CropProgress): string { + switch (progress.phase) { + case 'init': + return i18n._(CROP_PROGRESS_PREPARING_DESCRIPTOR); + case 'crop': + return i18n._(CROP_PROGRESS_CROPPING_DESCRIPTOR, { + percent: Math.round(Math.min(1, Math.max(0, progress.fraction)) * 100), + }); + case 'compress': + return i18n._(CROP_PROGRESS_COMPRESSING_DESCRIPTOR); } } @@ -410,7 +477,6 @@ function cropCoversDisplayedImage(displayDimensions: Size, cropDimensions: Size, interface ImageCropModalProps { imageUrl: string; - sourceMimeType: string; onCropComplete: (croppedImageBlob: Blob) => void; onSkip?: () => void; title: React.ReactNode; @@ -430,7 +496,6 @@ interface ImageCropModalProps { export const ImageCropModal: React.FC = observer( ({ imageUrl, - sourceMimeType, onCropComplete, onSkip, title, @@ -447,6 +512,9 @@ export const ImageCropModal: React.FC = observer( canSkipOriginal, }) => { const {i18n} = useLingui(); + const popOwningModal = usePopOwningModal(); + const abortRef = useRef(null); + const [progress, setProgress] = useState(null); const imageRef = useRef(null); const cropperContainerRef = useRef(null); const transformRef = useRef({x: 0, y: 0}); @@ -470,9 +538,6 @@ export const ImageCropModal: React.FC = observer( const [heightSliderKey, setHeightSliderKey] = useState(0); const [isSkipAllowed, setIsSkipAllowed] = useState(false); const isRound = cropShape === 'round'; - const isAnimated = ['image/gif', 'image/webp', 'image/avif', 'image/png'].some((type) => - sourceMimeType.toLowerCase().includes(type.replace('image/', '')), - ); const MIN_ZOOM = 1; const MAX_ZOOM = 3; const effectiveMinHeightRatio = !isRound ? (minHeightRatio ?? 1) : 1; @@ -641,55 +706,74 @@ export const ImageCropModal: React.FC = observer( cropCoversDisplayedImage(displayDimensions, cropDimensions, zoomRatio) ) { onSkip(); - ModalCommands.pop(); + popOwningModal(); return; } + abortRef.current?.abort(); + const controller = new AbortController(); + abortRef.current = controller; + const cropOrigin = transformRef.current; try { setIsProcessing(true); + setProgress(null); const scaledDisplayDimensions: Size = { width: displayDimensions.width * zoomRatio, height: displayDimensions.height * zoomRatio, }; - const outBlob = isAnimated - ? await exportAnimatedImage( - img, - scaledDisplayDimensions, - cropDimensions, - transformRef.current, - rotation, - maxWidth, - maxHeight, - sizeLimitBytes, - imageUrl, - sourceMimeType, - ) - : await exportStaticImage( - img, - scaledDisplayDimensions, - cropDimensions, - transformRef.current, - rotation, - maxWidth, - maxHeight, - sizeLimitBytes, - ); + const response = await fetch(imageUrl); + if (controller.signal.aborted) return; + if (!response.ok) { + throw new Error('Failed to fetch image data'); + } + const bytes = await response.arrayBuffer(); + if (controller.signal.aborted) return; + const inspected = await inspectImageBytes(new Uint8Array(bytes)); + if (controller.signal.aborted) return; + const outBlob = + inspected.animated && isAnimatedCropSourceFormat(inspected.format) + ? await exportAnimatedImage( + img, + scaledDisplayDimensions, + cropDimensions, + cropOrigin, + rotation, + maxWidth, + maxHeight, + sizeLimitBytes, + bytes, + inspected.format, + controller.signal, + setProgress, + ) + : await exportStaticImage( + img, + scaledDisplayDimensions, + cropDimensions, + cropOrigin, + rotation, + maxWidth, + maxHeight, + sizeLimitBytes, + ); + if (controller.signal.aborted) return; onCropComplete(outBlob); - ModalCommands.pop(); + popOwningModal(); } catch (error) { + if (controller.signal.aborted) return; + const message = getCropErrorMessage(i18n, error, errorMessage, sizeLimitBytes); + if (message == null) return; logger.error('Error cropping image:', error); - const message = - error instanceof CropSizeLimitError - ? i18n._(CROPPED_IMAGE_IS_TOO_LARGE_PLEASE_CHOOSE_A_DESCRIPTOR, { - maxSizeLabel: formatFileSize(i18n.locale, error.maxBytes), - }) - : errorMessage; showMessagingErrorModal({ title: i18n._(COULDN_T_CROP_IMAGE_DESCRIPTOR), message, dataFlx: 'messaging.image-crop-modal.crop-failed.generic-error-modal', }); } finally { - setIsProcessing(false); + if (abortRef.current === controller) { + abortRef.current = null; + setIsProcessing(false); + setProgress(null); + } } }, [ cropDimensions, @@ -698,29 +782,30 @@ export const ImageCropModal: React.FC = observer( hasEdits, i18n, imageUrl, - isAnimated, isSkipAllowed, maxHeight, maxWidth, onCropComplete, onSkip, + popOwningModal, rotation, sizeLimitBytes, - sourceMimeType, zoomRatio, ]); const handleSkip = useCallback(() => { if (!isSkipAllowed) return; if (onSkip) onSkip(); - ModalCommands.pop(); - }, [isSkipAllowed, onSkip]); + popOwningModal(); + }, [isSkipAllowed, onSkip, popOwningModal]); const handleCancel = useCallback(() => { - ModalCommands.pop(); - }, []); + abortRef.current?.abort(); + popOwningModal(); + }, [popOwningModal]); + useEffect(() => () => abortRef.current?.abort(), []); useEffect(() => { setIsSkipAllowed(false); setLoadError(false); - }, [imageUrl, sourceMimeType]); + }, [imageUrl]); useEffect(() => { const onMouseMove = (e: MouseEvent) => handleMouseMove(e); const onMouseUp = () => handleMouseUp(); @@ -769,9 +854,10 @@ export const ImageCropModal: React.FC = observer( }; }, [displayDimensions, zoomRatio]); const exportDisabled = isProcessing || loadError; + const progressLabel = isProcessing && progress != null ? getCropProgressLabel(i18n, progress) : null; return ( - - + +
{description} @@ -935,12 +1021,7 @@ export const ImageCropModal: React.FC = observer( > Reset - {onSkip && isSkipAllowed && ( @@ -956,10 +1037,10 @@ export const ImageCropModal: React.FC = observer( diff --git a/fluxer_app/src/features/messaging/utils/MediaNativeBridge.ts b/fluxer_app/src/features/messaging/utils/MediaNativeBridge.ts deleted file mode 100644 index 33589faba..000000000 --- a/fluxer_app/src/features/messaging/utils/MediaNativeBridge.ts +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later - -export interface NativeFrame { - rgba: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface NativeDecodedImage { - frames: Array; - width: number; - height: number; - hasAlpha: boolean; -} - -export interface NativeBridge { - sniff(buffer: Uint8Array): { - mime: string; - animated: boolean; - frames: number; - }; - decodeImage(buffer: Uint8Array): NativeDecodedImage; - decodeHeic(buffer: Uint8Array): NativeFrame; - decodeJxl(buffer: Uint8Array): NativeFrame; - encodeAnimatedWebp( - frames: Array, - options?: { - quality?: number; - lossless?: boolean; - }, - ): Uint8Array; - encodeAnimatedApng(frames: Array): Uint8Array; - encodeAvif( - rgba: Uint8Array, - width: number, - height: number, - hasAlpha: boolean, - options?: { - quality?: number; - speed?: number; - }, - ): Uint8Array; -} - -declare global { - var fluxerNativeMedia: NativeBridge | undefined; -} - -export function getNativeBridge(): NativeBridge | null { - return globalThis.fluxerNativeMedia ?? null; -} - -export function hasNativeBridge(): boolean { - return getNativeBridge() !== null; -} - -export function __setNativeBridgeForTesting(bridge: NativeBridge | null): void { - if (bridge === null) { - delete globalThis.fluxerNativeMedia; - } else { - globalThis.fluxerNativeMedia = bridge; - } -} - -export type DecoderRoute = 'libfluxcore' | 'native' | 'browser' | 'unsupported'; - -export function pickDecoderRouteFor(mime: string, hasNative: boolean): DecoderRoute { - const m = mime.toLowerCase(); - if (m === 'image/gif' || m === 'image/png' || m === 'image/apng' || m === 'image/jpeg') { - return 'libfluxcore'; - } - if (m === 'image/webp') { - return hasNative ? 'native' : 'browser'; - } - if (m === 'image/avif' || m === 'image/jxl') { - return hasNative ? 'native' : 'browser'; - } - if (m === 'image/heic' || m === 'image/heif') { - return hasNative ? 'native' : 'unsupported'; - } - if (m === 'application/json' || m === 'application/lottie+json') { - return 'unsupported'; - } - return 'unsupported'; -} diff --git a/fluxer_app/src/features/platform/utils/ImageDecoderInterop.ts b/fluxer_app/src/features/platform/utils/ImageDecoderInterop.ts index 36016fe4d..c89c3c007 100644 --- a/fluxer_app/src/features/platform/utils/ImageDecoderInterop.ts +++ b/fluxer_app/src/features/platform/utils/ImageDecoderInterop.ts @@ -3,7 +3,6 @@ export interface FluxerImageDecoderInit { data: ReadableStream | ArrayBuffer | ArrayBufferView; type: string; - preferAnimation?: boolean; } export interface FluxerImageDecoderDecodedFrame { @@ -20,6 +19,7 @@ export interface FluxerImageDecoderTrack { export interface FluxerImageDecoderInstance { decode(options?: {frameIndex?: number; completeFramesOnly?: boolean}): Promise; tracks: { + ready: Promise; selectedTrack: FluxerImageDecoderTrack | null; }; completed: Promise; @@ -31,6 +31,9 @@ export interface FluxerImageDecoderConstructor { isTypeSupported(type: string): Promise; } +export const AVIF_ALPHA_PROBE_BASE64 = + 'AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAAGGbWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAAAAAAAOcGl0bQAAAAAAAQAAACxpbG9jAAAAAEQAAAIAAQAAAAEAAAHAAAAAFAACAAAAAQAAAa4AAAASAAAAQmlpbmYAAAAAAAIAAAAaaW5mZQIAAAAAAQAAYXYwMUNvbG9yAAAAABppbmZlAgAAAAACAABhdjAxQWxwaGEAAAAAGmlyZWYAAAAAAAAADmF1eGwAAgABAAEAAADDaXBycAAAAJ1pcGNvAAAAFGlzcGUAAAAAAAAAAgAAAAIAAAAQcGl4aQAAAAADCAgIAAAADGF2MUOBAAwAAAAAE2NvbHJuY2x4AAEADQAGgAAAAA5waXhpAAAAAAEIAAAADGF2MUOBABwAAAAAOGF1eEMAAAAAdXJuOm1wZWc6bXBlZ0I6Y2ljcDpzeXN0ZW1zOmF1eGlsaWFyeTphbHBoYQAAAAAeaXBtYQAAAAAAAAACAAEEAQKDBAACBAEFhgcAAAAubWRhdBIACgQYADYVMggQAAAY4UJyEBIACgUYADYEIDIJEAAAAAfIJMZi'; + export type Canvas2DContext = OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D; function isImageDecoderConstructor(value: unknown): value is FluxerImageDecoderConstructor { @@ -47,3 +50,54 @@ export function getImageDecoderConstructor(): FluxerImageDecoderConstructor | nu export function drawVideoFrameToCanvas(ctx: Canvas2DContext, image: VideoFrame, x = 0, y = 0): void { ctx.drawImage(image as VideoFrame & CanvasImageSource, x, y); } + +let animatedAvifSupport: Promise | null = null; + +function decodeBase64(value: string): Uint8Array { + const binary = atob(value); + const out = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i); + return out; +} + +export function closeImageDecoder(decoder: FluxerImageDecoderInstance): void { + try { + decoder.close(); + } catch {} +} + +async function probeAvifAlpha(ImageDecoderConstructor: FluxerImageDecoderConstructor): Promise { + const decoder = new ImageDecoderConstructor({data: decodeBase64(AVIF_ALPHA_PROBE_BASE64), type: 'image/avif'}); + try { + const {image} = await decoder.decode({frameIndex: 0}); + try { + const canvas = new OffscreenCanvas(image.displayWidth, image.displayHeight); + const context = canvas.getContext('2d', {willReadFrequently: true}); + if (!context) return false; + drawVideoFrameToCanvas(context, image); + return context.getImageData(0, 0, 1, 1).data[3] === 0; + } finally { + image.close(); + } + } catch { + return false; + } finally { + closeImageDecoder(decoder); + } +} + +async function detectAnimatedAvifSupport(): Promise { + const ImageDecoderConstructor = getImageDecoderConstructor(); + if (!ImageDecoderConstructor || typeof OffscreenCanvas === 'undefined') return false; + try { + if (!(await ImageDecoderConstructor.isTypeSupported('image/avif'))) return false; + } catch { + return false; + } + return probeAvifAlpha(ImageDecoderConstructor); +} + +export function canDecodeAnimatedAvif(): Promise { + animatedAvifSupport ??= detectAnimatedAvifSupport(); + return animatedAvifSupport; +} diff --git a/fluxer_app/src/features/platform/utils/LibFluxcore.ts b/fluxer_app/src/features/platform/utils/LibFluxcore.ts index 80fbb0851..4f3e914f3 100644 --- a/fluxer_app/src/features/platform/utils/LibFluxcore.ts +++ b/fluxer_app/src/features/platform/utils/LibFluxcore.ts @@ -14,32 +14,6 @@ let pendingModuleOperations = 0; const liveZstdStreamDecoders = new Set(); const liveZstdStreamEncoders = new Set(); -export interface RgbaTransformResult { - rgba: Uint8Array; - width: number; - height: number; -} - -export interface DecodedFrame { - rgba: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedApngFrame { - compressed: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedGifChunk { - data: Uint8Array; - width: number; - height: number; -} - async function loadModule(): Promise { if (!modulePromise) { modulePromise = (async () => { @@ -103,135 +77,8 @@ export async function detectAnimatedImage(data: Uint8Array): Promise { return withPinnedLibfluxcoreModule(() => Boolean(wasm.is_animated_image(data))); } -export function cropAndRotateGif( - gif: Uint8Array, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Uint8Array { - try { - const result = wasm.crop_and_rotate_gif(gif, x, y, width, height, rotation, resizeWidth, resizeHeight); - return result instanceof Uint8Array ? result : new Uint8Array(result); - } finally { - releaseLibfluxcoreMemoryIfIdle(); - } -} - -export function cropAndRotateImage( - image: Uint8Array, - format: string, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Uint8Array { - try { - const result = wasm.crop_and_rotate_image(image, format, x, y, width, height, rotation, resizeWidth, resizeHeight); - return result instanceof Uint8Array ? result : new Uint8Array(result); - } finally { - releaseLibfluxcoreMemoryIfIdle(); - } -} - -export function cropRotateRgba( - rgba: Uint8Array, - width: number, - height: number, - x: number, - y: number, - cropWidth: number, - cropHeight: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): RgbaTransformResult { - const result = wasm.crop_rotate_rgba( - rgba, - width, - height, - x, - y, - cropWidth, - cropHeight, - rotation, - resizeWidth, - resizeHeight, - ); - return { - rgba: result.rgba instanceof Uint8Array ? result.rgba : new Uint8Array(result.rgba), - width: result.width, - height: result.height, - }; -} - -export function decodeGifFrames(input: Uint8Array): Array { - return wasm.decode_gif_frames(input); -} - -export function decodeApngFrames(input: Uint8Array): Array { - return wasm.decode_apng_frames(input); -} - -export function encodeGifFrames(frames: Array): Uint8Array { - const result = wasm.encode_gif_frames(frames); - return result instanceof Uint8Array ? result : new Uint8Array(result); -} - -export function encodeApngFrames(frames: Array): Uint8Array { - const result = wasm.encode_apng_frames(frames); - return result instanceof Uint8Array ? result : new Uint8Array(result); -} - -export function encodeGifFrameChunk(frame: DecodedFrame, first: boolean): EncodedGifChunk { - const result = wasm.encode_gif_frame_chunk(frame, first); - return { - data: result.data instanceof Uint8Array ? result.data : new Uint8Array(result.data), - width: result.width, - height: result.height, - }; -} - -export function assembleGifFrameChunks(chunks: Array): Uint8Array { - const result = wasm.assemble_gif_frame_chunks(chunks); - return result instanceof Uint8Array ? result : new Uint8Array(result); -} - -export function encodeApngFramePayload(frame: DecodedFrame): EncodedApngFrame { - const result = wasm.encode_apng_frame_payload(frame); - return { - compressed: result.compressed instanceof Uint8Array ? result.compressed : new Uint8Array(result.compressed), - width: result.width, - height: result.height, - delayMs: result.delayMs, - }; -} - -export function assembleApngFrames(frames: Array): Uint8Array { - const result = wasm.assemble_apng_frames(frames); - return result instanceof Uint8Array ? result : new Uint8Array(result); -} - -export async function cropAndRotateApng( - apng: Uint8Array, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Promise { - return withPinnedLibfluxcoreModule(() => { - const result = wasm.crop_and_rotate_apng(apng, x, y, width, height, rotation, resizeWidth, resizeHeight); - return result instanceof Uint8Array ? result : new Uint8Array(result); - }); +export async function sniffImageFormat(data: Uint8Array): Promise { + return withPinnedLibfluxcoreModule(() => wasm.sniff_image_format(data)); } export async function decompressZstdFrame(input: Uint8Array): Promise { diff --git a/fluxer_app/src/features/platform/workers/LibFluxcoreWorker.ts b/fluxer_app/src/features/platform/workers/LibFluxcoreWorker.ts index 209a7bab1..049257c95 100644 --- a/fluxer_app/src/features/platform/workers/LibFluxcoreWorker.ts +++ b/fluxer_app/src/features/platform/workers/LibFluxcoreWorker.ts @@ -1,52 +1,20 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import {resolveWorkerAssetUrl} from '@app/features/platform/utils/WorkerAssetUrl'; -import type {InitOutput} from '@pkgs/libfluxcore/libfluxcore'; import initLibfluxcore, * as wasm from '@pkgs/libfluxcore/libfluxcore'; import libfluxcoreWasmUrl from '@pkgs/libfluxcore/libfluxcore_bg.wasm'; -export interface RgbaTransformResult { - rgba: Uint8Array; - width: number; - height: number; -} - -export interface DecodedFrame { - rgba: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedApngFrame { - compressed: Uint8Array; - width: number; - height: number; - delayMs: number; -} - -export interface EncodedGifChunk { - data: Uint8Array; - width: number; - height: number; -} - let modulePromise: Promise | null = null; let moduleReady = false; -let moduleExports: InitOutput | null = null; -const MAX_RETAINED_LIBFLUXCORE_WASM_MEMORY_BYTES = 64 * 1024 * 1024; -async function loadModule(): Promise { +export async function ensureLibfluxcoreReady(): Promise { if (!modulePromise) { - const wasmUrl = resolveWorkerAssetUrl(libfluxcoreWasmUrl); - modulePromise = initLibfluxcore(wasmUrl) - .then((exports) => { - moduleExports = exports; + modulePromise = initLibfluxcore({module_or_path: resolveWorkerAssetUrl(libfluxcoreWasmUrl)}) + .then(() => { moduleReady = true; }) .catch((error) => { modulePromise = null; - moduleExports = null; moduleReady = false; throw error; }); @@ -54,74 +22,11 @@ async function loadModule(): Promise { await modulePromise; } -function assertModuleReady(): void { - if (!moduleReady) { - throw new Error('WASM module not loaded. Call ensureLibfluxcoreReady() first.'); - } +function toU32(value: number): number { + return Number.isFinite(value) && value > 0 ? Math.min(0xffffffff, Math.floor(value)) : 0; } -function normalizeResult(result: Uint8Array | ArrayBuffer): Uint8Array { - return result instanceof Uint8Array ? result : new Uint8Array(result); -} - -export async function ensureLibfluxcoreReady(): Promise { - await loadModule(); -} - -export function releaseLibfluxcoreMemoryIfIdle(): void { - if ((moduleExports?.memory.buffer.byteLength ?? 0) <= MAX_RETAINED_LIBFLUXCORE_WASM_MEMORY_BYTES) return; - wasm.__resetLibfluxcoreWasmForMemoryPressure(); - modulePromise = null; - moduleReady = false; - moduleExports = null; -} - -export function cropAndRotateGif( - gif: Uint8Array, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Uint8Array { - assertModuleReady(); - return normalizeResult(wasm.crop_and_rotate_gif(gif, x, y, width, height, rotation, resizeWidth, resizeHeight)); -} - -export async function cropAndRotateApng( - apng: Uint8Array, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Promise { - await loadModule(); - return normalizeResult(wasm.crop_and_rotate_apng(apng, x, y, width, height, rotation, resizeWidth, resizeHeight)); -} - -export function cropAndRotateImage( - image: Uint8Array, - format: string, - x: number, - y: number, - width: number, - height: number, - rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): Uint8Array { - assertModuleReady(); - return normalizeResult( - wasm.crop_and_rotate_image(image, format, x, y, width, height, rotation, resizeWidth, resizeHeight), - ); -} - -export function cropRotateRgba( +export function cropRotateRgbaInto( rgba: Uint8Array, width: number, height: number, @@ -130,81 +35,24 @@ export function cropRotateRgba( cropWidth: number, cropHeight: number, rotation: number, - resizeWidth: number | null, - resizeHeight: number | null, -): RgbaTransformResult { - assertModuleReady(); - const result = wasm.crop_rotate_rgba( + output: Uint8Array, + outputWidth: number, + outputHeight: number, +): void { + if (!moduleReady) { + throw new Error('WASM module not loaded. Call ensureLibfluxcoreReady() first.'); + } + wasm.crop_rotate_rgba_into_buffer( rgba, - width, - height, - x, - y, - cropWidth, - cropHeight, - rotation, - resizeWidth, - resizeHeight, + output, + toU32(width), + toU32(height), + toU32(x), + toU32(y), + toU32(cropWidth), + toU32(cropHeight), + toU32(rotation), + toU32(outputWidth), + toU32(outputHeight), ); - return { - rgba: result.rgba instanceof Uint8Array ? result.rgba : new Uint8Array(result.rgba), - width: result.width, - height: result.height, - }; -} - -export function decodeGifFrames(input: Uint8Array): Array { - assertModuleReady(); - return wasm.decode_gif_frames(input); -} - -export function decodeApngFrames(input: Uint8Array): Array { - assertModuleReady(); - return wasm.decode_apng_frames(input); -} - -export function encodeGifFrames(frames: Array): Uint8Array { - assertModuleReady(); - return normalizeResult(wasm.encode_gif_frames(frames)); -} - -export function encodeApngFrames(frames: Array): Uint8Array { - assertModuleReady(); - return normalizeResult(wasm.encode_apng_frames(frames)); -} - -export function encodeGifFrameChunk(frame: DecodedFrame, first: boolean): EncodedGifChunk { - assertModuleReady(); - const result = wasm.encode_gif_frame_chunk(frame, first); - return { - data: result.data instanceof Uint8Array ? result.data : new Uint8Array(result.data), - width: result.width, - height: result.height, - }; -} - -export function assembleGifFrameChunks(chunks: Array): Uint8Array { - assertModuleReady(); - return normalizeResult(wasm.assemble_gif_frame_chunks(chunks)); -} - -export function encodeApngFramePayload(frame: DecodedFrame): EncodedApngFrame { - assertModuleReady(); - const result = wasm.encode_apng_frame_payload(frame); - return { - compressed: result.compressed instanceof Uint8Array ? result.compressed : new Uint8Array(result.compressed), - width: result.width, - height: result.height, - delayMs: result.delayMs, - }; -} - -export function assembleApngFrames(frames: Array): Uint8Array { - assertModuleReady(); - return normalizeResult(wasm.assemble_apng_frames(frames)); -} - -export async function detectAnimatedImage(data: Uint8Array): Promise { - await loadModule(); - return Boolean(wasm.is_animated_image(data)); } diff --git a/fluxer_app/src/features/platform/workers/LibWebpWorker.ts b/fluxer_app/src/features/platform/workers/LibWebpWorker.ts new file mode 100644 index 000000000..4e51d063e --- /dev/null +++ b/fluxer_app/src/features/platform/workers/LibWebpWorker.ts @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import {resolveWorkerAssetUrl} from '@app/features/platform/utils/WorkerAssetUrl'; +import initLibWebp, {AnimDecoder, AnimEncoder, webp_probe} from '@pkgs/libfluxwebp/libfluxwebp'; +import libWebpScalarWasmUrl from '@pkgs/libfluxwebp/libfluxwebp_bg.wasm'; +import libWebpSimdWasmUrl from '@pkgs/libfluxwebp/libfluxwebp_simd_bg.wasm'; + +export type LibWebpVariant = 'simd' | 'scalar'; + +export interface WebpProbe { + width: number; + height: number; + frameCount: number; + plays: number; + hasAlpha: boolean; + lossless: boolean; +} + +interface WebpFrame { + rgba: Uint8Array; + delayMs: number; +} + +interface WebpFrameSource { + width: number; + height: number; + frameCount: number; + plays: number; + next(): WebpFrame | null; + close(): void; +} + +interface WebpFrameSink { + add(rgba: Uint8Array, delayMs: number): void; + finish(): Uint8Array; + close(): void; +} + +interface WebpRung { + quality: number; + method: number; + lossless: boolean; +} + +const WEBP_MAX_FRAME_DURATION_MS = 0xffffff; +const SIMD_PROBE_MODULE = new Uint8Array([ + 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 10, 1, 8, 0, 65, 0, 253, 15, 253, 98, 11, +]); + +let readyPromise: Promise | null = null; +let wasmMemory: WebAssembly.Memory | null = null; + +async function loadLibWebp(): Promise { + const variant: LibWebpVariant = WebAssembly.validate(SIMD_PROBE_MODULE) ? 'simd' : 'scalar'; + const wasmUrl = resolveWorkerAssetUrl(variant === 'simd' ? libWebpSimdWasmUrl : libWebpScalarWasmUrl); + const exports = await initLibWebp({module_or_path: wasmUrl}); + wasmMemory = exports.memory; + return variant; +} + +export function ensureLibWebpReady(): Promise { + if (!readyPromise) { + readyPromise = loadLibWebp().catch((error: unknown) => { + readyPromise = null; + wasmMemory = null; + throw error; + }); + } + return readyPromise; +} + +function requireMemory(): WebAssembly.Memory { + if (!wasmMemory) { + throw new Error('libwebp is not loaded. Call ensureLibWebpReady() first.'); + } + return wasmMemory; +} + +export function probeWebp(bytes: Uint8Array): WebpProbe { + requireMemory(); + const [width, height, frameCount, plays, hasAlpha, lossless] = webp_probe(bytes); + return {width, height, frameCount, plays, hasAlpha: hasAlpha === 1, lossless: lossless === 1}; +} + +export function openWebpFrameSource(bytes: Uint8Array): WebpFrameSource { + const {width, height, frameCount, plays} = probeWebp(bytes); + const decoder = new AnimDecoder(bytes); + const frameBytes = width * height * 4; + let previousEnd = 0; + let closed = false; + return { + width, + height, + frameCount, + plays, + next() { + if (!decoder.next()) { + return null; + } + const end = decoder.end_timestamp; + const delayMs = end - previousEnd; + previousEnd = end; + return {rgba: new Uint8Array(requireMemory().buffer, decoder.frame_ptr, frameBytes), delayMs}; + }, + close() { + if (closed) return; + closed = true; + decoder.free(); + }, + }; +} + +export function openWebpFrameSink(width: number, height: number, plays: number, rung: WebpRung): WebpFrameSink { + requireMemory(); + const encoder = new AnimEncoder(width, height, plays, rung.lossless); + let elapsed = 0; + let closed = false; + return { + add(rgba, delayMs) { + encoder.add(rgba, Math.round(elapsed), rung.quality, rung.method); + elapsed += Math.min(delayMs, WEBP_MAX_FRAME_DURATION_MS); + }, + finish() { + return encoder.finish(Math.round(elapsed)); + }, + close() { + if (closed) return; + closed = true; + encoder.free(); + }, + }; +} diff --git a/fluxer_app/src/features/ui/utils/ModalUtils.ts b/fluxer_app/src/features/ui/utils/ModalUtils.ts index 87a4f745b..fe0b2edca 100644 --- a/fluxer_app/src/features/ui/utils/ModalUtils.ts +++ b/fluxer_app/src/features/ui/utils/ModalUtils.ts @@ -121,6 +121,30 @@ export interface ModalLogicState { getDefaultLabelId: (source: LabelSource) => string; } +export function usePopOwningModal(): () => void { + const stackPlacement = useContext(ModalStackContext); + const portalHost = usePortalHost(); + const ownerDocument = portalHost?.ownerDocument ?? document; + const stackEntryKeyRef = useRef(null); + useLayoutEffect(() => { + if (stackPlacement === UNSTACKED_MODAL_CONTEXT) { + return; + } + const resolvedKey = ModalState.getKeyAtStackIndex(stackPlacement.stackIndex, ownerDocument); + if (resolvedKey != null) { + stackEntryKeyRef.current = resolvedKey; + } + }, [ownerDocument, stackPlacement]); + return useCallback(() => { + const stackEntryKey = stackEntryKeyRef.current; + if (stackEntryKey != null) { + ModalCommands.popWithKey(stackEntryKey); + return; + } + ModalCommands.pop(); + }, []); +} + export function useModalLogic({ size = 'medium', centered = false, @@ -135,10 +159,9 @@ export function useModalLogic({ const prefersReducedMotion = Accessibility.useReducedMotion; const baseLabelId = useId() || 'modal'; const modalKey = useRef(Math.random().toString(36).substring(7)).current; - const stackPlacement = useContext(ModalStackContext); const portalHost = usePortalHost(); const ownerDocument = portalHost?.ownerDocument ?? document; - const stackEntryKeyRef = useRef(null); + const popOwningModal = usePopOwningModal(); const [labelRegistry, setLabelRegistry] = useState>>({}); const [hasMounted, setHasMounted] = useState(false); const registerLabel = useCallback((source: LabelSource, id: string) => { @@ -159,24 +182,7 @@ export function useModalLogic({ const ids = Object.values(labelRegistry).filter(Boolean); return ids.length > 0 ? ids.join(' ') : undefined; }, [labelRegistry]); - useLayoutEffect(() => { - if (stackPlacement === UNSTACKED_MODAL_CONTEXT) { - return; - } - const resolvedKey = ModalState.getKeyAtStackIndex(stackPlacement.stackIndex, ownerDocument); - if (resolvedKey != null) { - stackEntryKeyRef.current = resolvedKey; - } - }, [ownerDocument, stackPlacement]); useEffect(() => watchBackdropActivation(ownerDocument), [ownerDocument]); - const popOwningModal = useCallback(() => { - const stackEntryKey = stackEntryKeyRef.current; - if (stackEntryKey != null) { - ModalCommands.popWithKey(stackEntryKey); - return; - } - ModalCommands.pop(); - }, []); const modalContextValue = useMemo( () => ({getDefaultLabelId, registerLabel, popOwningModal}), [getDefaultLabelId, popOwningModal, registerLabel], diff --git a/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx b/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx index a9b1c7b5f..85b4a9d35 100644 --- a/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx +++ b/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.tsx @@ -16,11 +16,7 @@ import type {Gif} from '@app/features/expressions/commands/GifCommands'; import {AssetCropModal, AssetType} from '@app/features/expressions/components/modals/AssetCropModal'; import {openAssetSourceModal} from '@app/features/expressions/components/modals/AssetSourceModal'; import {showAnimatedAvifUnsupportedModal} from '@app/features/expressions/utils/AnimatedAvifModalUtils'; -import { - getAnimatedFormatLabel, - isAnimatedFile, - shouldHandleAnimatedNonGifUpload, -} from '@app/features/expressions/utils/AnimatedImageUtils'; +import {inspectImageFile} from '@app/features/expressions/utils/AnimatedImageUtils'; import {getAcceptString, getAssetFormatErrorMessage} from '@app/features/expressions/utils/AssetFormatCopy'; import { formatImageUploadRecommendedHint, @@ -28,7 +24,6 @@ import { } from '@app/features/expressions/utils/AssetUploadHintCopy'; import {downloadGifAsImageFile} from '@app/features/expressions/utils/GifFileDownload'; import {isSvgFile, readImageFileAsUploadDataUrl} from '@app/features/expressions/utils/ImageUploadFileUtils'; -import {isGif} from '@app/features/guild/components/modals/guild_tabs/guild_overview_tab/utils/ImageAsset'; import { CANCEL_DESCRIPTOR, FAILED_TO_PROCESS_CROPPED_IMAGE_DESCRIPTOR, @@ -37,18 +32,18 @@ import { } from '@app/features/i18n/utils/CommonMessageDescriptors'; import {openFilePicker} from '@app/features/messaging/utils/FilePickerUtils'; import {formatFileSize} from '@app/features/messaging/utils/FileUtils'; +import {canDecodeAnimatedAvif} from '@app/features/platform/utils/ImageDecoderInterop'; import * as PremiumModalCommands from '@app/features/premium/commands/PremiumModalCommands'; import {shouldShowPremiumFeatures} from '@app/features/premium/utils/PremiumUtils'; import {Button} from '@app/features/ui/button/Button'; import * as ModalCommands from '@app/features/ui/commands/ModalCommands'; import {modal} from '@app/features/ui/commands/ModalCommands'; -import * as ToastCommands from '@app/features/ui/commands/ToastCommands'; import {RadioGroup} from '@app/features/ui/radio_group/RadioGroup'; import styles from '@app/features/user/components/modals/tabs/my_profile_tab/AvatarUploader.module.css'; import type {ProfileAssetMode} from '@app/features/user/components/modals/tabs/my_profile_tab/ProfileAssetCustomizationStateMachine'; import * as AvatarUtils from '@app/features/user/utils/AvatarUtils'; import {showUserErrorModal} from '@app/features/user/utils/UserErrorModalUtils'; -import {canCropFormat} from '@app/features/voice/utils/MediaCapabilities'; +import {canCropFile} from '@app/features/voice/utils/MediaCapabilities'; import {msg} from '@lingui/core/macro'; import {Trans, useLingui} from '@lingui/react/macro'; import {clsx} from 'clsx'; @@ -92,14 +87,6 @@ const ANIMATED_AVATARS_NOT_AVAILABLE_DESCRIPTOR = msg({ message: 'Animated avatars not available', comment: 'Error message in the avatar uploader.', }); -const CROPPING_ANIMATED_FILES_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR = msg({ - message: "Cropping animated {formatLabel} files isn't supported yet. The original upload will be used.", - comment: 'Description text in the avatar uploader. Preserve {formatLabel}; it is inserted by code.', -}); -const CROPPING_ANIMATED_FILES_WITHOUT_FORMAT_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR = msg({ - message: "Cropping animated files isn't supported yet. The original upload will be used.", - comment: 'Description text in the avatar uploader when the animated image format is unknown.', -}); const AVATAR_MODE_SELECTION_DESCRIPTOR = msg({ message: 'Avatar mode selection', comment: 'Short label in the avatar uploader. Keep it concise.', @@ -185,15 +172,14 @@ export const AvatarUploader = observer( return; } const svg = isSvgFile(file); - if (!svg && !(await canCropFormat(file.type))) { + if (!svg && !(await canCropFile(file))) { showUserErrorModal( i18n._(COULDN_T_UPLOAD_AVATAR_DESCRIPTOR), getAssetFormatErrorMessage(i18n, 'avatar', 'unsupported_mime'), ); return; } - const animated = svg ? false : await isAnimatedFile(file); - const isGifFile = isGif(file); + const {format, animated} = svg ? {format: 'unknown', animated: false} : await inspectImageFile(file); if (animated && !canUploadAnimatedAvatar) { if (shouldShowPremiumFeatures()) { ModalCommands.push( @@ -249,35 +235,17 @@ export const AvatarUploader = observer( } return; } - const base64 = svg ? await readImageFileAsUploadDataUrl(file) : await AvatarUtils.fileToBase64(file); - const animatedHandled = shouldHandleAnimatedNonGifUpload({ - file, - isGif: isGifFile, - animated, - onAnimatedAvif: () => { - showAnimatedAvifUnsupportedModal({i18n}); - }, - onOtherAnimated: () => { - const formatLabel = getAnimatedFormatLabel(file); - ToastCommands.createToast({ - type: 'info', - children: - formatLabel == null - ? i18n._(CROPPING_ANIMATED_FILES_WITHOUT_FORMAT_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR) - : i18n._(CROPPING_ANIMATED_FILES_ISN_T_SUPPORTED_YET_THE_DESCRIPTOR, {formatLabel}), - }); - onAvatarChange(base64); - }, - }); - if (animatedHandled) { + const isAnimatedAvif = animated && format === 'avif'; + if (isAnimatedAvif && !(await canDecodeAnimatedAvif())) { + showAnimatedAvifUnsupportedModal({i18n}); return; } + const base64 = svg ? await readImageFileAsUploadDataUrl(file) : await AvatarUtils.fileToBase64(file); ModalCommands.push( modal(() => ( { const reader = new FileReader(); reader.onload = () => { @@ -292,9 +260,13 @@ export const AvatarUploader = observer( }; reader.readAsDataURL(croppedBlob); }} - onSkip={() => { - onAvatarChange(base64); - }} + onSkip={ + isAnimatedAvif + ? undefined + : () => { + onAvatarChange(base64); + } + } data-flx="user.my-profile-tab.avatar-uploader.handle-avatar-upload.asset-crop-modal" /> )), diff --git a/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx b/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx index c6b138200..7174a5373 100644 --- a/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx +++ b/fluxer_app/src/features/user/components/modals/tabs/my_profile_tab/BannerUploader.tsx @@ -13,6 +13,8 @@ import {isLimitToggleEnabled} from '@app/features/app/utils/LimitUtils'; import type {Gif} from '@app/features/expressions/commands/GifCommands'; import {AssetCropModal, AssetType} from '@app/features/expressions/components/modals/AssetCropModal'; import {openAssetSourceModal} from '@app/features/expressions/components/modals/AssetSourceModal'; +import {showAnimatedAvifUnsupportedModal} from '@app/features/expressions/utils/AnimatedAvifModalUtils'; +import {inspectImageFile} from '@app/features/expressions/utils/AnimatedImageUtils'; import {getAcceptString} from '@app/features/expressions/utils/AssetFormatCopy'; import {formatImageUploadMinimumHint} from '@app/features/expressions/utils/AssetUploadHintCopy'; import {downloadGifAsImageFile} from '@app/features/expressions/utils/GifFileDownload'; @@ -25,6 +27,7 @@ import { } from '@app/features/i18n/utils/CommonMessageDescriptors'; import {openFilePicker} from '@app/features/messaging/utils/FilePickerUtils'; import {formatFileSize} from '@app/features/messaging/utils/FileUtils'; +import {canDecodeAnimatedAvif} from '@app/features/platform/utils/ImageDecoderInterop'; import * as PremiumModalCommands from '@app/features/premium/commands/PremiumModalCommands'; import {shouldShowPremiumFeatures} from '@app/features/premium/utils/PremiumUtils'; import {Button} from '@app/features/ui/button/Button'; @@ -190,12 +193,17 @@ export const BannerUploader = observer( return; } const svg = isSvgFile(file); + const {format, animated} = svg ? {format: 'unknown', animated: false} : await inspectImageFile(file); + const isAnimatedAvif = animated && format === 'avif'; + if (isAnimatedAvif && !(await canDecodeAnimatedAvif())) { + showAnimatedAvifUnsupportedModal({i18n}); + return; + } const base64 = svg ? await readImageFileAsUploadDataUrl(file) : await AvatarUtils.fileToBase64(file); ModalCommands.push( modal(() => ( { const reader = new FileReader(); @@ -211,9 +219,13 @@ export const BannerUploader = observer( }; reader.readAsDataURL(croppedBlob); }} - onSkip={() => { - onBannerChange(base64); - }} + onSkip={ + isAnimatedAvif + ? undefined + : () => { + onBannerChange(base64); + } + } data-flx="user.my-profile-tab.banner-uploader.handle-banner-upload.asset-crop-modal" /> )), diff --git a/fluxer_app/src/features/voice/utils/MediaCapabilities.ts b/fluxer_app/src/features/voice/utils/MediaCapabilities.ts index 90cd21d42..4b4b9e5e9 100644 --- a/fluxer_app/src/features/voice/utils/MediaCapabilities.ts +++ b/fluxer_app/src/features/voice/utils/MediaCapabilities.ts @@ -1,7 +1,9 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import {inspectImageFile} from '@app/features/expressions/utils/AnimatedImageUtils'; import {isSvgMimeType, normalizeImageMimeType} from '@app/features/expressions/utils/ImageUploadFileUtils'; import AppStorage from '@app/features/platform/state/PersistentStorage'; +import {AVIF_ALPHA_PROBE_BASE64} from '@app/features/platform/utils/ImageDecoderInterop'; interface CapabilityResult { avif: boolean; @@ -11,11 +13,10 @@ interface CapabilityResult { uaKey: string; } -const AVIF_PROBE = - 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgIYAQQUDAJEBQYJlAQUAAAAB1FmDuOmIs='; +const AVIF_PROBE = `data:image/avif;base64,${AVIF_ALPHA_PROBE_BASE64}`; const WEBP_PROBE = 'data:image/webp;base64,UklGRhwAAABXRUJQVlA4TBAAAAAvAAAAAAfQ//73v/+BiOh/AAA='; const JXL_PROBE = 'data:image/jxl;base64,/wr6PwH4TWFvLnVMkM4='; -const STORAGE_KEY = 'fluxer:media_caps:v1'; +const STORAGE_KEY = 'fluxer:media_caps:v2'; const PROBE_TIMEOUT_MS = 1500; function buildUaKey(): string { @@ -106,8 +107,6 @@ export async function canCropFormat(mime: string): Promise { } if (isSvgMimeType(m)) return false; if (m === 'application/json' || m === 'application/lottie+json') return false; - const {hasNativeBridge} = await import('@app/features/messaging/utils/MediaNativeBridge'); - if (hasNativeBridge()) return true; const caps = await probeMediaCapabilities(); if (m === 'image/webp') return caps.webp; if (m === 'image/avif') return caps.avif; @@ -118,6 +117,12 @@ export async function canCropFormat(mime: string): Promise { return false; } +export async function canCropFile(file: File): Promise { + if (await canCropFormat(file.type)) return true; + const {format} = await inspectImageFile(file); + return format !== 'unknown' && (await canCropFormat(`image/${format}`)); +} + async function canDecodeViaImage(mime: string): Promise { if (typeof document === 'undefined' || typeof Image === 'undefined') return false; try { diff --git a/fluxer_app/src/types/assets.d.ts b/fluxer_app/src/types/assets.d.ts index 3ffd641a8..6dd46e51f 100644 --- a/fluxer_app/src/types/assets.d.ts +++ b/fluxer_app/src/types/assets.d.ts @@ -59,6 +59,16 @@ declare module '@pkgs/libfluxcore/libfluxcore_bg.wasm' { export default url; } +declare module '@pkgs/libfluxwebp/libfluxwebp_bg.wasm' { + const url: string; + export default url; +} + +declare module '@pkgs/libfluxwebp/libfluxwebp_simd_bg.wasm' { + const url: string; + export default url; +} + declare module '*.onnx' { const url: string; export default url; diff --git a/fluxer_app/src/types/gifenc.d.ts b/fluxer_app/src/types/gifenc.d.ts new file mode 100644 index 000000000..3f5571f6b --- /dev/null +++ b/fluxer_app/src/types/gifenc.d.ts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +declare module 'gifenc' { + export type GifPaletteColor = [number, number, number]; + export interface GifFrameOptions { + palette?: Array; + delay?: number; + repeat?: number; + transparent?: boolean; + transparentIndex?: number; + dispose?: number; + } + export interface GifEncoderInstance { + writeFrame(index: Uint8Array, width: number, height: number, options?: GifFrameOptions): void; + finish(): void; + bytes(): Uint8Array; + bytesView(): Uint8Array; + } + export function GIFEncoder(options?: {initialCapacity?: number}): GifEncoderInstance; +} diff --git a/fluxer_app/src/types/upng-js.d.ts b/fluxer_app/src/types/upng-js.d.ts new file mode 100644 index 000000000..48470d4a2 --- /dev/null +++ b/fluxer_app/src/types/upng-js.d.ts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +declare module 'upng-js' { + export interface UpngImage { + width: number; + height: number; + } + const UPNG: { + decode(buffer: ArrayBuffer, inflated?: Uint8Array): UpngImage; + toRGBA8(image: UpngImage): Array; + }; + export default UPNG; +} diff --git a/fluxer_static/THIRD_PARTY_LICENSES.md b/fluxer_static/THIRD_PARTY_LICENSES.md index 80342e1e8..6c508247f 100644 --- a/fluxer_static/THIRD_PARTY_LICENSES.md +++ b/fluxer_static/THIRD_PARTY_LICENSES.md @@ -17,6 +17,13 @@ by `fluxer_app` from `@sapphi-red/web-noise-suppressor` rather than mirrored here; their licenses and build-time modification disclosure live with the code in `fluxer_app/src/features/voice/utils/noise_suppression/NOTICE.md`. +The `libfluxcore` and `libfluxwebp` WebAssembly modules are built by +`fluxer_app` from Zstandard, libwebp and Emscripten's SSE compatibility headers +rather than mirrored here. Their licenses live with the crates in +`fluxer_app/rust/libfluxcore/NOTICE.md` and `fluxer_app/rust/libfluxwebp/NOTICE.md`, +and the app build ships them next to the modules as `assets/libfluxcore-*.txt` +and `assets/libfluxwebp-*.txt`. + Fonts used to be mirrored here under `fonts/`. They are now bundled by each app that uses them, and their OFL-1.1 licenses and modification disclosure live with the binaries in `packages/fonts/` (`LICENSE-IBM-PLEX.txt`, diff --git a/knip.json b/knip.json index ebbe81afa..410ee47da 100644 --- a/knip.json +++ b/knip.json @@ -8,10 +8,7 @@ "@types/events", "events", "fflate", - "gifenc", - "gifuct-js", - "tailwindcss", - "upng-js" + "tailwindcss" ], "ignoreFiles": [ "fluxer_admin/src/styles/app.css", diff --git a/patches/gifuct-js@2.1.2.patch b/patches/gifuct-js@2.1.2.patch new file mode 100644 index 000000000..fcb5275d8 --- /dev/null +++ b/patches/gifuct-js@2.1.2.patch @@ -0,0 +1,63 @@ +diff --git a/lib/deinterlace.js b/lib/deinterlace.js +index c21b8ca02a128d6c53cd19ef91b3c8cb8c0c0807..18a44628dccf67ab25424deccbfb2ae41084c854 100644 +--- a/lib/deinterlace.js ++++ b/lib/deinterlace.js +@@ -8,13 +8,15 @@ exports.deinterlace = void 0; + /** + * Deinterlace function from https://github.com/shachaf/jsgif + */ ++var deinterlaceBuffer = new Uint8Array(0); ++ + var deinterlace = function deinterlace(pixels, width) { +- var newPixels = new Array(pixels.length); ++ if (deinterlaceBuffer.length !== pixels.length) deinterlaceBuffer = new Uint8Array(pixels.length); ++ var newPixels = deinterlaceBuffer; + var rows = pixels.length / width; + + var cpRow = function cpRow(toRow, fromRow) { +- var fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width); +- newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels)); ++ newPixels.set(pixels.subarray(fromRow * width, (fromRow + 1) * width), toRow * width); + }; // See appendix E. + + +diff --git a/lib/lzw.js b/lib/lzw.js +index 70eb11e7661d4b52a9216e7a8a2509c1a6c2e31e..b757b9407bfeae36d05d22c50b879c8e119d5de9 100644 +--- a/lib/lzw.js ++++ b/lib/lzw.js +@@ -9,12 +9,15 @@ exports.lzw = void 0; + * javascript port of java LZW decompression + * Original java author url: https://gist.github.com/devunwired/4479231 + */ ++var dstBuffer = new Uint8Array(0); ++ + var lzw = function lzw(minCodeSize, data, pixelCount) { + var MAX_STACK_SIZE = 4096; + var nullCode = -1; + var npix = pixelCount; + var available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, i, datum, data_size, first, top, bi, pi; +- var dstPixels = new Array(pixelCount); ++ if (dstBuffer.length !== pixelCount) dstBuffer = new Uint8Array(pixelCount); ++ var dstPixels = dstBuffer; + var prefix = new Array(MAX_STACK_SIZE); + var suffix = new Array(MAX_STACK_SIZE); + var pixelStack = new Array(MAX_STACK_SIZE + 1); // Initialize GIF data stream decoder. +@@ -39,6 +42,7 @@ var lzw = function lzw(minCodeSize, data, pixelCount) { + for (i = 0; i < npix;) { + if (top === 0) { + if (bits < code_size) { ++ if (bi >= data.length) break; + // get the next byte + datum += data[bi] << bits; + bits += 8; +@@ -108,9 +112,7 @@ var lzw = function lzw(minCodeSize, data, pixelCount) { + i++; + } + +- for (i = pi; i < npix; i++) { +- dstPixels[i] = 0; // clear missing pixels +- } ++ if (pi < npix) throw new Error('GIF frame is truncated'); + + return dstPixels; + }; diff --git a/patches/upng-js@2.1.0.patch b/patches/upng-js@2.1.0.patch new file mode 100644 index 000000000..a6edcb504 --- /dev/null +++ b/patches/upng-js@2.1.0.patch @@ -0,0 +1,80 @@ +diff --git a/UPNG.js b/UPNG.js +index 020127a1dab3c599592a56c203fed1708b23507e..a463e9da2504fd5125f97f586ebadf4fcdb4b180 100644 +--- a/UPNG.js ++++ b/UPNG.js +@@ -87,10 +87,10 @@ UPNG.toRGBA8.decodeImage = function(data, w, h, out) + if(depth==16) for(var i=0; i>3]>>(7 -((i&7) )))& 1), al=(gr==tr*255)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } +- if(depth== 2) for(var i=0; i>2]>>(6 -((i&3)<<1)))& 3), al=(gr==tr* 85)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } +- if(depth== 4) for(var i=0; i>1]>>(4 -((i&1)<<2)))&15), al=(gr==tr* 17)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } ++ var tr = out.tabs["tRNS"] != null ? out.tabs["tRNS"] : -1; ++ if(depth== 1) for(var i=0; i>3)]>>(7 -((x&7) )))& 1), al=(gr==tr*255)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } ++ if(depth== 2) for(var i=0; i>2)]>>(6 -((x&3)<<1)))& 3), al=(gr==tr* 85)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } ++ if(depth== 4) for(var i=0; i>1)]>>(4 -((x&1)<<2)))&15), al=(gr==tr* 17)?0:255; bf32[i]=(al<<24)|(gr<<16)|(gr<<8)|gr; } + if(depth== 8) for(var i=0; i>3]; val = (val>>(7-(cdi&7)))&1; +- img[row*bpl + (col>>3)] |= (val << (7-((col&3)<<0))); ++ img[row*bpl + (col>>3)] |= (val << (7-((col&7)<<0))); + } + if(bpp==2) { + var val = data[cdi>>3]; val = (val>>(6-(cdi&7)))&3; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 343712f14..0fd92267b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -471,7 +471,9 @@ patchedDependencies: '@phosphor-icons/react@2.1.10': 9b0b481de857aa7a7525f023baea9da72be4574ff72825e39d959e6979d78eea emscripten-wasm-loader@3.0.3: 65d0567cd2da382764aee3839187feb5284662c4a9f0b755f1e52163c5e36399 eslint-plugin-react-google-translate@1.0.4: 343c47e52467ec6018beff92d73b6ca2cf231399d98116925687451e8bd527d8 + gifuct-js@2.1.2: ea6e8ed3084100883f9206acf5b9031ef6aeaf25236ff59a9cb3dbea3b77ed10 hunspell-asm@4.0.2: 594ff55f398ab3a575ba1b4d090c4838a26e4251a2f1d65ba0f02d5b098d02ae + upng-js@2.1.0: 34ef83d86b7cdf910a393193e3321a239470e7c5e5c7755fd14c30e30db4ea8e importers: @@ -1523,7 +1525,7 @@ importers: version: 1.0.3 gifuct-js: specifier: ^2.1.2 - version: 2.1.2 + version: 2.1.2(patch_hash=ea6e8ed3084100883f9206acf5b9031ef6aeaf25236ff59a9cb3dbea3b77ed10) idna-uts46-hx: specifier: 'catalog:' version: 6.2.1 @@ -1622,7 +1624,7 @@ importers: version: 4.7.1 upng-js: specifier: ^2.1.0 - version: 2.1.0 + version: 2.1.0(patch_hash=34ef83d86b7cdf910a393193e3321a239470e7c5e5c7755fd14c30e30db4ea8e) urlpattern-polyfill: specifier: 'catalog:' version: 10.1.0 @@ -17137,7 +17139,7 @@ snapshots: gifenc@1.0.3: {} - gifuct-js@2.1.2: + gifuct-js@2.1.2(patch_hash=ea6e8ed3084100883f9206acf5b9031ef6aeaf25236ff59a9cb3dbea3b77ed10): dependencies: js-binary-schema-parser: 2.0.3 @@ -20331,7 +20333,7 @@ snapshots: github-url-to-object: 4.0.6 ms: 2.1.3 - upng-js@2.1.0: + upng-js@2.1.0(patch_hash=34ef83d86b7cdf910a393193e3321a239470e7c5e5c7755fd14c30e30db4ea8e): dependencies: pako: 1.0.11 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 388b459df..0defd5f03 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -7,6 +7,7 @@ packages: - fluxer_api/pkgs/* - fluxer_app/pkgs/* - '!fluxer_app/pkgs/libfluxcore' + - '!fluxer_app/pkgs/libfluxwebp' - fluxer_desktop - fluxer_admin - fluxer_docs @@ -207,7 +208,9 @@ patchedDependencies: '@phosphor-icons/react@2.1.10': patches/@phosphor-icons__react@2.1.10.patch emscripten-wasm-loader@3.0.3: patches/emscripten-wasm-loader@3.0.3.patch eslint-plugin-react-google-translate@1.0.4: patches/eslint-plugin-react-google-translate@1.0.4.patch + gifuct-js@2.1.2: patches/gifuct-js@2.1.2.patch hunspell-asm@4.0.2: patches/hunspell-asm@4.0.2.patch + upng-js@2.1.0: patches/upng-js@2.1.0.patch peerDependencyRules: allowedVersions: diff --git a/tools/ci/src/app_dev_server.rs b/tools/ci/src/app_dev_server.rs index cbf5d92c5..2b1bd2ae2 100644 --- a/tools/ci/src/app_dev_server.rs +++ b/tools/ci/src/app_dev_server.rs @@ -444,6 +444,11 @@ fn gather_wasm_inputs(project_root: &Path) -> Result { Path::new("rust/libfluxcore"), |path| !path.contains("/target/"), )?); + inputs.extend(collect_directory_digests( + project_root, + Path::new("rust/libfluxwebp"), + |path| !path.contains("/target/"), + )?); inputs.extend(collect_directory_digests( project_root, &markdown_parser_rust_dir, @@ -601,6 +606,23 @@ mod tests { ); } + #[test] + fn wasm_inputs_cover_the_libfluxwebp_sources_and_headers() { + let app_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../fluxer_app"); + let inputs = gather_wasm_inputs(&app_dir).expect("gather wasm inputs"); + + for key in [ + "rust/libfluxwebp/Cargo.toml", + "rust/libfluxwebp/Cargo.lock", + "rust/libfluxwebp/src/lib.rs", + "rust/libfluxwebp/shim/stdlib.h", + "rust/libfluxwebp/simd/emmintrin.h", + ] { + assert!(inputs.contains_key(key), "missing {key}"); + } + assert!(inputs.keys().all(|key| !key.contains("/target/"))); + } + #[test] fn display_command_quotes_globs() { assert_eq!( diff --git a/tools/ci/src/app_wasm.rs b/tools/ci/src/app_wasm.rs index 3ee2807bf..dc2dce135 100644 --- a/tools/ci/src/app_wasm.rs +++ b/tools/ci/src/app_wasm.rs @@ -15,6 +15,11 @@ const LIBFLUXCORE_WASM_BINDGEN_VERSION: &str = "0.2.128"; const LIBFLUXCORE_WASM_SIZE_BUDGET_BYTES: u64 = 300 * 1024; const LIBFLUXCORE_WRAPPER_JS: &str = include_str!("../templates/libfluxcore_wrapper.js"); const LIBFLUXCORE_WRAPPER_DTS: &str = include_str!("../templates/libfluxcore_wrapper.d.ts"); +const LIBFLUXWEBP_SIMD_WASM_SIZE_BUDGET_BYTES: u64 = 672 * 1024; +const LIBFLUXWEBP_SCALAR_WASM_SIZE_BUDGET_BYTES: u64 = 288 * 1024; +const LIBFLUXWEBP_WASM_IMPORT_MODULE: &str = "./libfluxwebp_bg.js"; +const WASM_TARGET_RUSTFLAGS_ENV: &str = "CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUSTFLAGS"; +const WASM_CFLAGS_ENV: &str = "CFLAGS_wasm32_unknown_unknown"; #[derive(Debug, Args, Clone)] pub struct BuildAppWasmArgs { @@ -31,7 +36,8 @@ pub struct BuildMarkdownParserWasmArgs { pub fn run_build_app_wasm(args: BuildAppWasmArgs) -> Result<()> { let app_dir = args.app_dir.unwrap_or(resolve_app_dir()?); build_markdown_parser_wasm(&app_dir)?; - build_libfluxcore_wasm(&app_dir) + build_libfluxcore_wasm(&app_dir)?; + build_libfluxwebp_wasm(&app_dir) } pub fn run_build_markdown_parser_wasm(args: BuildMarkdownParserWasmArgs) -> Result<()> { @@ -97,8 +103,8 @@ fn discover_wasm_clang_with( } Err(anyhow!( - "No clang with a wasm32 backend was found, so cc-rs cannot compile zstd-sys for \ - wasm32-unknown-unknown.\nTried: {}\nOn macOS the Xcode clang has no wasm32 target; \ + "No clang with a wasm32 backend was found, so cc-rs cannot compile the C dependencies \ + for wasm32-unknown-unknown.\nTried: {}\nOn macOS the Xcode clang has no wasm32 target; \ install a full LLVM and retry:\n brew install llvm\nOr point the build at one \ explicitly:\n export {WASM_CC_ENV}=/path/to/clang\n export {WASM_AR_ENV}=/path/to/llvm-ar", seen.iter() @@ -199,19 +205,12 @@ fn build_libfluxcore_wasm(app_dir: &Path) -> Result<()> { } run_command(apply_wasm_c_toolchain(build)?)?; - let wasm_bindgen = ensure_wasm_bindgen_cli()?; let temp = TempDir::new().context("Failed to create libfluxcore wasm-bindgen temp dir")?; let bindgen_dir = temp.path().join("bindgen"); - fs::create_dir_all(&bindgen_dir) - .with_context(|| format!("Failed to create {}", bindgen_dir.display()))?; - - run_command( - CommandSpec::new(wasm_bindgen) - .args(["--target", "web", "--out-dir"]) - .arg(&bindgen_dir) - .args(["--out-name", "libfluxcore"]) - .arg(rust_package_dir.join("target/wasm32-unknown-unknown/release/libfluxcore.wasm")) - .current_dir(&rust_package_dir), + run_wasm_bindgen( + &rust_package_dir.join("target/wasm32-unknown-unknown/release/libfluxcore.wasm"), + &bindgen_dir, + "libfluxcore", )?; let bindgen_js_path = bindgen_dir.join("libfluxcore.js"); @@ -274,14 +273,7 @@ fn build_libfluxcore_wasm(app_dir: &Path) -> Result<()> { fs::write(out_dir.join("README.md"), libfluxcore_readme_content()) .with_context(|| format!("Failed to write {}", out_dir.join("README.md").display()))?; - let wasm_size = file_size(&wasm_path)? - .ok_or_else(|| anyhow!("libfluxcore build did not emit {}", wasm_path.display()))?; - ensure!( - wasm_size <= LIBFLUXCORE_WASM_SIZE_BUDGET_BYTES, - "libfluxcore_bg.wasm is {}, over the {} budget", - format_bytes(wasm_size), - format_bytes(LIBFLUXCORE_WASM_SIZE_BUDGET_BYTES) - ); + let wasm_size = check_wasm_size_budget(&wasm_path, LIBFLUXCORE_WASM_SIZE_BUDGET_BYTES)?; let size_comparison = match previous_wasm_size { Some(previous) => format!("{} -> {}", format_bytes(previous), format_bytes(wasm_size)), @@ -295,6 +287,298 @@ fn build_libfluxcore_wasm(app_dir: &Path) -> Result<()> { Ok(()) } +fn run_wasm_bindgen(wasm: &Path, out_dir: &Path, out_name: &str) -> Result<()> { + let wasm_bindgen = ensure_wasm_bindgen_cli()?; + fs::create_dir_all(out_dir) + .with_context(|| format!("Failed to create {}", out_dir.display()))?; + run_command( + CommandSpec::new(wasm_bindgen) + .args(["--target", "web", "--out-dir"]) + .arg(out_dir) + .args(["--out-name", out_name]) + .arg(wasm), + ) +} + +fn check_wasm_size_budget(path: &Path, budget: u64) -> Result { + let size = + file_size(path)?.ok_or_else(|| anyhow!("wasm build did not emit {}", path.display()))?; + ensure!( + size <= budget, + "{} is {}, over the {} budget", + path.file_name() + .map(|name| name.to_string_lossy().into_owned()) + .unwrap_or_default(), + format_bytes(size), + format_bytes(budget) + ); + Ok(size) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum LibfluxwebpVariant { + Simd, + Scalar, +} + +impl LibfluxwebpVariant { + fn name(self) -> &'static str { + match self { + Self::Simd => "simd", + Self::Scalar => "scalar", + } + } + + fn installed_wasm_name(self) -> &'static str { + match self { + Self::Simd => "libfluxwebp_simd_bg.wasm", + Self::Scalar => "libfluxwebp_bg.wasm", + } + } + + fn size_budget(self) -> u64 { + match self { + Self::Simd => LIBFLUXWEBP_SIMD_WASM_SIZE_BUDGET_BYTES, + Self::Scalar => LIBFLUXWEBP_SCALAR_WASM_SIZE_BUDGET_BYTES, + } + } + + fn cflags(self, crate_dir: &Path) -> String { + let shim = crate_dir.join("shim"); + match self { + Self::Simd => format!( + "-isystem {} -isystem {} -msimd128 -DEMSCRIPTEN -D__SSE__ -D__SSE2__ \ + -DWEBP_HAVE_SSE2 -DNDEBUG -O3", + shim.display(), + crate_dir.join("simd").display() + ), + Self::Scalar => format!("-isystem {} -DNDEBUG -Oz", shim.display()), + } + } +} + +fn build_libfluxwebp_wasm(app_dir: &Path) -> Result<()> { + let crate_dir = app_dir.join("rust/libfluxwebp"); + let crate_dir = fs::canonicalize(&crate_dir) + .with_context(|| format!("Failed to resolve {}", crate_dir.display()))?; + let out_dir = app_dir.join("pkgs/libfluxwebp"); + let temp = TempDir::new().context("Failed to create libfluxwebp wasm-bindgen temp dir")?; + + let mut bindgen_dirs = Vec::new(); + for variant in [LibfluxwebpVariant::Simd, LibfluxwebpVariant::Scalar] { + let target_dir = crate_dir.join("target").join(variant.name()); + let mut build = CommandSpec::new("cargo") + .args([ + "build", + "--release", + "--locked", + "--target", + "wasm32-unknown-unknown", + ]) + .env("CARGO_TARGET_DIR", target_dir.as_os_str()) + .env(WASM_CFLAGS_ENV, variant.cflags(&crate_dir)) + .current_dir(&crate_dir); + build = match variant { + LibfluxwebpVariant::Simd => { + build.env(WASM_TARGET_RUSTFLAGS_ENV, "-C target-feature=+simd128") + } + LibfluxwebpVariant::Scalar => build.env_remove(WASM_TARGET_RUSTFLAGS_ENV), + }; + run_command(apply_wasm_c_toolchain(build)?)?; + + let bindgen_dir = temp.path().join(variant.name()); + run_wasm_bindgen( + &target_dir.join("wasm32-unknown-unknown/release/libfluxwebp.wasm"), + &bindgen_dir, + "libfluxwebp", + )?; + let wasm_path = bindgen_dir.join("libfluxwebp_bg.wasm"); + let wasm = fs::read(&wasm_path) + .with_context(|| format!("Failed to read {}", wasm_path.display()))?; + ensure_wasm_imports_only_from(&wasm, LIBFLUXWEBP_WASM_IMPORT_MODULE) + .with_context(|| format!("libfluxwebp {} wasm import gate", variant.name()))?; + bindgen_dirs.push((variant, bindgen_dir)); + } + + let (_, reference_dir) = &bindgen_dirs[0]; + for file in [ + "libfluxwebp.js", + "libfluxwebp.d.ts", + "libfluxwebp_bg.wasm.d.ts", + ] { + let reference = + fs::read(reference_dir.join(file)).with_context(|| format!("Failed to read {file}"))?; + for (variant, dir) in &bindgen_dirs[1..] { + let other = + fs::read(dir.join(file)).with_context(|| format!("Failed to read {file}"))?; + ensure!( + other == reference, + "libfluxwebp {} glue {file} differs from the simd build", + variant.name() + ); + } + } + + fs::create_dir_all(&out_dir) + .with_context(|| format!("Failed to create {}", out_dir.display()))?; + write_with_spdx( + &out_dir.join("libfluxwebp.js"), + &fs::read_to_string(reference_dir.join("libfluxwebp.js")) + .context("Failed to read libfluxwebp.js")?, + )?; + write_with_spdx( + &out_dir.join("libfluxwebp.d.ts"), + &fs::read_to_string(reference_dir.join("libfluxwebp.d.ts")) + .context("Failed to read libfluxwebp.d.ts")?, + )?; + for installed in ["libfluxwebp_bg.wasm.d.ts", "libfluxwebp_simd_bg.wasm.d.ts"] { + fs::copy( + reference_dir.join("libfluxwebp_bg.wasm.d.ts"), + out_dir.join(installed), + ) + .with_context(|| format!("Failed to install {installed}"))?; + } + + for (variant, dir) in &bindgen_dirs { + let installed = out_dir.join(variant.installed_wasm_name()); + let previous = file_size(&installed)?; + fs::copy(dir.join("libfluxwebp_bg.wasm"), &installed) + .with_context(|| format!("Failed to install {}", installed.display()))?; + let size = check_wasm_size_budget(&installed, variant.size_budget())?; + let size_comparison = match previous { + Some(previous) => format!("{} -> {}", format_bytes(previous), format_bytes(size)), + None => "no previous artifact".to_string(), + }; + println!( + "{} size: {size_comparison} (budget {})", + variant.installed_wasm_name(), + format_bytes(variant.size_budget()) + ); + } + + Ok(()) +} + +fn ensure_wasm_imports_only_from(wasm: &[u8], allowed: &str) -> Result<()> { + let foreign: Vec = wasm_import_modules(wasm)? + .into_iter() + .filter(|module| module != allowed) + .collect(); + ensure!( + foreign.is_empty(), + "wasm imports from {} instead of only {allowed}; a C dependency probably references a \ + libc symbol the shim does not provide", + foreign.join(", ") + ); + Ok(()) +} + +fn wasm_import_modules(wasm: &[u8]) -> Result> { + ensure!( + wasm.len() >= 8 && wasm[..4] == *b"\0asm", + "not a wasm module" + ); + let mut reader = WasmReader { + bytes: wasm, + pos: 8, + }; + let mut modules = Vec::new(); + while reader.pos < wasm.len() { + let id = reader.byte()?; + let size = reader.leb()? as usize; + let end = reader + .pos + .checked_add(size) + .filter(|end| *end <= wasm.len()) + .ok_or_else(|| anyhow!("wasm section {id} overruns the module"))?; + if id == 2 { + let count = reader.leb()?; + for _ in 0..count { + let module = reader.name()?; + reader.name()?; + reader.import_desc()?; + if !modules.contains(&module) { + modules.push(module); + } + } + } + reader.pos = end; + } + Ok(modules) +} + +struct WasmReader<'a> { + bytes: &'a [u8], + pos: usize, +} + +impl WasmReader<'_> { + fn byte(&mut self) -> Result { + let value = *self + .bytes + .get(self.pos) + .ok_or_else(|| anyhow!("wasm module ends early"))?; + self.pos += 1; + Ok(value) + } + + fn leb(&mut self) -> Result { + let mut value = 0u64; + for shift in (0..64).step_by(7) { + let byte = self.byte()?; + value |= u64::from(byte & 0x7f) << shift; + if byte & 0x80 == 0 { + return Ok(value); + } + } + Err(anyhow!("wasm LEB128 value is too long")) + } + + fn name(&mut self) -> Result { + let len = self.leb()? as usize; + let end = self + .pos + .checked_add(len) + .filter(|end| *end <= self.bytes.len()) + .ok_or_else(|| anyhow!("wasm name overruns the module"))?; + let name = String::from_utf8_lossy(&self.bytes[self.pos..end]).into_owned(); + self.pos = end; + Ok(name) + } + + fn limits(&mut self) -> Result<()> { + let flags = self.byte()?; + self.leb()?; + if flags & 1 != 0 { + self.leb()?; + } + Ok(()) + } + + fn import_desc(&mut self) -> Result<()> { + match self.byte()? { + 0 => { + self.leb()?; + } + 1 => { + self.byte()?; + self.limits()?; + } + 2 => self.limits()?, + 3 => { + self.byte()?; + self.byte()?; + } + 4 => { + self.byte()?; + self.leb()?; + } + kind => return Err(anyhow!("unknown wasm import kind {kind}")), + } + Ok(()) + } +} + fn patch_libfluxcore_bindgen_js(content: &str) -> Result { const MARKER: &str = "\nasync function __wbg_load(module, imports) {"; const RESET_EXPORT: &str = r#" @@ -522,6 +806,73 @@ export const MARKDOWN_PARSER_WASM_BASE64 =\n\ assert_eq!(discover_wasm_ar(&clang), Some(archiver)); } + fn wasm_with_imports(imports: &[(&str, &str)]) -> Vec { + let mut section = vec![imports.len() as u8]; + for (module, field) in imports { + section.push(module.len() as u8); + section.extend_from_slice(module.as_bytes()); + section.push(field.len() as u8); + section.extend_from_slice(field.as_bytes()); + section.extend_from_slice(&[0, 0]); + } + let mut wasm = b"\0asm\x01\0\0\0".to_vec(); + wasm.extend_from_slice(&[1, 4, 1, 0x60, 0, 0]); + wasm.push(2); + wasm.push(section.len() as u8); + wasm.extend_from_slice(§ion); + wasm.extend_from_slice(&[5, 3, 1, 0, 17]); + wasm + } + + #[test] + fn wasm_import_gate_accepts_a_bindgen_only_module() { + let wasm = wasm_with_imports(&[ + ("./libfluxwebp_bg.js", "__wbg_new_1"), + ("./libfluxwebp_bg.js", "__wbindgen_throw"), + ]); + assert_eq!( + wasm_import_modules(&wasm).expect("parse"), + vec!["./libfluxwebp_bg.js".to_string()] + ); + ensure_wasm_imports_only_from(&wasm, LIBFLUXWEBP_WASM_IMPORT_MODULE) + .expect("bindgen imports pass"); + } + + #[test] + fn wasm_import_gate_rejects_a_libc_import() { + let wasm = wasm_with_imports(&[ + ("./libfluxwebp_bg.js", "__wbindgen_throw"), + ("env", "fopen"), + ]); + let message = ensure_wasm_imports_only_from(&wasm, LIBFLUXWEBP_WASM_IMPORT_MODULE) + .expect_err("env import must fail") + .to_string(); + assert!(message.contains("env"), "{message}"); + } + + #[test] + fn wasm_import_parser_rejects_truncated_modules() { + let mut wasm = wasm_with_imports(&[("env", "fopen")]); + wasm.truncate(wasm.len() - 12); + assert!(wasm_import_modules(&wasm).is_err()); + assert!(wasm_import_modules(b"\0asm").is_err()); + } + + #[test] + fn libfluxwebp_cflags_select_sse2_for_simd_and_oz_for_scalar() { + let crate_dir = Path::new("/repo/fluxer_app/rust/libfluxwebp"); + assert_eq!( + LibfluxwebpVariant::Simd.cflags(crate_dir), + "-isystem /repo/fluxer_app/rust/libfluxwebp/shim -isystem \ + /repo/fluxer_app/rust/libfluxwebp/simd -msimd128 -DEMSCRIPTEN -D__SSE__ -D__SSE2__ \ + -DWEBP_HAVE_SSE2 -DNDEBUG -O3" + ); + assert_eq!( + LibfluxwebpVariant::Scalar.cflags(crate_dir), + "-isystem /repo/fluxer_app/rust/libfluxwebp/shim -DNDEBUG -Oz" + ); + } + #[test] fn libfluxcore_bindgen_dts_reset_hook_is_inserted() { let content = "export function is_animated_image(input: Uint8Array): boolean;\nexport type InitInput = RequestInfo;"; diff --git a/tools/ci/src/ci_workflow.rs b/tools/ci/src/ci_workflow.rs index 5c1297cd0..12a0e7e55 100644 --- a/tools/ci/src/ci_workflow.rs +++ b/tools/ci/src/ci_workflow.rs @@ -123,6 +123,12 @@ fn app_wasm_artifacts(root: &Path) -> Vec { app_dir.join("pkgs/libfluxcore/libfluxcore_bg.wasm"), app_dir.join("pkgs/libfluxcore/libfluxcore_bg.wasm.d.ts"), app_dir.join("pkgs/libfluxcore/package.json"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp.js"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp.d.ts"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp_bg.wasm"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp_bg.wasm.d.ts"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp_simd_bg.wasm"), + app_dir.join("pkgs/libfluxwebp/libfluxwebp_simd_bg.wasm.d.ts"), app_dir.join("src/features/messaging/utils/markdown/parser/MarkdownParserWasmBytes.ts"), ] }