Compare commits

..

68 Commits

Author SHA1 Message Date
schlagmichdoch d6287c4cf0 Increase version to v1.10.7
## Enhancements
- Implemented drag and drop into text fields
- Tidy up code
- Translations update from Hosted Weblate (Italian)

## Fixes
- Received URLs with single letter subdomains not hydrated into links #258
- Button does not change color on hover (#262 + #263)
- On Windows Edge, PeerUI shows „preparing“ when file selector is cancelled (#257)
2024-02-09 03:53:53 +01:00
schlagmichdoch c83e55b448 Merge pull request #253 from weblate/weblate-pairdrop-pairdrop-spa
Translations update from Hosted Weblate
2024-02-09 03:46:54 +01:00
Hosted Weblate 49160f9b02 Translated using Weblate (Italian)
Currently translated at 100.0% (166 of 166 strings)

Translated using Weblate (Italian)

Currently translated at 87.9% (146 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Luca FiltroMan <FiltroMan@users.noreply.hosted.weblate.org>
Co-authored-by: Radosław Rudner <radek.rud112@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/it/
Translation: PairDrop/pairdrop-spa
2024-02-09 03:46:01 +01:00
schlagmichdoch 7be2830a08 Merge pull request #259 from schlagmichdoch/fix_url_hydration
Prepare next patch version
2024-02-09 03:44:41 +01:00
schlagmichdoch 1f3dd080a0 Fix canceling file selector on Windows Edge sometimes blocks UI (#257) 2024-02-09 03:41:41 +01:00
schlagmichdoch 5d709966af Fix button color change on hover (fixes #262) 2024-02-09 03:40:21 +01:00
schlagmichdoch 99b0c6ff01 Fix URL not replaced with link node (fixes #258), beautify text via regex without rendering it, and fix execution order 2024-02-01 14:25:38 +01:00
schlagmichdoch 76e08927de Enable drag and drop and pasting in text fields; Tidy up existing drag and drop code. 2024-02-01 14:25:38 +01:00
schlagmichdoch 9118b0ae06 Use default line-height for textareas 2024-02-01 14:25:38 +01:00
schlagmichdoch b36105b1cf Remove trailing back quote` from command in how-to.md
Fixes #256
2024-01-30 19:09:09 +01:00
schlagmichdoch ad4f727d19 Merge pull request #212 from comradekingu/patch-2
README reworked
2024-01-30 19:05:00 +01:00
schlagmichdoch 3fa0873bc4 Increase version to v1.10.6
## Changes
- Fix loading error on older iOS and Mac versions
- Fix websocket-fallback info text position
- Translations update from Hosted Weblate (Turkish, Japanese, Indonesian)
2024-01-21 20:09:11 +01:00
schlagmichdoch a03482bc7f Merge branch 'master' into translate 2024-01-21 20:01:09 +01:00
schlagmichdoch 40aa46fdd9 Merge pull request #245 from weblate/weblate-pairdrop-pairdrop-spa
Translations update from Hosted Weblate
2024-01-21 19:56:08 +01:00
Hosted Weblate 9003094e49 Translated using Weblate (Indonesian)
Currently translated at 93.9% (156 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Reza Almanda <rezaalmanda27@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/id/
Translation: PairDrop/pairdrop-spa
2024-01-21 19:55:10 +01:00
Hosted Weblate 0459a361c3 Translated using Weblate (Japanese)
Currently translated at 98.1% (163 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: RintanBroadleaf <rintanbroadleaf@outlook.jp>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/ja/
Translation: PairDrop/pairdrop-spa
2024-01-21 19:55:10 +01:00
Hosted Weblate 10a669d7c6 Translated using Weblate (Turkish)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Oğuz Ersen <oguz@ersen.moe>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/tr/
Translation: PairDrop/pairdrop-spa
2024-01-21 19:55:10 +01:00
schlagmichdoch 3fbca72d74 Merge pull request #243 from schlagmichdoch/fix-regex-error
Fix Error Invalid Group Specifier Name on MacOS Safari and iOS Firefox on older MacOS/iOS
2024-01-21 19:53:57 +01:00
Allan Nordhøy f048c4f1bd GIF 2024-01-13 13:46:19 +00:00
Allan Nordhøy 6c1672ba25 Fixing conflicts, better 2024-01-13 13:44:44 +00:00
Allan Nordhøy caf19bdb45 Merge branch 'master' into patch-2 2024-01-13 13:25:31 +00:00
Allan Nordhøy 5dcda58ce5 Structure and requested fixes 2024-01-13 13:18:06 +00:00
schlagmichdoch 59360fb047 Fix websocket-fallback info text not centered when line is broken 2024-01-12 01:43:08 +01:00
schlagmichdoch 2e15a018da Fix Error Invalid Group Specifier Name on Safari by removing REGEX lookbehind group construct (fixes #239) 2024-01-12 01:23:14 +01:00
schlagmichdoch 041261be2a Fix url argument case ?share_target 2024-01-06 16:15:30 +01:00
schlagmichdoch f152645452 Increase version to v1.10.5
## Changes
- Fix Zip Release workflow
2024-01-06 15:41:39 +01:00
schlagmichdoch a7f5d336c3 Fix Zip Release workflow: wrong upload path 2024-01-06 15:37:05 +01:00
schlagmichdoch c9e4510f65 Increase version to v1.10.4
## Changes
- Use blue icons as favicons for better contrast (#235)
- Fix pairdrop-cli exit on error
- Enhancement: On release: Prevent nesting of pairdrop-cli folder inside pairdrop-cli.zip
- Enhance documentation for pairdrop-cli and sending from context menu (#236)
- Translations update from Hosted Weblate
2024-01-06 15:30:20 +01:00
schlagmichdoch 70f74923e6 Merge branch 'master' into translate 2024-01-06 15:23:21 +01:00
schlagmichdoch 6217042f12 Merge pull request #229 from weblate/weblate-pairdrop-pairdrop-spa
Translations update from Hosted Weblate
2024-01-06 15:22:42 +01:00
Hosted Weblate 4659ef2041 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Eric <zxmegaxqug@hldrive.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/zh_Hans/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:30 +01:00
Hosted Weblate a21881b7ca Translated using Weblate (Kannada)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Chethan <76928501+ch3thanhs@users.noreply.github.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/kn/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
Hosted Weblate f589e9471e Translated using Weblate (Indonesian)
Currently translated at 86.7% (144 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: schlagmichdoch <sonnig-02.hieven@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/id/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
Hosted Weblate 067117159a Translated using Weblate (Arabic)
Currently translated at 83.7% (139 of 166 strings)

Co-authored-by: schlagmichdoch <sonnig-02.hieven@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/ar/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
Hosted Weblate d901ca031a Translated using Weblate (Italian)
Currently translated at 87.3% (145 of 166 strings)

Co-authored-by: schlagmichdoch <sonnig-02.hieven@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/it/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
Hosted Weblate 21fa6f07d8 Translated using Weblate (Romanian)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Alexandru-Ionut Chiuta <chiuta@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/ro/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
Hosted Weblate f49b800f9e Translated using Weblate (German)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: schlagmichdoch <sonnig-02.hieven@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/de/
Translation: PairDrop/pairdrop-spa
2024-01-06 15:20:29 +01:00
schlagmichdoch 1a9fa8e60a Enhance the documentation for pairdrop-cli and add shell commands 2024-01-06 15:13:48 +01:00
schlagmichdoch 79cc8e5590 Release file pairdrop-cli.zip should only include contents of folder pairdrop-cli instead of the folder itself 2024-01-06 15:11:18 +01:00
schlagmichdoch 89addd6649 pairdrop-cli: Exit application if config file cannot be created on first run 2024-01-06 15:09:08 +01:00
schlagmichdoch ff883fb994 Use blue icons as favicons too to prevent white logo on white background (fixes #235) 2024-01-04 17:41:20 +01:00
schlagmichdoch ccb2170287 Increase version to v1.10.3 2024-01-03 17:18:04 +01:00
schlagmichdoch 3454eebf37 Merge branch 'fix-small-issues' 2024-01-03 17:15:20 +01:00
schlagmichdoch b6203288bf Merge pull request #234 from schlagmichdoch/dependabot/npm_and_yarn/ws-8.16.0
Bump ws from 8.15.0 to 8.16.0
2024-01-03 17:14:47 +01:00
schlagmichdoch bea0fa5b9c Fix color of URLs on receive text dialog 2024-01-03 17:11:38 +01:00
schlagmichdoch 48090ec41c Fix x-paper width (fixed #233) 2024-01-03 16:54:43 +01:00
schlagmichdoch 229084fab3 Properly style indented text via css 2024-01-03 16:54:01 +01:00
schlagmichdoch d58f380565 Prevent executing _onCopy() when text is selected on receive text dialog 2024-01-03 16:53:09 +01:00
schlagmichdoch 676c68b6e7 Clear text field when closing receive text dialog 2024-01-03 16:52:26 +01:00
schlagmichdoch dd0dc21db5 Fix replacement of sent URLs with actual links (fixes #231) 2024-01-03 16:51:44 +01:00
dependabot[bot] 4e72339479 Bump ws from 8.15.0 to 8.16.0
Bumps [ws](https://github.com/websockets/ws) from 8.15.0 to 8.16.0.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.15.0...8.16.0)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 04:45:23 +00:00
schlagmichdoch c3e92d7d4c Increase version to v1.10.2 2023-12-15 23:54:20 +01:00
schlagmichdoch b90924af68 Merge branch 'master' into translate 2023-12-15 23:51:11 +01:00
schlagmichdoch 4f80ab4401 Merge pull request #226 from schlagmichdoch/parallelize_asset_loading
Parallelize and speed up loading of deferred assets, refactor code, and fix `RTC_CONFIG` env var
2023-12-15 23:49:54 +01:00
schlagmichdoch f299c90f47 Merge pull request #224 from weblate/weblate-pairdrop-pairdrop-spa
Translations update from Hosted Weblate
2023-12-15 23:47:25 +01:00
schlagmichdoch 6737dcacf7 Defer scripts and prevent deferred stylesheets from being render blocking 2023-12-15 23:40:30 +01:00
Hosted Weblate 5d39bf4a76 Translated using Weblate (Kannada)
Currently translated at 100.0% (161 of 161 strings)

Co-authored-by: Chethan <76928501+ch3thanhs@users.noreply.github.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/kn/
Translation: PairDrop/pairdrop-spa
2023-12-15 21:08:45 +00:00
Hosted Weblate 5c70c873ab Translated using Weblate (Spanish)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/es/
Translation: PairDrop/pairdrop-spa
2023-12-15 21:08:45 +00:00
Hosted Weblate b336c75b72 Translated using Weblate (German)
Currently translated at 100.0% (166 of 166 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: schlagmichdoch <sonnig-02.hieven@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/de/
Translation: PairDrop/pairdrop-spa
2023-12-15 21:08:44 +00:00
Hosted Weblate b3f5619f2d Translated using Weblate (Turkish)
Currently translated at 100.0% (161 of 161 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Æthereal <fr.izgi.kn@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/pairdrop/pairdrop-spa/tr/
Translation: PairDrop/pairdrop-spa
2023-12-15 21:08:44 +00:00
schlagmichdoch 939ca3d35d Enable Kannada translation 2023-12-15 22:08:25 +01:00
schlagmichdoch c2ee459231 Fix error if env var RTC_CONFIG=false (as in default docker-compose.yml and docs) 2023-12-15 21:22:33 +01:00
schlagmichdoch c08b324d6a Refactor localization.js 2023-12-15 21:20:35 +01:00
schlagmichdoch d3a623d352 Refactor for loops to specify imagesOnly to Array.prototype.every() 2023-12-15 21:19:56 +01:00
schlagmichdoch d8f9532039 Parallelize asset loading 2023-12-15 19:39:26 +01:00
schlagmichdoch 9847feeb52 Fix SIGNALING_SERVER documentation 2023-12-13 18:50:33 +01:00
schlagmichdoch 4a5a2ceb67 Merge branch 'master' into patch-2 2023-12-04 21:16:41 +01:00
Allan Nordhøy 214d557feb README reworked 2023-11-30 01:20:28 +00:00
32 changed files with 714 additions and 401 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ If applicable, add screenshots to help explain your problem.
**Bug occurs on official PairDrop instance https://pairdrop.net/** **Bug occurs on official PairDrop instance https://pairdrop.net/**
No | Yes No | Yes
Version: v1.10.1 Version: v1.10.7
**Bug occurs on self-hosted PairDrop instance** **Bug occurs on self-hosted PairDrop instance**
No | Yes No | Yes
@@ -44,7 +44,7 @@ No | Yes
**Self-Hosted Setup** **Self-Hosted Setup**
Proxy: Nginx | Apache2 Proxy: Nginx | Apache2
Deployment: docker run | docker compose | npm run start:prod Deployment: docker run | docker compose | npm run start:prod
Version: v1.10.1 Version: v1.10.7
**Additional context** **Additional context**
Add any other context about the problem here. Add any other context about the problem here.
+2 -3
View File
@@ -26,12 +26,11 @@ jobs:
- name: Archive Release - name: Archive Release
uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 # v0.7.6 uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 # v0.7.6
with: with:
type: 'zip'
filename: 'pairdrop-cli.zip' filename: 'pairdrop-cli.zip'
path: 'pairdrop-cli' directory: 'pairdrop-cli'
exclusions: '*.git* /*node_modules/* .editorconfig' exclusions: '*.git* /*node_modules/* .editorconfig'
- name: Upload Release - name: Upload Release
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0 uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
with: with:
artifacts: "pairdrop-cli.zip" artifacts: "pairdrop-cli/pairdrop-cli.zip"
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
+86 -92
View File
@@ -3,133 +3,127 @@
<img src="public/images/android-chrome-512x512.png" alt="Logo" width="150" height="150"> <img src="public/images/android-chrome-512x512.png" alt="Logo" width="150" height="150">
</a> </a>
<h1>PairDrop</h1> # _Send it_, with [PairDrop](https://pairdrop.net)
<p> <p>
Local file sharing in your browser. Inspired by Apple's AirDrop. Local file sharing <a href="https://pairdrop.net"><strong>in your web browser</strong></a>.
<br />
<a href="https://pairdrop.net"><strong>Explore »</strong></a>
<br /> <br />
<br /> <br />
<a href="https://github.com/schlagmichdoch/PairDrop/issues">Report Bug</a> <a href="https://github.com/schlagmichdoch/PairDrop/issues">Report a bug</a>
· <br />
<a href="https://github.com/schlagmichdoch/PairDrop/issues">Request Feature</a> <a href="https://github.com/schlagmichdoch/PairDrop/issues">Request feature</a>
</p> </p>
</div> </div>
## Features ## Features
[PairDrop](https://pairdrop.net) is a sublime alternative to AirDrop that works on all platforms. File sharing on your local network that works on all platforms.
- File Sharing on your local network - A multi-platform AirDrop-like solution that works.
- Send images, documents or text via peer to peer connection to devices on the same local network. - Send images, documents or text via peer-to-peer connection to devices on the same local network.
- Internet Transfers - Internet transfers
- Join temporary public rooms to transfer files easily over the internet! - Join temporary public rooms to transfer files easily over the Internet.
- Web-Application - Web-app
- As it is web based, it runs on all devices. - Works on all devices with a modern web-browser.
Send a file from your phone to your laptop?
<br>Share photos in original quality with friends using Android and iOS?
<br>Share private files peer-to-peer between Linux systems?
You want to quickly send a file from your phone to your laptop? <img src="docs/pairdrop_screenshot_mobile.gif" alt="Screenshot GIF showing PairDrop in use" style="width: 300px">
<br>You want to share photos in original quality with friends that use a mixture of Android and iOS?
<br>You want to share private files peer to peer between Linux systems?
<br>AirDrop is unreliable again?
<br>_Send it with PairDrop!_
Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop) ## Differences to the [Snapdrop](https://github.com/RobinLinus/snapdrop) it is based on
<details><summary>List view</summary>
## Differences to Snapdrop ### Paired Devices and Public Rooms — Internet Transfer
<details><summary>Click to expand</summary> * Transfer files over the Internet between paired devices or by entering temporary public rooms.
* Connect to devices in complex network environments (public Wi-Fi, company network, iCloud Private Relay, VPN, etc.).
### Paired Devices and Public Rooms - Internet Transfer
* Transfer files over the internet between paired devices or by entering temporary public rooms.
* Connect to devices in complex network environments (public Wi-Fi, company network, Apple Private Relay, VPN etc.).
* Connect to devices on your mobile hotspot. * Connect to devices on your mobile hotspot.
* Devices outside your local network that are behind a NAT are connected automatically via the PairDrop TURN server. * Devices outside of your local network that are behind a NAT are auto-connected via the PairDrop TURN server.
* Connect to devices on your mobile hotspot. * Connect to devices on your mobile hotspot.
* You will always discover devices on your local network. Paired devices and devices in the same public room are shown additionally. * Devices from the local network, in the same public room, or previously paired are shown.
#### Persistent Device Pairing #### Persistent Device Pairing
* Pair your devices via a 6-digit code or a QR-Code.
* Paired devices will always find each other via shared secrets independently of their local network. Always connect to known devices
* Paired devices are persistent. You find your devices even after reopening PairDrop.
* You can edit and unpair devices easily * Pair devices via a 6-digit code or a QR-Code.
* Ideal to always connect easily to your own devices * Paired devices always find each other via shared secrets independently of their local network.
* Pairing is persistent. You find your devices even after reopening PairDrop.
* You can edit and unpair devices easily.
#### Temporary Public Rooms #### Temporary Public Rooms
* Enter a public room via a 5-letter code or a QR-Code.
* Enter a public room to temporarily connect to devices outside your local network.
* All devices in the same public room see each other mutually.
* Public rooms are temporary. Public rooms are left as soon as PairDrop is closed.
* Ideal to connect easily to others in complex network situations or over the internet.
### [Improved UI for sending/receiving files](https://github.com/RobinLinus/snapdrop/issues/560) Connect to others in complex network situations, or over the Internet.
* Files are transferred only after a request is accepted first. On transfer completion files are downloaded automatically if possible.
* Enter a public room via a 5-letter code or a QR-code.
* Enter a public room to temporarily connect to devices outside your local network.
* All devices in the same public room see each other.
* Public rooms are temporary. Closing PairDrop leaves all rooms.
### [Improved UI for Sending/Receiving Files](https://github.com/RobinLinus/snapdrop/issues/560)
* Files are transferred after a request is accepted. Files are auto-downloaded upon completing a transfer, if possible.
* Multiple files are downloaded as a ZIP file * Multiple files are downloaded as a ZIP file
* On iOS and Android, in addition to downloading, files can be shared or saved to the gallery via the Share menu. * Download, share or save to gallery via the "Share" menu on Android and iOS.
* Multiple files are transferred at once with an overall progress indicator * Multiple files are transferred at once with an overall progress indicator.
### Send Files or Text Directly From Share Menu, Context Menu or CLI ### Send Files or Text Directly From Share Menu, Context Menu or CLI
* [Send files directly from context menu on Windows](docs/how-to.md#send-multiple-files-and-directories-directly-from-context-menu-on-windows) * [Send files directly from context menu on Ubuntu (using Nautilus)](docs/how-to.md#send-multiple-files-and-directories-directly-from-context-menu-on-ubuntu-using-nautilus)
* [Send files directly from context menu on Ubuntu (using Nautilus)](/docs/how-to.md#send-multiple-files-and-directories-directly-from-context-menu-on-ubuntu-using-nautilus) * [Send files directly from the context menu on Windows](docs/how-to.md#send-files-directly-from-context-menu-on-windows)
* [Send files directly from share menu on iOS](docs/how-to.md#send-directly-from-share-menu-on-ios) * [Send directly from the "Share" menu on iOS](docs/how-to.md#send-directly-from-share-menu-on-ios)
* [Send files directly from share menu on Android](docs/how-to.md#send-directly-from-share-menu-on-android) * [Send directly from the "Share" menu on Android](docs/how-to.md#send-directly-from-share-menu-on-android)
* [Send files directly via command-line interface](docs/how-to.md#send-directly-via-command-line-interface) * [Send directly via the command-line interface](docs/how-to.md#send-directly-via-command-line-interface)
### Other changes ### Other Changes
* Change your display name permanently to easily differentiate your devices * Change your display name to easily differentiate your devices.
* [Paste files/text and choose the recipient afterwords ](https://github.com/RobinLinus/snapdrop/pull/534) * [Paste files/text and choose the recipient afterwards ](https://github.com/RobinLinus/snapdrop/pull/534)
* [Prevent devices from sleeping on file transfer](https://github.com/RobinLinus/snapdrop/pull/413) * [Prevent devices from sleeping on file transfer](https://github.com/RobinLinus/snapdrop/pull/413)
* Warn user before PairDrop is closed on file transfer * Warn user before PairDrop is closed on file transfer
* Open PairDrop on multiple tabs simultaneously (Thanks [@willstott101](https://github.com/willstott101)) * Open PairDrop on multiple tabs simultaneously (Thanks [@willstott101](https://github.com/willstott101))
* [Video and Audio preview](https://github.com/RobinLinus/snapdrop/pull/455) (Thanks [@victorwads](https://github.com/victorwads)) * [Video and audio preview](https://github.com/RobinLinus/snapdrop/pull/455) (Thanks [@victorwads](https://github.com/victorwads))
* Switch theme back to auto/system after darkmode or lightmode is enabled * Switch theme back to auto/system after dark or light mode is on
* Node-only implementation (Thanks [@Bellisario](https://github.com/Bellisario)) * Node-only implementation (Thanks [@Bellisario](https://github.com/Bellisario))
* Automatic restart on error (Thanks [@KaKi87](https://github.com/KaKi87)) * Auto-restart on error (Thanks [@KaKi87](https://github.com/KaKi87))
* Lots of stability fixes (Thanks [@MWY001](https://github.com/MWY001) [@skiby7](https://github.com/skiby7) and [@willstott101](https://github.com/willstott101)) * Lots of stability fixes (Thanks [@MWY001](https://github.com/MWY001) [@skiby7](https://github.com/skiby7) and [@willstott101](https://github.com/willstott101))
* To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558) * To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558)
* When hosting PairDrop yourself you can [set your own STUN/TURN servers](docs/host-your-own.md#specify-stunturn-servers) * When hosting PairDrop yourself, you can [set your own STUN/TURN servers](docs/host-your-own.md#specify-stunturn-servers)
* Built-in translations via [Weblate](https://hosted.weblate.org/engage/pairdrop/) * Translations.
* Airy design (Thanks [@Avieshek](https://linktr.ee/avieshek/))
</details> </details>
## Screenshots ## Translate PairDrop on [Hosted Weblate](https://hosted.weblate.org/engage/pairdrop/)
<img src="docs/pairdrop_screenshot_mobile.gif" alt="Gif of Screenshots that show PairDrop in use" style="width: 300px">
## PairDrop is built with the following awesome technologies:
* Vanilla HTML5 / ES6 / CSS3 frontend
* [WebRTC](http://webrtc.org/) / [WebSockets](http://www.websocket.org/)
* [NodeJS](https://nodejs.org/en/) backend
* [Progressive Web App](https://wikipedia.org/wiki/Progressive_Web_App)
* [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
* [Weblate](https://weblate.org/) Web based localization tool
* [zip.js](https://github.com/gildas-lormeau/zip.js) JavaScript library to zip and unzip files ([BSD 3-Clause License](licenses/BSD_3-Clause-zip-js))
* [NoSleep](https://github.com/richtr/NoSleep.js) JavaScript library to prevent display sleep and enable wake lock in any Android or iOS web browser ([MIT License](licenses/MIT-NoSleep))
* [heic2any](https://github.com/alexcorvi/heic2any) JavaScript library to convert HEIC/HEIF images to PNG/GIF/JPEG ([MIT License](licenses/MIT-heic2any))
* [cyrb53](https://github.com/bryc) Super fast hash function
Have any questions? Read our [FAQ](docs/faq.md).
You can [host your own instance with Docker](docs/host-your-own.md).
## Support PairDrop
<a href="https://www.buymeacoffee.com/pairdrop" target="_blank">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" >
</a>
PairDrop is free and always will be.
Still, we have to pay for the domain and the server.
To contribute and support, please use BuyMeACoffee via the button above.
Thanks a lot for supporting free and open software!
## Translate PairDrop
<a href="https://hosted.weblate.org/engage/pairdrop/"> <a href="https://hosted.weblate.org/engage/pairdrop/">
<img src="https://hosted.weblate.org/widget/pairdrop/pairdrop-spa/open-graph.png" alt="Translation status" style="width: 300px" /> <img src="https://hosted.weblate.org/widget/pairdrop/horizontal-blue.svg" alt="Translation status" style="width: 300px" />
</a> </a>
## How to contribute ## Built with the following awesome technologies:
* Vanilla HTML5 / JS ES6 / CSS 3 frontend
* [WebRTC](http://webrtc.org/) / WebSockets
* [Node.js](https://nodejs.org/en/) backend
* [Progressive web app (PWA)](https://en.wikipedia.org/wiki/Progressive_web_app) unified functionality
* [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) storage handling
* [zip.js](https://gildas-lormeau.github.io/zip.js/) library
* [cyrb53](https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js) super-fast hash function
* [NoSleep](https://github.com/richtr/NoSleep.js) display sleep, add wake lock ([MIT](licenses/MIT-NoSleep))
* [heic2any](https://github.com/alexcorvi/heic2any) HEIC/HEIF to PNG/GIF/JPEG ([MIT](licenses/MIT-heic2any))
* [Weblate](https://weblate.org/) web-based localization tool
[FAQ](docs/faq.md)
[Host your own instance with Docker or Node.js](docs/host-your-own.md).
## Support
<a href="https://www.buymeacoffee.com/pairdrop" target="_blank">
<img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy me a coffee" style="height: 60px !important;width: 217px !important;" >
</a>
<br />
<br />
PairDrop is libre, and always will be. \
I footed the bill for the domain and the server, and you can help create great softeare by supporting me. \
Please use BuyMeACoffee via the button above. \
Thanks a lot for supporting copylefted libre software!
## Contributing
Feel free to [open an issue](https://github.com/schlagmichdoch/pairdrop/issues/new/choose) or a Feel free to [open an issue](https://github.com/schlagmichdoch/pairdrop/issues/new/choose) or a
[pull request](https://github.com/schlagmichdoch/pairdrop/pulls) but follow [pull request](https://github.com/schlagmichdoch/pairdrop/pulls), following the
[Contributing Guidelines](CONTRIBUTING.md). [Contributing Guidelines](CONTRIBUTING.md).
+4 -3
View File
@@ -399,7 +399,8 @@ RTC_CONFIG="rtc_config.json"
You can host an instance that uses another signaling server You can host an instance that uses another signaling server
This can be useful if you don't want to trust the client files that are hosted on another instance but still want to connect to devices that use https://pairdrop.net. This can be useful if you don't want to trust the client files that are hosted on another instance but still want to connect to devices that use https://pairdrop.net.
### Host Websocket Server (for VPN)
### Specify Signaling Server
```bash ```bash
SIGNALING_SERVER="pairdrop.net" SIGNALING_SERVER="pairdrop.net"
@@ -415,9 +416,9 @@ SIGNALING_SERVER="pairdrop.net"
> E.g. host your own client files under *pairdrop.your-domain.com* but use the official signaling server under *pairdrop.net* > E.g. host your own client files under *pairdrop.your-domain.com* but use the official signaling server under *pairdrop.net*
> This way devices connecting to *pairdrop.your-domain.com* and *pairdrop.net* can discover each other. > This way devices connecting to *pairdrop.your-domain.com* and *pairdrop.net* can discover each other.
> >
> Beware that the version of your PairDrop server is compatible with the version of the signaling server. > Beware that the version of your PairDrop server must be compatible with the version of the signaling server.
> >
> `WS_SERVER` must be a valid url without the protocol prefix. > `SIGNALING_SERVER` must be a valid url without the protocol prefix.
> Examples of valid values: `pairdrop.net`, `pairdrop.your-domain.com:3000`, `your-domain.com/pairdrop` > Examples of valid values: `pairdrop.net`, `pairdrop.your-domain.com:3000`, `your-domain.com/pairdrop`
<br> <br>
+59 -37
View File
@@ -24,7 +24,7 @@ This opens PairDrop in the default browser where you can choose the receiver.
```bash ```bash
pairdrop -h pairdrop -h
``` ```
```bash ```
Send files or text with PairDrop via command-line interface. Send files or text with PairDrop via command-line interface.
Current domain: https://pairdrop-dev.onrender.com/ Current domain: https://pairdrop-dev.onrender.com/
@@ -35,44 +35,61 @@ Send text: pairdrop -t "text"
Specify domain: pairdrop -d "https://pairdrop.net/" Specify domain: pairdrop -d "https://pairdrop.net/"
Show this help text: pairdrop (-h|--help) Show this help text: pairdrop (-h|--help)
This pairdrop-cli version was released alongside v1.10.0 This pairdrop-cli version was released alongside v1.10.4
``` ```
<br> <br>
### Setup ### Setup
Download the bash file: [pairdrop-cli/pairdrop](/pairdrop-cli/pairdrop).
#### Linux #### Linux / Mac
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) 1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases)
2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/` ```shell
3. Make sure the bash file `/usr/local/bin/pairdrop-cli/pairdrop` is executable. Otherwise, use `chmod +x pairdrop` wget "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.10.7/pairdrop-cli.zip"
4. Add absolute path of the folder to PATH variable to make `pairdrop` available globally by executing ```
`export PATH=$PATH:/usr/local/bin/pairdrop-cli/` or
```shell
<br> curl -LO "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.10.7/pairdrop-cli.zip"
```
#### Mac 2. Unzip the archive to a folder of your choice e.g. `/usr/share/pairdrop-cli/`
1. add bash file to `/usr/local/bin` ```shell
sudo unzip pairdrop-cli.zip -d /usr/share/pairdrop-cli/
```
3. Copy the file _.pairdrop-cli-config.example_ to _.pairdrop-cli-config_
```shell
sudo cp /usr/share/pairdrop-cli/.pairdrop-cli-config.example /usr/share/pairdrop-cli/.pairdrop-cli-config
```
4. Make the bash file _pairdrop_ executable
```shell
sudo chmod +x /usr/share/pairdrop-cli/pairdrop
```
5. Add a symlink to /usr/local/bin/ to include _pairdrop_ to _PATH_
```shell
sudo ln -s /usr/share/pairdrop-cli/pairdrop /usr/local/bin/pairdrop
```
<br> <br>
#### Windows #### Windows
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) 1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases)
2. Put file in a preferred folder e.g. `C:\Program Files\pairdrop-cli` 2. Put file in a preferred folder e.g. `C:\Program Files\pairdrop-cli`
3. Search for and open `Edit environment variables for your account` 3. Inside this folder, copy the file _.pairdrop-cli-config.example_ to _.pairdrop-cli-config_
4. Click `Environment Variables…` 4. Search for and open `Edit environment variables for your account`
5. Under *System Variables* select `Path` and click *Edit...* 5. Click `Environment Variables…`
6. Click *New*, insert the preferred folder (`C:\Program Files\pairdrop-cli`), click *OK* until all windows are closed 6. Under _System Variables_ select `Path` and click _Edit..._
7. Reopen Command prompt window 7. Click _New_, insert the preferred folder (`C:\Program Files\pairdrop-cli`), click *OK* until all windows are closed
8. Reopen Command prompt window
<br> **Requirements**
### Requirements
As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/). As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/).
Then, you can also use pairdrop-cli from the default Windows Command Prompt \
by using the shell file instead of the bash file: `pairdrop.sh -h` which then itself executes \ Then, you can also use pairdrop-cli from the default Windows Command Prompt
pairdrop-cli (the bash file) via the Git Bash. by using the shell file instead of the bash file which then itself executes
_pairdrop-cli_ (the bash file) via the Git Bash.
```shell
pairdrop.sh -h
```
<br> <br>
@@ -82,14 +99,15 @@ pairdrop-cli (the bash file) via the Git Bash.
It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Windows `Send to` menu: It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Windows `Send to` menu:
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) 1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases)
2. Unzip the archive to a folder of your choice e.g. `C:\Program Files\pairdrop-cli\` 2. Unzip the archive to a folder of your choice e.g. `C:\Program Files\pairdrop-cli\`
3. Copy the shortcut _send with PairDrop.lnk_ 3. Inside this folder, copy the file _.pairdrop-cli-config.example_ to _.pairdrop-cli-config_
4. Hit Windows Key+R, type: `shell:sendto` and hit Enter. 4. Copy the shortcut _send with PairDrop.lnk_
5. Paste the copied shortcut into the directory 5. Hit Windows Key+R, type: `shell:sendto` and hit Enter.
6. Open the properties window of the shortcut and edit the link field to point to _send-with-pairdrop.ps1_ located in the folder you used in step 2: \ 6. Paste the copied shortcut into the directory
7. Open the properties window of the shortcut and edit the link field to point to _send-with-pairdrop.ps1_ located in the folder you used in step 2: \
`"C:\Program Files\PowerShell\7\pwsh.exe" -File "C:\Program Files\pairdrop-cli\send-with-pairdrop.ps1"` `"C:\Program Files\PowerShell\7\pwsh.exe" -File "C:\Program Files\pairdrop-cli\send-with-pairdrop.ps1"`
7. You are done! You can now send multiple files and directories directly via PairDrop: 8. You are done! You can now send multiple files and directories directly via PairDrop:
> _context menu > Send to > PairDrop_ _context menu_ > _Send to_ > _PairDrop_
##### Requirements ##### Requirements
As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/). As Windows cannot execute bash scripts natively, you need to install [Git Bash](https://gitforwindows.org/).
@@ -100,14 +118,18 @@ As Windows cannot execute bash scripts natively, you need to install [Git Bash](
### Registering to open files with PairDrop ### Registering to open files with PairDrop
It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Nautilus `Scripts` menu: It is possible to send multiple files with PairDrop via the context menu by adding pairdrop-cli to Nautilus `Scripts` menu:
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases) 1. Register _pairdrop_ as executable via [guide above](#linux).
2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/` 2. Copy the shell file _send-with-pairdrop_ to `~/.local/share/nautilus/scripts/` to include it in the context menu
3. Copy the shell file _send-with-pairdrop.sh_ to `/home/<user>/.local/share/nautilus/scripts/` ```shell
4. Edit the shell file and edit the variable `pathToPairDropCli` to point to the pairdrop-cli executable from step 2 (e.g. `/usr/local/bin/pairdrop-cli/pairdrop`) cp /usr/share/pairdrop-cli/send-with-pairdrop ~/.local/share/nautilus/scripts/
5. Make sure the shell file `/home/<user>/.local/share/nautilus/scripts/send-with-pairdrop.sh` is executable. Otherwise, use `chmod +x send-with-pairdrop.sh` ```
6. You are done! You can now send multiple files and directories directly via PairDrop: 3. Make the shell file _send-with-pairdrop_ executable
```shell
chmod +x ~/.local/share/nautilus/scripts/send-with-pairdrop
```
4. You are done! You can now send multiple files and directories directly via PairDrop:
> _context menu > Scripts > send-with-pairdrop.sh_ _context menu_ > _Scripts_ > _send-with-pairdrop_
<br> <br>
@@ -115,6 +137,6 @@ It is possible to send multiple files with PairDrop via the context menu by addi
The [File Handling API](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files) The [File Handling API](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/handle-files)
was implemented, but it was removed as default file associations were overwritten ([#17](https://github.com/schlagmichdoch/PairDrop/issues/17), was implemented, but it was removed as default file associations were overwritten ([#17](https://github.com/schlagmichdoch/PairDrop/issues/17),
[#116](https://github.com/schlagmichdoch/PairDrop/issues/116) [#190](https://github.com/schlagmichdoch/PairDrop/issues/190)) [#116](https://github.com/schlagmichdoch/PairDrop/issues/116) [#190](https://github.com/schlagmichdoch/PairDrop/issues/190))
and it only worked with explicitly specified file types and not with directories at all. and it only worked with explicitly specified file types and couldn't handle directories at all.
[< Back](/README.md) [< Back](/README.md)
+9 -9
View File
@@ -1,19 +1,19 @@
{ {
"name": "pairdrop", "name": "pairdrop",
"version": "1.10.1", "version": "1.10.7",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "pairdrop", "name": "pairdrop",
"version": "1.10.1", "version": "1.10.7",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.18.2", "express": "^4.18.2",
"express-rate-limit": "^7.1.5", "express-rate-limit": "^7.1.5",
"ua-parser-js": "^1.0.37", "ua-parser-js": "^1.0.37",
"unique-names-generator": "^4.3.0", "unique-names-generator": "^4.3.0",
"ws": "^8.15.0" "ws": "^8.16.0"
}, },
"engines": { "engines": {
"node": ">=15" "node": ">=15"
@@ -640,9 +640,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.15.0", "version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },
@@ -1102,9 +1102,9 @@
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
}, },
"ws": { "ws": {
"version": "8.15.0", "version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"requires": {} "requires": {}
} }
} }
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "pairdrop", "name": "pairdrop",
"version": "1.10.1", "version": "1.10.7",
"type": "module", "type": "module",
"description": "", "description": "",
"main": "server/index.js", "main": "server/index.js",
@@ -15,7 +15,7 @@
"express-rate-limit": "^7.1.5", "express-rate-limit": "^7.1.5",
"ua-parser-js": "^1.0.37", "ua-parser-js": "^1.0.37",
"unique-names-generator": "^4.3.0", "unique-names-generator": "^4.3.0",
"ws": "^8.15.0" "ws": "^8.16.0"
}, },
"engines": { "engines": {
"node": ">=15" "node": ">=15"
@@ -0,0 +1 @@
DOMAIN=https://pairdrop.net/
+9 -3
View File
@@ -1,6 +1,9 @@
#!/bin/bash #!/bin/bash
set -e set -e
# PairDrop version when this file was last changed
version="v1.10.4"
############################################################ ############################################################
# Help # # Help #
############################################################ ############################################################
@@ -17,7 +20,7 @@ help()
echo -e "Specify domain:\t\t$(basename "$0") -d \"https://pairdrop.net/\"" echo -e "Specify domain:\t\t$(basename "$0") -d \"https://pairdrop.net/\""
echo -e "Show this help text:\t$(basename "$0") (-h|--help)" echo -e "Show this help text:\t$(basename "$0") (-h|--help)"
echo echo
echo "This pairdrop-cli version was released alongside v1.10.0" echo "This pairdrop-cli version was released alongside ${version}"
} }
openPairDrop() openPairDrop()
@@ -337,12 +340,15 @@ popd > '/dev/null';
config_path="${script_path}/.pairdrop-cli-config" config_path="${script_path}/.pairdrop-cli-config"
# If config file does not exist, try to create it. If it fails log error message and exit
[ ! -f "$config_path" ] && [ ! -f "$config_path" ] &&
specifyDomain "https://pairdrop.net/" && specifyDomain "https://pairdrop.net/" &&
[ ! -f "$config_path" ] && [ ! -f "$config_path" ] &&
echo "Could not create config file. Add 'DOMAIN=https://pairdrop.net/' to a file called .pairdrop-cli-config in the same file as this 'pairdrop' bash file" echo "Could not create config file. Add 'DOMAIN=https://pairdrop.net/' to a file called .pairdrop-cli-config in the same file as this 'pairdrop' bash file (${script_path})" &&
exit
[ ! -f "$config_path" ] || export "$(grep -v '^#' "$config_path" | xargs)" # Read config variables
export "$(grep -v '^#' "$config_path" | xargs)"
setOs setOs
@@ -1,8 +1,5 @@
#!/bin/bash #!/bin/bash
# edit this to point to the pairdrop-cli executable
pathToPairDropCli="/usr/local/bin/pairdrop-cli/pairdrop"
# Initialize an array # Initialize an array
lines=() lines=()
@@ -17,4 +14,4 @@ length=${#lines[@]}
# Remove the last entry # Remove the last entry
unset 'lines[length-1]' unset 'lines[length-1]'
$pathToPairDropCli "${lines[@]}" pairdrop "${lines[@]}"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+11 -6
View File
@@ -139,7 +139,7 @@
<div class="edit-btn btn btn-small btn-rounded btn-dark text-white" data-i18n-key="header.edit-share-mode" data-i18n-attrs="text" hidden></div> <div class="edit-btn btn btn-small btn-rounded btn-dark text-white" data-i18n-key="header.edit-share-mode" data-i18n-attrs="text" hidden></div>
</div> </div>
</div> </div>
<div id="websocket-fallback" hidden> <div id="websocket-fallback" class="text-center" hidden>
<span data-i18n-key="footer.traffic" data-i18n-attrs="text"></span> <span data-i18n-key="footer.traffic" data-i18n-attrs="text"></span>
<span data-i18n-key="footer.routed" data-i18n-attrs="text"></span> <span data-i18n-key="footer.routed" data-i18n-attrs="text"></span>
<span data-i18n-key="footer.webrtc" data-i18n-attrs="text"></span> <span data-i18n-key="footer.webrtc" data-i18n-attrs="text"></span>
@@ -225,6 +225,11 @@
<span>&nbsp;&nbsp;-&nbsp;&nbsp;</span> <span>&nbsp;&nbsp;-&nbsp;&nbsp;</span>
<span>(Italian)</span> <span>(Italian)</span>
</button> </button>
<button class="btn fw wrap" value="kn">
<span>ಕನ್ನಡ</span>
<span>&nbsp;&nbsp;-&nbsp;&nbsp;</span>
<span>(Kannada)</span>
</button>
<button class="btn fw wrap" value="nl"> <button class="btn fw wrap" value="nl">
<span>Nederlands</span> <span>Nederlands</span>
<span>&nbsp;&nbsp;-&nbsp;&nbsp;</span> <span>&nbsp;&nbsp;-&nbsp;&nbsp;</span>
@@ -577,7 +582,7 @@
</svg> </svg>
<div class="title-wrapper" dir="ltr"> <div class="title-wrapper" dir="ltr">
<h1>PairDrop</h1> <h1>PairDrop</h1>
<div class="font-subheading">v1.10.1</div> <div class="font-subheading">v1.10.7</div>
</div> </div>
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div> <div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
<div class="row"> <div class="row">
@@ -734,10 +739,10 @@
</symbol> </symbol>
</svg> </svg>
<!-- Scripts --> <!-- Scripts -->
<script src="scripts/localization.js"></script> <script src="scripts/localization.js" defer></script>
<script src="scripts/persistent-storage.js"></script> <script src="scripts/persistent-storage.js" defer></script>
<script src="scripts/ui-main.js"></script> <script src="scripts/ui-main.js" defer></script>
<script src="scripts/main.js"></script> <script src="scripts/main.js" defer></script>
<!-- Sounds --> <!-- Sounds -->
<audio id="blop" autobuffer="true"> <audio id="blop" autobuffer="true">
<source src="sounds/blop.mp3" type="audio/mpeg"> <source src="sounds/blop.mp3" type="audio/mpeg">
+2 -1
View File
@@ -66,7 +66,8 @@
"language-selector_title": "إختر اللغة", "language-selector_title": "إختر اللغة",
"about_title": "حول PairDrop", "about_title": "حول PairDrop",
"about_aria-label": "افتح حول PairDrop", "about_aria-label": "افتح حول PairDrop",
"theme-light_title": "إستخدم دائماً المظهر الفاتح" "theme-light_title": "إستخدم دائماً المظهر الفاتح",
"edit-share-mode": "ت٧ارف"
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "انقر لإرسال الملفات أو انقر لفترة طويلة لإرسال رسالة", "x-instructions_mobile": "انقر لإرسال الملفات أو انقر لفترة طويلة لإرسال رسالة",
+8 -3
View File
@@ -12,7 +12,8 @@
"cancel-share-mode": "Fertig", "cancel-share-mode": "Fertig",
"language-selector_title": "Sprache Wählen", "language-selector_title": "Sprache Wählen",
"join-public-room_title": "Öffentlichen Raum temporär betreten", "join-public-room_title": "Öffentlichen Raum temporär betreten",
"edit-share-mode": "Bearbeiten" "edit-share-mode": "Bearbeiten",
"expand_title": "Schaltflächenzeile ausklappen"
}, },
"dialogs": { "dialogs": {
"share": "Teilen", "share": "Teilen",
@@ -81,7 +82,11 @@
"close-about_aria-label": "Schließe Über PairDrop", "close-about_aria-label": "Schließe Über PairDrop",
"github_title": "PairDrop auf GitHub", "github_title": "PairDrop auf GitHub",
"buy-me-a-coffee_title": "Kauf mir einen Kaffee!", "buy-me-a-coffee_title": "Kauf mir einen Kaffee!",
"claim": "Der einfachste Weg, Dateien zwischen Geräten zu übertragen" "claim": "Der einfachste Weg, Dateien zwischen Geräten zu übertragen",
"bluesky_title": "Folge uns auf BlueSky",
"privacypolicy_title": "Öffne unsere Datenschutzerklärung",
"mastodon_title": "Schreibe über PairDrop auf Mastodon",
"custom_title": "Folge uns"
}, },
"footer": { "footer": {
"known-as": "Du wirst angezeigt als:", "known-as": "Du wirst angezeigt als:",
@@ -147,7 +152,7 @@
"x-instructions_desktop": "Klicke, um Dateien zu senden oder benutze einen Rechtsklick, um eine Nachricht zu senden", "x-instructions_desktop": "Klicke, um Dateien zu senden oder benutze einen Rechtsklick, um eine Nachricht zu senden",
"no-peers-title": "Öffne PairDrop auf anderen Geräten, um Dateien zu senden", "no-peers-title": "Öffne PairDrop auf anderen Geräten, um Dateien zu senden",
"no-peers_data-drop-bg": "Hier ablegen, um Empfänger auszuwählen", "no-peers_data-drop-bg": "Hier ablegen, um Empfänger auszuwählen",
"no-peers-subtitle": "Kopple Geräte oder betrete einen öffentlichen Raum, um in anderen Netzwerken sichtbar zu sein", "no-peers-subtitle": "Kopple Geräte oder betritt einen öffentlichen Raum, um in anderen Netzwerken sichtbar zu sein",
"x-instructions-share-mode_desktop": "Klicke zum Senden von {{descriptor}}", "x-instructions-share-mode_desktop": "Klicke zum Senden von {{descriptor}}",
"x-instructions-share-mode_mobile": "Tippe zum Senden von {{descriptor}}", "x-instructions-share-mode_mobile": "Tippe zum Senden von {{descriptor}}",
"x-instructions_data-drop-peer": "Hier ablegen, um an Peer zu senden", "x-instructions_data-drop-peer": "Hier ablegen, um an Peer zu senden",
+25 -8
View File
@@ -11,7 +11,9 @@
"join-public-room_title": "Unirse a una sala pública temporalmente", "join-public-room_title": "Unirse a una sala pública temporalmente",
"notification_title": "Activar notificaciones", "notification_title": "Activar notificaciones",
"edit-paired-devices_title": "Editar dispositivos emparejados", "edit-paired-devices_title": "Editar dispositivos emparejados",
"theme-light_title": "Siempre usar tema claro" "theme-light_title": "Siempre usar tema claro",
"expand_title": "Ampliar la fila de botones de la cabecera",
"edit-share-mode": "Editar"
}, },
"footer": { "footer": {
"webrtc": "si WebRTC no está disponible.", "webrtc": "si WebRTC no está disponible.",
@@ -73,9 +75,9 @@
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "Toque para enviar archivos o toque prologádamente para enviar un mensaje", "x-instructions_mobile": "Toque para enviar archivos o toque prologádamente para enviar un mensaje",
"x-instructions-share-mode_desktop": "Haga clic para enviar", "x-instructions-share-mode_desktop": "Haga clic para enviar {{descriptor}}",
"activate-share-mode-and-other-files-plural": "y {{count}} archivos diferentes", "activate-share-mode-and-other-files-plural": "y {{count}} archivos diferentes",
"x-instructions-share-mode_mobile": "Toca para enviar", "x-instructions-share-mode_mobile": "Toque para enviar {{descriptor}}",
"activate-share-mode-base": "Abra PairDrop en otros dispositivos para enviar", "activate-share-mode-base": "Abra PairDrop en otros dispositivos para enviar",
"no-peers-subtitle": "Empareje dispositivos o ingrese a una sala pública para que lo puedan encontrar en otras redes", "no-peers-subtitle": "Empareje dispositivos o ingrese a una sala pública para que lo puedan encontrar en otras redes",
"activate-share-mode-shared-text": "texto compartido", "activate-share-mode-shared-text": "texto compartido",
@@ -84,7 +86,10 @@
"x-instructions_data-drop-peer": "Liberar para enviar a un par", "x-instructions_data-drop-peer": "Liberar para enviar a un par",
"x-instructions_data-drop-bg": "Liberar para seleccionar destinatario", "x-instructions_data-drop-bg": "Liberar para seleccionar destinatario",
"no-peers_data-drop-bg": "Liberar para seleccionar destinatario", "no-peers_data-drop-bg": "Liberar para seleccionar destinatario",
"webrtc-requirement": "Para utilizar esta instancia de PairDrop, ¡WebRTC debe estar activado!" "webrtc-requirement": "Para utilizar esta instancia de PairDrop, ¡WebRTC debe estar activado!",
"activate-share-mode-shared-files-plural": "{{count}} archivos compartidos",
"activate-share-mode-shared-file": "archivo compartido",
"activate-share-mode-and-other-file": "y 1 archivo más"
}, },
"peer-ui": { "peer-ui": {
"processing": "Procesando…", "processing": "Procesando…",
@@ -96,7 +101,7 @@
"transferring": "Transferiendo…" "transferring": "Transferiendo…"
}, },
"dialogs": { "dialogs": {
"base64-paste-to-send": "Pegar aquí para enviar {{type}}", "base64-paste-to-send": "Pegar el portapapeles aquí para compartir {{type}}",
"auto-accept-instructions-2": "para aceptar automáticamente todos los archivos enviados desde ese dispositivo.", "auto-accept-instructions-2": "para aceptar automáticamente todos los archivos enviados desde ese dispositivo.",
"receive-text-title": "Mensaje Recibido", "receive-text-title": "Mensaje Recibido",
"edit-paired-devices-title": "Editar Dispositivos Emparejados", "edit-paired-devices-title": "Editar Dispositivos Emparejados",
@@ -112,7 +117,7 @@
"join": "Unirse", "join": "Unirse",
"title-image-plural": "Imágenes", "title-image-plural": "Imágenes",
"send": "Enviar", "send": "Enviar",
"base64-tap-to-paste": "Toca aquí para pegar {{type}}", "base64-tap-to-paste": "Pulse aquí para compartir {{type}}",
"base64-text": "texto", "base64-text": "texto",
"copy": "Copiar", "copy": "Copiar",
"file-other-description-image": "y una imagen mas", "file-other-description-image": "y una imagen mas",
@@ -146,7 +151,15 @@
"message_title": "Insertar el mensaje a enviar", "message_title": "Insertar el mensaje a enviar",
"pair-devices-qr-code_title": "Haz clic para copiar el enlace para emparejar este dispositivo", "pair-devices-qr-code_title": "Haz clic para copiar el enlace para emparejar este dispositivo",
"public-room-qr-code_title": "Haz clic para copiar el enlace a la sala pública", "public-room-qr-code_title": "Haz clic para copiar el enlace a la sala pública",
"message_placeholder": "Texto" "message_placeholder": "Texto",
"close-toast_title": "Cerrar la notificación",
"share-text-checkbox": "Mostrar siempre este cuadro de diálogo al compartir texto",
"base64-title-files": "Compartir archivos",
"approve": "aprobar",
"paired-device-removed": "Se ha eliminado el dispositivo emparejado.",
"share-text-title": "Compartir un mensaje de texto",
"share-text-subtitle": "Edita el mensaje antes de enviarlo:",
"base64-title-text": "Compartir el texto"
}, },
"about": { "about": {
"claim": "La forma más sencilla de transferir archivos entre dispositivos", "claim": "La forma más sencilla de transferir archivos entre dispositivos",
@@ -154,7 +167,11 @@
"close-about_aria-label": "Cerrar Sobre PairDrop", "close-about_aria-label": "Cerrar Sobre PairDrop",
"buy-me-a-coffee_title": "¡Cómprame un café!", "buy-me-a-coffee_title": "¡Cómprame un café!",
"github_title": "PairDrop en GitHub", "github_title": "PairDrop en GitHub",
"faq_title": "Preguntas frecuentes" "faq_title": "Preguntas frecuentes",
"bluesky_title": "Síganos en BlueSky",
"privacypolicy_title": "Abrir nuestra política de privacidad",
"mastodon_title": "Escriba sobre PairDrop en Mastodon",
"custom_title": "Síguenos en"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "Transferencia de archivos solicitada", "file-transfer-requested": "Transferencia de archivos solicitada",
+16 -6
View File
@@ -58,7 +58,7 @@
"room-url-copied-to-clipboard": "Tautan ke ruang publik disalin ke papan klip" "room-url-copied-to-clipboard": "Tautan ke ruang publik disalin ke papan klip"
}, },
"header": { "header": {
"cancel-share-mode": "Selesai", "cancel-share-mode": "Batalkan",
"theme-auto_title": "Sesuaikan tema dengan sistem", "theme-auto_title": "Sesuaikan tema dengan sistem",
"install_title": "Instal PairDrop", "install_title": "Instal PairDrop",
"theme-dark_title": "Selalu gunakan tema gelap", "theme-dark_title": "Selalu gunakan tema gelap",
@@ -69,7 +69,9 @@
"language-selector_title": "Atur Bahasa", "language-selector_title": "Atur Bahasa",
"about_title": "Tentang PairDrop", "about_title": "Tentang PairDrop",
"about_aria-label": "Buka Tentang PairDrop", "about_aria-label": "Buka Tentang PairDrop",
"theme-light_title": "Selalu gunakan tema terang" "theme-light_title": "Selalu gunakan tema terang",
"edit-share-mode": "Sunting",
"expand_title": "Perluas baris tombol header"
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "Ketuk untuk mengirim file atau ketuk lama untuk mengirim pesan", "x-instructions_mobile": "Ketuk untuk mengirim file atau ketuk lama untuk mengirim pesan",
@@ -83,7 +85,11 @@
"no-peers-title": "Buka PairDrop di perangkat lain untuk berkirim file", "no-peers-title": "Buka PairDrop di perangkat lain untuk berkirim file",
"x-instructions_data-drop-peer": "Lepaskan untuk mengirim ke rekan", "x-instructions_data-drop-peer": "Lepaskan untuk mengirim ke rekan",
"x-instructions_data-drop-bg": "Lepaskan untuk memilih penerima", "x-instructions_data-drop-bg": "Lepaskan untuk memilih penerima",
"no-peers_data-drop-bg": "Lepaskan untuk memilih penerima" "no-peers_data-drop-bg": "Lepaskan untuk memilih penerima",
"activate-share-mode-and-other-file": "dan 1 file lainnya",
"activate-share-mode-shared-file": "file yang dibagikan",
"activate-share-mode-shared-files-plural": "{{count}} file yang dibagikan",
"webrtc-requirement": "Untuk menggunakan instance PairDrop ini, WebRTC harus diaktifkan!"
}, },
"peer-ui": { "peer-ui": {
"processing": "Memproses…", "processing": "Memproses…",
@@ -111,7 +117,7 @@
"join": "Gabung", "join": "Gabung",
"title-image-plural": "Gambar", "title-image-plural": "Gambar",
"send": "Kirim", "send": "Kirim",
"base64-tap-to-paste": "Ketuk di sini untuk menempelkan {{type}}", "base64-tap-to-paste": "Ketuk di sini untuk membagikan{{type}}",
"base64-text": "teks", "base64-text": "teks",
"copy": "Salin", "copy": "Salin",
"file-other-description-image": "dan 1 gambar lainnya", "file-other-description-image": "dan 1 gambar lainnya",
@@ -125,7 +131,7 @@
"title-image": "Gambar", "title-image": "Gambar",
"file-other-description-file-plural": "dan {{count}} file lainnya", "file-other-description-file-plural": "dan {{count}} file lainnya",
"would-like-to-share": "ingin berbagi", "would-like-to-share": "ingin berbagi",
"send-message-to": "Kirim pesan ke", "send-message-to": "Ke:",
"language-selector-title": "Pilih Bahasa", "language-selector-title": "Pilih Bahasa",
"pair": "Pasangkan", "pair": "Pasangkan",
"hr-or": "ATAU", "hr-or": "ATAU",
@@ -144,7 +150,11 @@
"enter-room-id-from-another-device": "Masukkan room ID dari perangkat lain untuk bergabung dengan room.", "enter-room-id-from-another-device": "Masukkan room ID dari perangkat lain untuk bergabung dengan room.",
"message_title": "Masukkan pesan untuk dikirim", "message_title": "Masukkan pesan untuk dikirim",
"pair-devices-qr-code_title": "Klik untuk menyalin tautan untuk memasangkan perangkat ini", "pair-devices-qr-code_title": "Klik untuk menyalin tautan untuk memasangkan perangkat ini",
"public-room-qr-code_title": "Klik untuk menyalin tautan ke ruang publik" "public-room-qr-code_title": "Klik untuk menyalin tautan ke ruang publik",
"base64-title-files": "Bagikan File",
"base64-title-text": "Bagikan Teks",
"message_placeholder": "Teks",
"paired-device-removed": "Perangkat yang dipasangkan telah dihapus."
}, },
"about": { "about": {
"claim": "Cara termudah untuk mentransfer file lintas perangkat", "claim": "Cara termudah untuk mentransfer file lintas perangkat",
+52 -33
View File
@@ -5,9 +5,9 @@
"display-name_data-placeholder": "Caricamento…", "display-name_data-placeholder": "Caricamento…",
"display-name_title": "Modifica il nome del tuo dispositivo permanentemente", "display-name_title": "Modifica il nome del tuo dispositivo permanentemente",
"traffic": "Il traffico è", "traffic": "Il traffico è",
"paired-devices_title": "Puoi essere rilevato dai dispositivi abbinati in ogni momento, indipendentemente dalla rete.", "paired-devices_title": "Puoi essere rilevato dai dispositivi associati in ogni momento, indipendentemente dalla rete.",
"public-room-devices": "nella stanza {{roomId}}", "public-room-devices": "nella stanza {{roomId}}",
"paired-devices": "da dispositivi abbinati", "paired-devices": "da dispositivi associati",
"on-this-network": "su questa rete", "on-this-network": "su questa rete",
"routed": "instradato attraverso il server", "routed": "instradato attraverso il server",
"discovery": "Puoi essere rilevato:", "discovery": "Puoi essere rilevato:",
@@ -15,7 +15,7 @@
"known-as": "Sei visibile come:" "known-as": "Sei visibile come:"
}, },
"header": { "header": {
"cancel-share-mode": "Fatto", "cancel-share-mode": "Annulla",
"theme-auto_title": "Adatta il tema al sistema automaticamente", "theme-auto_title": "Adatta il tema al sistema automaticamente",
"install_title": "Installa PairDrop", "install_title": "Installa PairDrop",
"theme-dark_title": "Usa sempre il tema scuro", "theme-dark_title": "Usa sempre il tema scuro",
@@ -26,13 +26,15 @@
"language-selector_title": "Imposta Lingua", "language-selector_title": "Imposta Lingua",
"about_title": "Informazioni su PairDrop", "about_title": "Informazioni su PairDrop",
"about_aria-label": "Apri Informazioni su PairDrop", "about_aria-label": "Apri Informazioni su PairDrop",
"theme-light_title": "Usa sempre il tema chiaro" "theme-light_title": "Usa sempre il tema chiaro",
"edit-share-mode": "Modifica",
"expand_title": "Espandi la riga dei pulsanti nell'intestazione"
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "Tocca per inviare file o tocco prolungato per inviare un messaggio", "x-instructions_mobile": "Tocca per inviare file o tocco prolungato per inviare un messaggio",
"x-instructions-share-mode_desktop": "Clicca per inviare", "x-instructions-share-mode_desktop": "Clicca per inviare {{descriptor}}",
"activate-share-mode-and-other-files-plural": "e altri {{count}} files", "activate-share-mode-and-other-files-plural": "e altri {{count}} files",
"x-instructions-share-mode_mobile": "Tocca per inviare", "x-instructions-share-mode_mobile": "Tocca per inviare {{descriptor}}",
"activate-share-mode-base": "Apri PairDrop su altri dispositivi per inviare", "activate-share-mode-base": "Apri PairDrop su altri dispositivi per inviare",
"no-peers-subtitle": "Abbina dispositivi o entra in una stanza pubblica per essere rilevabile su altre reti", "no-peers-subtitle": "Abbina dispositivi o entra in una stanza pubblica per essere rilevabile su altre reti",
"activate-share-mode-shared-text": "testo condiviso", "activate-share-mode-shared-text": "testo condiviso",
@@ -40,23 +42,27 @@
"no-peers-title": "Apri PairDrop su altri dispositivi per inviare files", "no-peers-title": "Apri PairDrop su altri dispositivi per inviare files",
"x-instructions_data-drop-peer": "Rilascia per inviare al peer", "x-instructions_data-drop-peer": "Rilascia per inviare al peer",
"x-instructions_data-drop-bg": "Rilascia per selezionare il destinatario", "x-instructions_data-drop-bg": "Rilascia per selezionare il destinatario",
"no-peers_data-drop-bg": "Rilascia per selezionare il destinatario" "no-peers_data-drop-bg": "Rilascia per selezionare il destinatario",
"webrtc-requirement": "Per usare questa istanza di PairDrop, devi attivare WebRTC!",
"activate-share-mode-shared-file": "file condiviso",
"activate-share-mode-shared-files-plural": "{{count}} files condivisi",
"activate-share-mode-and-other-file": "ed 1 altro file"
}, },
"dialogs": { "dialogs": {
"auto-accept-instructions-2": "per accettare automaticamente tutti i files inviati da quel dispositivo.", "auto-accept-instructions-2": "per accettare automaticamente tutti i files inviati da quel dispositivo.",
"edit-paired-devices-title": "Modifica Dispositivi Abbinati", "edit-paired-devices-title": "Modifica Dispositivi Associati",
"cancel": "Annulla", "cancel": "Annulla",
"auto-accept-instructions-1": "Attiva", "auto-accept-instructions-1": "Attiva",
"pair-devices-title": "Abbina Dispositivi Permanentemente", "pair-devices-title": "Associa Dispositivi Permanentemente",
"temporary-public-room-title": "Stanza Pubblica Temporanea", "temporary-public-room-title": "Stanza Pubblica Temporanea",
"close": "Chiudi", "close": "Chiudi",
"unpair": "Dissocia", "unpair": "Dissocia",
"pair": "Abbina", "pair": "Associa",
"scan-qr-code": "o scannerizza il codice QR.", "scan-qr-code": "o scannerizza il codice QR.",
"input-key-on-this-device": "Inserisci questo codice su un altro dispositivo", "input-key-on-this-device": "Inserisci questo codice su un altro dispositivo",
"paired-devices-wrapper_data-empty": "Nessun dispositivo abbinato.", "paired-devices-wrapper_data-empty": "Nessun dispositivo associato.",
"enter-key-from-another-device": "Inserisci il codice dell'altro dispositivo qui.", "enter-key-from-another-device": "Inserisci il codice dell'altro dispositivo qui.",
"auto-accept": "accetta-automaticamente", "auto-accept": "accetta automaticamente",
"input-room-id-on-another-device": "Inserisci l'ID di questa stanza su un altro dispositivo", "input-room-id-on-another-device": "Inserisci l'ID di questa stanza su un altro dispositivo",
"enter-room-id-from-another-device": "Inserisci l'ID stanza da un altro dispositivo per accedere alla stanza.", "enter-room-id-from-another-device": "Inserisci l'ID stanza da un altro dispositivo per accedere alla stanza.",
"base64-paste-to-send": "Incolla qui per inviare {{type}}", "base64-paste-to-send": "Incolla qui per inviare {{type}}",
@@ -70,7 +76,7 @@
"join": "Unisciti", "join": "Unisciti",
"title-image-plural": "Immagini", "title-image-plural": "Immagini",
"send": "Invia", "send": "Invia",
"base64-tap-to-paste": "Tocca qui per incollare {{type}}", "base64-tap-to-paste": "Tocca qui per condividere {{type}}",
"base64-text": "testo", "base64-text": "testo",
"copy": "Copia", "copy": "Copia",
"file-other-description-image": "e 1 altra immagine", "file-other-description-image": "e 1 altra immagine",
@@ -81,7 +87,7 @@
"title-image": "Immagine", "title-image": "Immagine",
"file-other-description-file-plural": "e altri {{count}} files", "file-other-description-file-plural": "e altri {{count}} files",
"would-like-to-share": "vorrebbe condividere", "would-like-to-share": "vorrebbe condividere",
"send-message-to": "Invia un messaggio a", "send-message-to": "A:",
"language-selector-title": "Imposta Lingua", "language-selector-title": "Imposta Lingua",
"hr-or": "OPPURE", "hr-or": "OPPURE",
"download-again": "Scarica ancora", "download-again": "Scarica ancora",
@@ -91,11 +97,20 @@
"send-message-title": "Invia Messaggio", "send-message-title": "Invia Messaggio",
"file-other-description-image-plural": "e {{count}} altre immagini", "file-other-description-image-plural": "e {{count}} altre immagini",
"message_title": "Inserire messaggio da inviare", "message_title": "Inserire messaggio da inviare",
"pair-devices-qr-code_title": "Clicca per copiare il link di abbinamento di questo dispositivo", "pair-devices-qr-code_title": "Clicca per copiare il link di associazione a questo dispositivo",
"public-room-qr-code_title": "Clicca per copirare il link della stanza pubblica" "public-room-qr-code_title": "Clicca per copirare il link della stanza pubblica",
"message_placeholder": "Testo",
"paired-device-removed": "Il dispositivo associato è stato rimosso.",
"base64-title-files": "Condividi Files",
"base64-title-text": "Condividi Testo",
"share-text-subtitle": "Modifica messaggio prima dell'invio:",
"share-text-checkbox": "Mostra sempre questa casella di dialogo quando si condivide del testo",
"approve": "accetta",
"share-text-title": "Condividi Messaggio di Testo",
"close-toast_title": "Chiudi notifica"
}, },
"notifications": { "notifications": {
"request-title": "{{name}} vorrebbe trasferire {{count}} {{descriptor}}", "request-title": "{{name}} vorrebbe inviare {{count}} {{descriptor}}",
"unfinished-transfers-warning": "Ci sono dei trasferimenti in corso. Sei sicuro di voler chiudere PairDrop?", "unfinished-transfers-warning": "Ci sono dei trasferimenti in corso. Sei sicuro di voler chiudere PairDrop?",
"message-received": "Messaggio ricevuto da {{name}} - Clicca per copiare", "message-received": "Messaggio ricevuto da {{name}} - Clicca per copiare",
"rate-limit-join-key": "Limite raggiunto. Aspetta 10 secondi e riprova.", "rate-limit-join-key": "Limite raggiunto. Aspetta 10 secondi e riprova.",
@@ -103,22 +118,22 @@
"pairing-key-invalidated": "Il codice {{key}} è stato invalidato", "pairing-key-invalidated": "Il codice {{key}} è stato invalidato",
"pairing-key-invalid": "Codice non valido", "pairing-key-invalid": "Codice non valido",
"connected": "Connesso", "connected": "Connesso",
"pairing-not-persistent": "I dispositivi abbinati non sono persistenti", "pairing-not-persistent": "I dispositivi associati non sono permanenti",
"text-content-incorrect": "Il contenuto testuale non è corretto", "text-content-incorrect": "Il contenuto di testo è errato",
"message-transfer-completed": "Trasferimento del messaggio completato", "message-transfer-completed": "Trasferimento del messaggio completato",
"file-transfer-completed": "Trasferimento file completato", "file-transfer-completed": "Trasferimento file completato",
"file-content-incorrect": "Il contenuto del file non è corretto", "file-content-incorrect": "Il contenuto del file è errato",
"files-incorrect": "I file non sono corretti", "files-incorrect": "I file sono errati",
"selected-peer-left": "Peer selezionato ha abbandonato", "selected-peer-left": "Il peer selezionato ha abbandonato",
"link-received": "Link ricevuto da {{name}} - Clicca per aprire", "link-received": "Link ricevuto da {{name}} - Clicca per aprire",
"online": "Sei di nuovo online", "online": "Sei di nuovo online",
"public-room-left": "Ha lasciato la stanza pubblica {{publicRoomId}}", "public-room-left": "Hai abbandonato la stanza pubblica {{publicRoomId}}",
"copied-text": "Testo copiato negli appunti", "copied-text": "Testo copiato negli appunti",
"display-name-random-again": "Il nome visualizzato è generato casualmente un'altra volta", "display-name-random-again": "Il nome visualizzato viene di nuovo generato casualmente",
"display-name-changed-permanently": "Il nome visualizzato è cambiato permanentemente", "display-name-changed-permanently": "Il nome visualizzato è cambiato definitivamente",
"copied-to-clipboard-error": "La copia non è possibile. Copia manualmente.", "copied-to-clipboard-error": "La funzione di copia non è possibile. Copia manualmente.",
"pairing-success": "Dispositivi abbinati", "pairing-success": "Dispositivi associati",
"clipboard-content-incorrect": "Il contenuto copiato non è corretto", "clipboard-content-incorrect": "Il contenuto copiato è errato",
"display-name-changed-temporarily": "Il nome visualizzato è cambiato solo per questa sessione", "display-name-changed-temporarily": "Il nome visualizzato è cambiato solo per questa sessione",
"copied-to-clipboard": "Copiato negli appunti", "copied-to-clipboard": "Copiato negli appunti",
"offline": "Sei offline", "offline": "Sei offline",
@@ -127,14 +142,14 @@
"click-to-download": "Clicca per scaricare", "click-to-download": "Clicca per scaricare",
"pairing-cleared": "Tutti i dispositivi sono stati dissociati", "pairing-cleared": "Tutti i dispositivi sono stati dissociati",
"notifications-enabled": "Notifiche attivate", "notifications-enabled": "Notifiche attivate",
"online-requirement-pairing": "Devi essere online per abbinare dispositivi", "online-requirement-pairing": "Devi essere online per associare dispositivi",
"ios-memory-limit": "L'invio di file a dispositivi iOS è possibile solo 200 MB alla volta", "ios-memory-limit": "L'invio di file a dispositivi iOS è possibile solo 200 MB alla volta",
"online-requirement-public-room": "Devi essere online per creare una stanza pubblica", "online-requirement-public-room": "Devi essere online per creare una stanza pubblica",
"copied-text-error": "Scrittura negli appunti fallita. Copia manualmente!", "copied-text-error": "Scrittura negli appunti fallita. Copia manualmente!",
"download-successful": "{{descriptor}} scaricato", "download-successful": "{{descriptor}} scaricato",
"click-to-show": "Clicca per mostrare", "click-to-show": "Clicca per mostrare",
"notifications-permissions-error": "Il permesso all'invio delle notifiche è stato negato poiché l'utente ha ignorato varie volte le richieste di permesso. Ciò può essere ripristinato nelle \"informazioni sito\" cliccando sull'icona a forma di lucchetto vicino alla barra degli indirizzi.", "notifications-permissions-error": "Il permesso all'invio delle notifiche è stato negato poiché l'utente ha ignorato varie volte le richieste di permesso. Ciò può essere ripristinato nelle \"informazioni sito\" cliccando sull'icona a forma di lucchetto vicino alla barra degli indirizzi.",
"pair-url-copied-to-clipboard": "Link di abbinamento copiato negli appunti", "pair-url-copied-to-clipboard": "Link di associazione copiato negli appunti",
"room-url-copied-to-clipboard": "Link della stanza copiato negli appunti" "room-url-copied-to-clipboard": "Link della stanza copiato negli appunti"
}, },
"peer-ui": { "peer-ui": {
@@ -150,14 +165,18 @@
"claim": "Il modo più semplice per trasferire files tra dispositivi", "claim": "Il modo più semplice per trasferire files tra dispositivi",
"tweet_title": "Twitta riguardo PairDrop", "tweet_title": "Twitta riguardo PairDrop",
"close-about_aria-label": "Chiudi Informazioni su PairDrop", "close-about_aria-label": "Chiudi Informazioni su PairDrop",
"buy-me-a-coffee_title": "Comprami un caffè!", "buy-me-a-coffee_title": "Offrimi un caffè!",
"github_title": "PairDrop su GitHub", "github_title": "PairDrop su GitHub",
"faq_title": "Domande Frequenti" "faq_title": "Domande Frequenti",
"mastodon_title": "Scrivi su Mastodon di PairDrop",
"bluesky_title": "Seguici su BlueSky",
"custom_title": "Seguici",
"privacypolicy_title": "Apri la nostra policy sulla privacy"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "Trasferimento File Richiesto", "file-transfer-requested": "Trasferimento File Richiesto",
"image-transfer-requested": "Trasferimento Immagine Richiesto", "image-transfer-requested": "Trasferimento Immagine Richiesto",
"message-received-plural": "{{count}} Messaggi ricevuti", "message-received-plural": "{{count}} Messaggi Ricevuti",
"message-received": "Messaggio ricevuto", "message-received": "Messaggio ricevuto",
"file-received": "File Ricevuto", "file-received": "File Ricevuto",
"file-received-plural": "{{count}} Files Ricevuti" "file-received-plural": "{{count}} Files Ricevuti"
+23 -4
View File
@@ -69,7 +69,9 @@
"language-selector_title": "言語を設定", "language-selector_title": "言語を設定",
"about_title": "PairDropについて", "about_title": "PairDropについて",
"about_aria-label": "PairDropについてを開く", "about_aria-label": "PairDropについてを開く",
"theme-light_title": "常にライトテーマを使用する" "theme-light_title": "常にライトテーマを使用する",
"edit-share-mode": "編集",
"expand_title": "ヘッダーボタン列を拡大する"
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "タップしてファイルを送信または長押ししてメッセージを送信します", "x-instructions_mobile": "タップしてファイルを送信または長押ししてメッセージを送信します",
@@ -83,7 +85,11 @@
"no-peers-title": "他のデバイスでPairDropを開いてファイルを送信します", "no-peers-title": "他のデバイスでPairDropを開いてファイルを送信します",
"x-instructions_data-drop-peer": "離すとこの相手に送信します", "x-instructions_data-drop-peer": "離すとこの相手に送信します",
"x-instructions_data-drop-bg": "送信したい相手の上で離してください", "x-instructions_data-drop-bg": "送信したい相手の上で離してください",
"no-peers_data-drop-bg": "送信したい相手の上で離してください" "no-peers_data-drop-bg": "送信したい相手の上で離してください",
"activate-share-mode-and-other-file": "もう1つの別のファイル",
"activate-share-mode-shared-file": "共有されたファイル",
"activate-share-mode-shared-files-plural": "{{count}}個の共有されたファイル",
"webrtc-requirement": "このPairDropインスタンスを使用するには、WebRTCを有効にする必要があります!"
}, },
"peer-ui": { "peer-ui": {
"processing": "処理中…", "processing": "処理中…",
@@ -144,7 +150,16 @@
"enter-room-id-from-another-device": "他のデバイスに表示された参加したいルームのIDを入力します。", "enter-room-id-from-another-device": "他のデバイスに表示された参加したいルームのIDを入力します。",
"message_title": "送信するメッセージを挿入", "message_title": "送信するメッセージを挿入",
"pair-devices-qr-code_title": "クリックしてこのデバイスをペア設定するリンクをコピー", "pair-devices-qr-code_title": "クリックしてこのデバイスをペア設定するリンクをコピー",
"public-room-qr-code_title": "クリックしてパブリックルームへのリンクをコピー" "public-room-qr-code_title": "クリックしてパブリックルームへのリンクをコピー",
"paired-device-removed": "ペア設定されたデバイスが削除されました。",
"message_placeholder": "テキスト",
"base64-title-files": "共有されたファイル",
"base64-title-text": "テキストを共有",
"approve": "承諾",
"share-text-subtitle": "送信する前にメッセージを編集する:",
"share-text-checkbox": "テキストを共有するときに常にこのダイアログを表示する",
"close-toast_title": "通知を閉じる",
"share-text-title": "テキストメッセージを共有します"
}, },
"about": { "about": {
"claim": "デバイス間でファイルを転送する最も簡単な方法", "claim": "デバイス間でファイルを転送する最も簡単な方法",
@@ -152,7 +167,11 @@
"close-about_aria-label": "PairDropについてを閉じる", "close-about_aria-label": "PairDropについてを閉じる",
"buy-me-a-coffee_title": "コーヒーをおごってください!", "buy-me-a-coffee_title": "コーヒーをおごってください!",
"github_title": "GitHubでPairDropを見る", "github_title": "GitHubでPairDropを見る",
"faq_title": "FAQ" "faq_title": "FAQ",
"mastodon_title": "MastodonにPairDropについて書く",
"bluesky_title": "BlueSkyでフォロー",
"custom_title": "フォロー",
"privacypolicy_title": "プライバシーポリシーを開く"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "ファイルの転送がリクエストされました", "file-transfer-requested": "ファイルの転送がリクエストされました",
+31 -7
View File
@@ -11,11 +11,14 @@
"edit-paired-devices_title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ", "edit-paired-devices_title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ",
"language-selector_title": "ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ", "language-selector_title": "ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ",
"about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ತೆರೆಯಿರಿ", "about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ತೆರೆಯಿರಿ",
"theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ" "theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ",
"edit-share-mode": "ಎಡಿಟ್ ಮಾಡಿ",
"cancel-share-mode": "ರದ್ದುಗೊಳಿಸಿ",
"expand_title": "ಹೆಡರ್ ಬಟನ್ ಸಾಲನ್ನು ವಿಸ್ತರಿಸಿ"
}, },
"dialogs": { "dialogs": {
"message_placeholder": "ಪಠ್ಯ", "message_placeholder": "ಪಠ್ಯ",
"base64-paste-to-send": "{{type}} ಕಳುಹಿಸಲು ಇಲ್ಲಿ ಅಂಟಿಸಿ", "base64-paste-to-send": "{{type}} ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ ಅನ್ನು ಇಲ್ಲಿ ಅಂಟಿಸಿ",
"auto-accept-instructions-2": "ಆ ಸಾಧನದಿಂದ ಕಳುಹಿಸಲಾದ ಎಲ್ಲಾ ಫೈಲ್‌ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸ್ವೀಕರಿಸಲು.", "auto-accept-instructions-2": "ಆ ಸಾಧನದಿಂದ ಕಳುಹಿಸಲಾದ ಎಲ್ಲಾ ಫೈಲ್‌ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸ್ವೀಕರಿಸಲು.",
"receive-text-title": "ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ", "receive-text-title": "ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ",
"edit-paired-devices-title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ", "edit-paired-devices-title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ",
@@ -32,7 +35,7 @@
"join": "ಸೇರಿಕೊಳ್ಳಿ", "join": "ಸೇರಿಕೊಳ್ಳಿ",
"title-image-plural": "ಚಿತ್ರಗಳು", "title-image-plural": "ಚಿತ್ರಗಳು",
"send": "ಕಳುಹಿಸಿ", "send": "ಕಳುಹಿಸಿ",
"base64-tap-to-paste": "{{type}} ಅಂಟಿಸಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ", "base64-tap-to-paste": "{{type}} ಹಂಚಿಕೊಳ್ಳಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ",
"base64-text": "ಪಠ್ಯ", "base64-text": "ಪಠ್ಯ",
"copy": "ನಕಲು ಮಾಡಿ", "copy": "ನಕಲು ಮಾಡಿ",
"file-other-description-image": "ಮತ್ತು ಇನ್ನೊಂದು ಚಿತ್ರ", "file-other-description-image": "ಮತ್ತು ಇನ್ನೊಂದು ಚಿತ್ರ",
@@ -64,7 +67,15 @@
"send-message-title": "ಸಂದೇಶ ಕಳುಹಿಸಿ", "send-message-title": "ಸಂದೇಶ ಕಳುಹಿಸಿ",
"input-room-id-on-another-device": "ಇನ್ನೊಂದು ಸಾಧನದಲ್ಲಿ ಈ ರೂಮ್ ಐಡಿಯನ್ನು ನಮೂದಿಸಿ", "input-room-id-on-another-device": "ಇನ್ನೊಂದು ಸಾಧನದಲ್ಲಿ ಈ ರೂಮ್ ಐಡಿಯನ್ನು ನಮೂದಿಸಿ",
"file-other-description-image-plural": "ಮತ್ತು {{count}} ಇತರ ಚಿತ್ರಗಳು", "file-other-description-image-plural": "ಮತ್ತು {{count}} ಇತರ ಚಿತ್ರಗಳು",
"enter-room-id-from-another-device": "ಕೊಠಡಿ ಸೇರಲು ಇನ್ನೊಂದು ಸಾಧನದಿಂದ ರೂಮ್ ಐಡಿ ನಮೂದಿಸಿ." "enter-room-id-from-another-device": "ಕೊಠಡಿ ಸೇರಲು ಇನ್ನೊಂದು ಸಾಧನದಿಂದ ರೂಮ್ ಐಡಿ ನಮೂದಿಸಿ.",
"close-toast_title": "ಅಧಿಸೂಚನೆಯನ್ನು ಮುಚ್ಚಿರಿ",
"share-text-checkbox": "ಪಠ್ಯವನ್ನು ಹಂಚಿಕೊಳ್ಳುವಾಗ ಯಾವಾಗಲೂ ಈ ಡೈಲಾಗ್ ಅನ್ನು ತೋರಿಸಿ",
"base64-title-files": "ಫೈಲ್‌ಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ",
"approve": "ಅನುಮೋದಿಸಿ",
"paired-device-removed": "ಜೋಡಿಸಲಾದ ಸಾಧನವನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ.",
"share-text-title": "ಪಠ್ಯ ಸಂದೇಶವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ",
"share-text-subtitle": "ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವ ಮೊದಲು ಎಡಿಟ್ ಮಾಡಿ:",
"base64-title-text": "ಪಠ್ಯವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ"
}, },
"footer": { "footer": {
"webrtc": "WebRTC ಲಭ್ಯವಿಲ್ಲದಿದ್ದರೆ.", "webrtc": "WebRTC ಲಭ್ಯವಿಲ್ಲದಿದ್ದರೆ.",
@@ -137,7 +148,15 @@
"x-instructions_data-drop-peer": "ಪೀರ್‌ಗೆ ಕಳುಹಿಸಲು ಬಿಡುಗಡೆ ಮಾಡಿ", "x-instructions_data-drop-peer": "ಪೀರ್‌ಗೆ ಕಳುಹಿಸಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
"x-instructions_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ", "x-instructions_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
"no-peers_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ", "no-peers_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
"webrtc-requirement": "ಈ PairDrop ನಿದರ್ಶನವನ್ನು ಬಳಸಲು, WebRTC ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು!" "webrtc-requirement": "ಈ PairDrop ನಿದರ್ಶನವನ್ನು ಬಳಸಲು, WebRTC ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು!",
"activate-share-mode-base": "ಕಳುಹಿಸಲು ಇತರ ಸಾಧನಗಳಲ್ಲಿ PairDrop ತೆರೆಯಿರಿ",
"activate-share-mode-shared-files-plural": "{{count}} ಹಂಚಿದ ಫೈಲ್‌ಗಳು",
"x-instructions-share-mode_desktop": "{{descriptor}} ಕಳುಹಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ",
"activate-share-mode-shared-file": "ಹಂಚಿದ ಫೈಲ್",
"activate-share-mode-and-other-file": "ಮತ್ತು ಇತರ 1 ಫೈಲ್",
"x-instructions-share-mode_mobile": "{{descriptor}} ಕಳುಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ",
"activate-share-mode-and-other-files-plural": "ಮತ್ತು ಇತರ {{count}} ಫೈಲ್‌ಗಳು",
"activate-share-mode-shared-text": "ಹಂಚಿದ ಪಠ್ಯ"
}, },
"peer-ui": { "peer-ui": {
"processing": "ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ…", "processing": "ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ…",
@@ -146,7 +165,8 @@
"waiting": "ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ…", "waiting": "ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ…",
"connection-hash": "ಎಂಡ್-ಟು-ಎಂಡ್ ಎನ್‌ಕ್ರಿಪ್ಶನ್‌ನ ಭದ್ರತೆಯನ್ನು ಪರಿಶೀಲಿಸಲು, ಎರಡೂ ಸಾಧನಗಳಲ್ಲಿ ಈ ಭದ್ರತಾ ಸಂಖ್ಯೆಯನ್ನು ಹೋಲಿಸಿ", "connection-hash": "ಎಂಡ್-ಟು-ಎಂಡ್ ಎನ್‌ಕ್ರಿಪ್ಶನ್‌ನ ಭದ್ರತೆಯನ್ನು ಪರಿಶೀಲಿಸಲು, ಎರಡೂ ಸಾಧನಗಳಲ್ಲಿ ಈ ಭದ್ರತಾ ಸಂಖ್ಯೆಯನ್ನು ಹೋಲಿಸಿ",
"preparing": "ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…", "preparing": "ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…",
"transferring": "ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ…" "transferring": "ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ…",
"click-to-send-share-mode": "{{descriptor}} ಕಳುಹಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"
}, },
"about": { "about": {
"claim": "ಸಾಧನಗಳಾದ್ಯಂತ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸುಲಭವಾದ ಮಾರ್ಗ", "claim": "ಸಾಧನಗಳಾದ್ಯಂತ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸುಲಭವಾದ ಮಾರ್ಗ",
@@ -154,7 +174,11 @@
"close-about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ಮುಚ್ಚಿ", "close-about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ಮುಚ್ಚಿ",
"buy-me-a-coffee_title": "ನನಗೆ ಕಾಫಿ ಖರೀದಿಸಿ!", "buy-me-a-coffee_title": "ನನಗೆ ಕಾಫಿ ಖರೀದಿಸಿ!",
"github_title": "GitHub ನಲ್ಲಿ PairDrop", "github_title": "GitHub ನಲ್ಲಿ PairDrop",
"faq_title": "ಪದೇ ಪದೇ ಕೇಳಲಾಗುವ ಪ್ರಶ್ನೆಗಳು" "faq_title": "ಪದೇ ಪದೇ ಕೇಳಲಾಗುವ ಪ್ರಶ್ನೆಗಳು",
"bluesky_title": "BlueSky ನಲ್ಲಿ ನಮ್ಮನ್ನು ಅನುಸರಿಸಿ",
"privacypolicy_title": "ನಮ್ಮ ಗೌಪ್ಯತೆ ನೀತಿ ತೆರೆಯಿರಿ",
"mastodon_title": "Mastodon ನಲ್ಲಿ PairDrop ಕುರಿತು ಬರೆಯಿರಿ",
"custom_title": "ನಮ್ಮನ್ನು ಅನುಸರಿಸಿ"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "ಫೈಲ್ ವರ್ಗಾವಣೆಗೆ ವಿನಂತಿಸಲಾಗಿದೆ", "file-transfer-requested": "ಫೈಲ್ ವರ್ಗಾವಣೆಗೆ ವಿನಂತಿಸಲಾಗಿದೆ",
+29 -10
View File
@@ -58,7 +58,7 @@
"room-url-copied-to-clipboard": "Link către sala publică copiat în clipboard" "room-url-copied-to-clipboard": "Link către sala publică copiat în clipboard"
}, },
"header": { "header": {
"cancel-share-mode": "Gata", "cancel-share-mode": "Anulare",
"theme-auto_title": "Adaptează tema la sistem", "theme-auto_title": "Adaptează tema la sistem",
"install_title": "Instalează PairDrop", "install_title": "Instalează PairDrop",
"theme-dark_title": "Utilizați mereu tema întunecoasă", "theme-dark_title": "Utilizați mereu tema întunecoasă",
@@ -69,13 +69,15 @@
"language-selector_title": "Setează Limba", "language-selector_title": "Setează Limba",
"about_title": "Despre PairDrop", "about_title": "Despre PairDrop",
"about_aria-label": "Deschide Despre PairDrop", "about_aria-label": "Deschide Despre PairDrop",
"theme-light_title": "Utilizați mereu tema luminoasă" "theme-light_title": "Utilizați mereu tema luminoasă",
"expand_title": "Extindeți rândul de butoane antet",
"edit-share-mode": "Editați"
}, },
"instructions": { "instructions": {
"x-instructions_mobile": "Atingeți pentru a trimite fișiere sau atingeți lung pentru a trimite un mesaj", "x-instructions_mobile": "Atingeți pentru a trimite fișiere sau atingeți lung pentru a trimite un mesaj",
"x-instructions-share-mode_desktop": "Clic pentru a trimite", "x-instructions-share-mode_desktop": "Faceți clic pentru a trimite {{descriptor}}",
"activate-share-mode-and-other-files-plural": "și {{count}} alte fișiere", "activate-share-mode-and-other-files-plural": "și {{count}} alte fișiere",
"x-instructions-share-mode_mobile": "Atinge pentru a trimite", "x-instructions-share-mode_mobile": "Atingeți pentru a trimite {{descriptor}}",
"activate-share-mode-base": "Deschideți PairDrop pe alte dispozitive pentru a trimite", "activate-share-mode-base": "Deschideți PairDrop pe alte dispozitive pentru a trimite",
"no-peers-subtitle": "Împerecheați dispozitive sau intrați într-o cameră publică pentru a fi descoperit în alte rețele", "no-peers-subtitle": "Împerecheați dispozitive sau intrați într-o cameră publică pentru a fi descoperit în alte rețele",
"activate-share-mode-shared-text": "text partajat", "activate-share-mode-shared-text": "text partajat",
@@ -83,7 +85,11 @@
"no-peers-title": "Deschideți PairDrop pe alte dispozitive pentru a trimite fișiere", "no-peers-title": "Deschideți PairDrop pe alte dispozitive pentru a trimite fișiere",
"x-instructions_data-drop-peer": "Eliberare pentru a trimite la peer", "x-instructions_data-drop-peer": "Eliberare pentru a trimite la peer",
"x-instructions_data-drop-bg": "Eliberați pentru a selecta recipientul", "x-instructions_data-drop-bg": "Eliberați pentru a selecta recipientul",
"no-peers_data-drop-bg": "Eliberare pentru a selecta recipientul" "no-peers_data-drop-bg": "Eliberați pentru a selecta destinatarul",
"activate-share-mode-shared-files-plural": "{{count}} fișiere partajate",
"activate-share-mode-shared-file": "fișier partajat",
"activate-share-mode-and-other-file": "și încă 1 fișier",
"webrtc-requirement": "Pentru a utiliza această instanță PairDrop, WebRTC trebuie să fie activat!"
}, },
"peer-ui": { "peer-ui": {
"processing": "Procesarea…", "processing": "Procesarea…",
@@ -95,7 +101,7 @@
"transferring": "Transferul…" "transferring": "Transferul…"
}, },
"dialogs": { "dialogs": {
"base64-paste-to-send": "Lipiți aici pentru a trimite {{type}}", "base64-paste-to-send": "Inserați clipboard aici pentru a distribui {{type}}",
"auto-accept-instructions-2": "pentru a accepta automat toate fișierele trimise de la dispozitivul respectiv.", "auto-accept-instructions-2": "pentru a accepta automat toate fișierele trimise de la dispozitivul respectiv.",
"receive-text-title": "Mesaj primit", "receive-text-title": "Mesaj primit",
"edit-paired-devices-title": "Editați dispozitivele asociate", "edit-paired-devices-title": "Editați dispozitivele asociate",
@@ -111,7 +117,7 @@
"join": "Alătură-te", "join": "Alătură-te",
"title-image-plural": "Imagini", "title-image-plural": "Imagini",
"send": "Trimite", "send": "Trimite",
"base64-tap-to-paste": "Atinge aici pentru a lipi {{type}}", "base64-tap-to-paste": "Atingeți aici pentru a distribui {{type}}",
"base64-text": "text", "base64-text": "text",
"copy": "Copiază", "copy": "Copiază",
"file-other-description-image": "și 1 altă imagine", "file-other-description-image": "și 1 altă imagine",
@@ -125,7 +131,7 @@
"title-image": "Imagine", "title-image": "Imagine",
"file-other-description-file-plural": "și {{count}} alte fișiere", "file-other-description-file-plural": "și {{count}} alte fișiere",
"would-like-to-share": "ar dori să împărtășească", "would-like-to-share": "ar dori să împărtășească",
"send-message-to": "Trimite un mesaj la", "send-message-to": "La:",
"language-selector-title": "Setați Limba", "language-selector-title": "Setați Limba",
"pair": "Cuplu", "pair": "Cuplu",
"hr-or": "SAU", "hr-or": "SAU",
@@ -144,7 +150,16 @@
"enter-room-id-from-another-device": "Introdu ID-ul camerei de pe un alt dispozitiv pentru a intra în cameră.", "enter-room-id-from-another-device": "Introdu ID-ul camerei de pe un alt dispozitiv pentru a intra în cameră.",
"message_title": "Inserați mesajul de trimis", "message_title": "Inserați mesajul de trimis",
"pair-devices-qr-code_title": "Dați clic pentru a copia link-ul pentru a asocia acest dispozitiv", "pair-devices-qr-code_title": "Dați clic pentru a copia link-ul pentru a asocia acest dispozitiv",
"public-room-qr-code_title": "Dați clic pentru a copia link-ul în sala publică" "public-room-qr-code_title": "Dați clic pentru a copia link-ul în sala publică",
"message_placeholder": "Text",
"close-toast_title": "Închideți notificarea",
"share-text-checkbox": "Afișați întotdeauna acest dialog atunci când partajați text",
"base64-title-files": "Distribuie fisiere",
"approve": "aprobă",
"paired-device-removed": "Dispozitivul asociat a fost eliminat.",
"share-text-title": "Partajați un mesaj text",
"share-text-subtitle": "Editați mesajul înainte de a-l trimite:",
"base64-title-text": "Partajați textul"
}, },
"about": { "about": {
"claim": "Cel mai simplu mod de a transfera fișiere între dispozitive", "claim": "Cel mai simplu mod de a transfera fișiere între dispozitive",
@@ -152,7 +167,11 @@
"close-about_aria-label": "Închide Despre PairDrop", "close-about_aria-label": "Închide Despre PairDrop",
"buy-me-a-coffee_title": "Cumpără-mi o cafea!", "buy-me-a-coffee_title": "Cumpără-mi o cafea!",
"github_title": "PairDrop pe GitHub", "github_title": "PairDrop pe GitHub",
"faq_title": "Întrebări frecvente" "faq_title": "Întrebări frecvente",
"bluesky_title": "Urmărește-ne pe BlueSky",
"privacypolicy_title": "Deschideți politica noastră de confidențialitate",
"mastodon_title": "Scrieți despre PairDrop pe Mastodon",
"custom_title": "Urmăriți-ne"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "Transfer de fișiere cerut", "file-transfer-requested": "Transfer de fișiere cerut",
+14 -9
View File
@@ -1,7 +1,7 @@
{ {
"header": { "header": {
"about_title": "PairDrop Hakkında", "about_title": "PairDrop Hakkında",
"about_aria-label": "PairDrop Hakkında Aç", "about_aria-label": "PairDrop Hakkındayı Aç",
"theme-auto_title": "Temayı sisteme uyarla", "theme-auto_title": "Temayı sisteme uyarla",
"theme-light_title": "Daima açık tema kullan", "theme-light_title": "Daima açık tema kullan",
"theme-dark_title": "Daima koyu tema kullan", "theme-dark_title": "Daima koyu tema kullan",
@@ -12,18 +12,19 @@
"cancel-share-mode": "Bitti", "cancel-share-mode": "Bitti",
"join-public-room_title": "Geçici olarak genel odaya katılın", "join-public-room_title": "Geçici olarak genel odaya katılın",
"language-selector_title": "Dili Seç", "language-selector_title": "Dili Seç",
"edit-share-mode": "Düzenle" "edit-share-mode": "Düzenle",
"expand_title": "Başlık düğmesi satırını genişlet"
}, },
"instructions": { "instructions": {
"no-peers_data-drop-bg": "Alıcıyı seçmek için bırakın", "no-peers_data-drop-bg": "Alıcıyı seçmek için bırakın",
"x-instructions_mobile": "Dosya göndermek için dokun veya mesaj göndermek için uzun dokun", "x-instructions_mobile": "Dosya göndermek için dokun veya mesaj göndermek için uzun dokun",
"x-instructions-share-mode_desktop": "Göndermek için tıkla {{descriptor}}", "x-instructions-share-mode_desktop": "{{descriptor}} kişisine göndermek için tıkla",
"activate-share-mode-and-other-files-plural": "ve {{count}} diğer dosya", "activate-share-mode-and-other-files-plural": "ve {{count}} diğer dosya",
"x-instructions-share-mode_mobile": "Göndermek için dokun {{descriptor}}", "x-instructions-share-mode_mobile": "{{descriptor}} kişisine göndermek için dokun",
"activate-share-mode-base": "Göndermek için diğer cihazlarda PairDrop'u açın", "activate-share-mode-base": "Göndermek için diğer cihazlarda PairDrop'u açın",
"no-peers-subtitle": "Diğer ağlarda keşfedilebilir olmak için cihazları eşleştirin veya ortak bir odaya girin", "no-peers-subtitle": "Diğer ağlarda keşfedilebilir olmak için cihazları eşleştirin veya ortak bir odaya girin",
"activate-share-mode-shared-text": "paylaşılan metin", "activate-share-mode-shared-text": "paylaşılan metin",
"x-instructions_desktop": "Dosya göndermek için tıkla ya da mesaj göndermek için sağ tıkla", "x-instructions_desktop": "Dosya göndermek için tıkla veya mesaj göndermek için sağ tıkla",
"no-peers-title": "Dosya göndermek için diğer cihazlarda PairDrop'u açın", "no-peers-title": "Dosya göndermek için diğer cihazlarda PairDrop'u açın",
"x-instructions_data-drop-peer": "Göndermek için serbest bırak", "x-instructions_data-drop-peer": "Göndermek için serbest bırak",
"x-instructions_data-drop-bg": "Alıcıyı seçmek için bırakın", "x-instructions_data-drop-bg": "Alıcıyı seçmek için bırakın",
@@ -131,11 +132,11 @@
"public-room-left": "{{publicRoomId}} genel odasından ayrıldın", "public-room-left": "{{publicRoomId}} genel odasından ayrıldın",
"copied-text": "Metin panoya kopyalandı", "copied-text": "Metin panoya kopyalandı",
"display-name-random-again": "Mevcut adın tekrardan rastgele oluşturuldu", "display-name-random-again": "Mevcut adın tekrardan rastgele oluşturuldu",
"display-name-changed-permanently": "Mevcut adın kalıcı olarak değiştirilir", "display-name-changed-permanently": "Mevcut adın kalıcı olarak değiştirildi",
"copied-to-clipboard-error": "Kopyalama mümkün değil. Manuel olarak kopyalayın.", "copied-to-clipboard-error": "Kopyalama mümkün değil. Manuel olarak kopyalayın.",
"pairing-success": "Cihazlar eşleştirildi", "pairing-success": "Cihazlar eşleştirildi",
"clipboard-content-incorrect": "Pano içeriği yanlış", "clipboard-content-incorrect": "Pano içeriği yanlış",
"display-name-changed-temporarily": "Mevcut adın yalnızca bu oturum için değiştirilir", "display-name-changed-temporarily": "Mevcut adın yalnızca bu oturum için değiştirildi",
"copied-to-clipboard": "Panoya kopyalandı", "copied-to-clipboard": "Panoya kopyalandı",
"offline": "Çevrimdışısın", "offline": "Çevrimdışısın",
"pairing-tabs-error": "İki web tarayıcı sekmesini eşleştirmek mümkün değildir", "pairing-tabs-error": "İki web tarayıcı sekmesini eşleştirmek mümkün değildir",
@@ -149,7 +150,7 @@
"room-url-copied-to-clipboard": "Genel oda bağlantı linki panoya kopyalandı", "room-url-copied-to-clipboard": "Genel oda bağlantı linki panoya kopyalandı",
"copied-text-error": "Panoya kopyalanamadı. Lütfen manuel olarak kopyalayın!", "copied-text-error": "Panoya kopyalanamadı. Lütfen manuel olarak kopyalayın!",
"download-successful": "{{descriptor}} indirildi", "download-successful": "{{descriptor}} indirildi",
"click-to-show": "Göstermek için tıkla" "click-to-show": "Görmek için tıkla"
}, },
"peer-ui": { "peer-ui": {
"processing": "İşleniyor…", "processing": "İşleniyor…",
@@ -166,7 +167,11 @@
"close-about_aria-label": "PairDrop Hakkında'yı Kapat", "close-about_aria-label": "PairDrop Hakkında'yı Kapat",
"buy-me-a-coffee_title": "Bana bir kahve al!", "buy-me-a-coffee_title": "Bana bir kahve al!",
"github_title": "GitHub'da PairDrop", "github_title": "GitHub'da PairDrop",
"faq_title": "Sıkça sorulan sorular" "faq_title": "Sıkça sorulan sorular",
"custom_title": "Bizi takip edin",
"privacypolicy_title": "Gizlilik politikamızı açın",
"mastodon_title": "Mastodon'da PairDrop hakkında yazın",
"bluesky_title": "Bizi BlueSky'da takip edin"
}, },
"document-titles": { "document-titles": {
"file-transfer-requested": "Dosya Transferi Talep Edildi", "file-transfer-requested": "Dosya Transferi Talep Edildi",
+7 -2
View File
@@ -12,7 +12,8 @@
"cancel-share-mode": "完成", "cancel-share-mode": "完成",
"join-public-room_title": "暂时加入公共房间", "join-public-room_title": "暂时加入公共房间",
"language-selector_title": "设置语言", "language-selector_title": "设置语言",
"edit-share-mode": "编辑" "edit-share-mode": "编辑",
"expand_title": "展开标题按钮行"
}, },
"instructions": { "instructions": {
"x-instructions_data-drop-peer": "释放以发送到此设备", "x-instructions_data-drop-peer": "释放以发送到此设备",
@@ -114,7 +115,11 @@
"github_title": "PairDrop 在 GitHub 上开源", "github_title": "PairDrop 在 GitHub 上开源",
"claim": "最简单的跨设备传输方案", "claim": "最简单的跨设备传输方案",
"buy-me-a-coffee_title": "帮我买杯咖啡!", "buy-me-a-coffee_title": "帮我买杯咖啡!",
"tweet_title": "关于 PairDrop 的推特" "tweet_title": "关于 PairDrop 的推特",
"bluesky_title": "在 BlueSky 上关注",
"privacypolicy_title": "打开隐私政策",
"mastodon_title": "在 Maston 上推广 PairDrop",
"custom_title": "关注我们"
}, },
"notifications": { "notifications": {
"display-name-changed-permanently": "展示的名字已经永久变更", "display-name-changed-permanently": "展示的名字已经永久变更",
+91 -51
View File
@@ -1,40 +1,49 @@
class Localization { class Localization {
constructor() { constructor() {
Localization.$htmlRoot = document.querySelector('html');
Localization.defaultLocale = "en"; Localization.defaultLocale = "en";
Localization.supportedLocales = ["ar", "ca", "de", "en", "es", "fr", "id", "it", "ja", "nb", "nl", "pt-BR", "ro", "ru", "tr", "zh-CN"]; Localization.supportedLocales = ["ar", "ca", "de", "en", "es", "fr", "id", "it", "ja", "kn", "nb", "nl", "pt-BR", "ro", "ru", "tr", "zh-CN"];
Localization.supportedLocalesRtl = ["ar"]; Localization.supportedLocalesRtl = ["ar"];
Localization.translations = {}; Localization.translations = {};
Localization.defaultTranslations = {}; Localization.translationsDefaultLocale = {};
Localization.systemLocale = Localization.getSupportedOrDefault(navigator.languages); Localization.systemLocale = Localization.getSupportedOrDefaultLocales(navigator.languages);
let storedLanguageCode = localStorage.getItem('language_code'); let storedLanguageCode = localStorage.getItem('language_code');
Localization.initialLocale = storedLanguageCode && Localization.isSupported(storedLanguageCode) Localization.initialLocale = storedLanguageCode && Localization.localeIsSupported(storedLanguageCode)
? storedLanguageCode ? storedLanguageCode
: Localization.systemLocale; : Localization.systemLocale;
} }
static isSupported(locale) { static localeIsSupported(locale) {
return Localization.supportedLocales.indexOf(locale) > -1; return Localization.supportedLocales.indexOf(locale) > -1;
} }
static isRtlLanguage(locale) { static localeIsRtl(locale) {
return Localization.supportedLocalesRtl.indexOf(locale) > -1; return Localization.supportedLocalesRtl.indexOf(locale) > -1;
} }
static isCurrentLocaleRtl() { static currentLocaleIsRtl() {
return Localization.isRtlLanguage(Localization.locale); return Localization.localeIsRtl(Localization.locale);
} }
static getSupportedOrDefault(locales) { static currentLocaleIsDefault() {
return Localization.locale === Localization.defaultLocale
}
static getSupportedOrDefaultLocales(locales) {
// get generic locales not included in locales
// ["en-us", "de-CH", "fr"] --> ["en", "de"]
let localesGeneric = locales let localesGeneric = locales
.map(locale => locale.split("-")[0]) .map(locale => locale.split("-")[0])
.filter(locale => locales.indexOf(locale) === -1); .filter(locale => locales.indexOf(locale) === -1);
return locales.find(Localization.isSupported) // If there is no perfect match for browser locales, try generic locales first before resorting to the default locale
|| localesGeneric.find(Localization.isSupported) return locales.find(Localization.localeIsSupported)
|| localesGeneric.find(Localization.localeIsSupported)
|| Localization.defaultLocale; || Localization.defaultLocale;
} }
@@ -48,16 +57,14 @@ class Localization {
await Localization.setLocale(locale) await Localization.setLocale(locale)
await Localization.translatePage(); await Localization.translatePage();
const htmlRootNode = document.querySelector('html'); if (Localization.localeIsRtl(locale)) {
Localization.$htmlRoot.setAttribute('dir', 'rtl');
if (Localization.isRtlLanguage(locale)) {
htmlRootNode.setAttribute('dir', 'rtl');
} }
else { else {
htmlRootNode.removeAttribute('dir'); Localization.$htmlRoot.removeAttribute('dir');
} }
htmlRootNode.setAttribute('lang', locale); Localization.$htmlRoot.setAttribute('lang', locale);
console.log("Page successfully translated", console.log("Page successfully translated",
@@ -111,75 +118,108 @@ class Localization {
const key = element.getAttribute("data-i18n-key"); const key = element.getAttribute("data-i18n-key");
const attrs = element.getAttribute("data-i18n-attrs").split(" "); const attrs = element.getAttribute("data-i18n-attrs").split(" ");
for (let i in attrs) { attrs.forEach(attr => {
let attr = attrs[i];
if (attr === "text") { if (attr === "text") {
element.innerText = Localization.getTranslation(key); element.innerText = Localization.getTranslation(key);
} }
else { else {
element.setAttribute(attr, Localization.getTranslation(key, attr)); element.setAttribute(attr, Localization.getTranslation(key, attr));
} }
} })
} }
static getTranslation(key, attr = null, data = {}, useDefault = false) { static getTranslationFromTranslationsObj(translationObj, key, attr) {
const keys = key.split(".");
let translationCandidates = useDefault
? Localization.defaultTranslations
: Localization.translations;
let translation; let translation;
try { try {
const keys = key.split(".");
for (let i = 0; i < keys.length - 1; i++) { for (let i = 0; i < keys.length - 1; i++) {
translationCandidates = translationCandidates[keys[i]] // iterate into translation object until last layer
translationObj = translationObj[keys[i]]
} }
let lastKey = keys[keys.length - 1]; let lastKey = keys[keys.length - 1];
if (attr) lastKey += "_" + attr; if (attr) lastKey += "_" + attr;
translation = translationCandidates[lastKey]; translation = translationObj[lastKey];
for (let j in data) {
if (translation.includes(`{{${j}}}`)) {
translation = translation.replace(`{{${j}}}`, data[j]);
} else {
console.warn(`Translation for your language ${Localization.locale.toUpperCase()} misses at least one data placeholder:`, key, attr, data);
Localization.logHelpCallKey(key);
Localization.logHelpCall();
translation = "";
break;
}
}
} catch (e) { } catch (e) {
console.error(e); console.error(e);
translation = "";
} }
if (!translation) { if (!translation) {
if (!useDefault) { throw new Error(`Translation misses entry. Key: ${key} Attribute: ${attr}`);
console.warn(`Missing translation entry for your language ${Localization.locale.toUpperCase()}. Using ${Localization.defaultLocale.toUpperCase()} instead.`, key, attr); }
Localization.logHelpCallKey(key);
Localization.logHelpCall(); return translation;
translation = this.getTranslation(key, attr, data, true); }
static addDataToTranslation(translation, data) {
for (let j in data) {
if (!translation.includes(`{{${j}}}`)) {
throw new Error(`Translation misses data placeholder: ${j}`);
}
// Add data to translation
translation = translation.replace(`{{${j}}}`, data[j]);
}
return translation;
}
static getTranslation(key, attr = null, data = {}, useDefault = false) {
let translationObj = useDefault
? Localization.translationsDefaultLocale
: Localization.translations;
let translation;
try {
translation = Localization.getTranslationFromTranslationsObj(translationObj, key, attr);
translation = Localization.addDataToTranslation(translation, data);
}
catch (e) {
// Log warnings and help calls
console.warn(e);
Localization.logTranslationMissingOrBroken(key, attr, data, useDefault);
Localization.logHelpCallKey(key, attr);
Localization.logHelpCall();
if (useDefault || Localization.currentLocaleIsDefault()) {
// Is default locale already
// Use empty string as translation
translation = ""
} }
else { else {
console.warn("Missing translation in default language:", key, attr); // Is not default locale yet
Localization.logHelpCall(); // Get translation for default language with same arguments
console.log(`Using default language ${Localization.defaultLocale.toUpperCase()} instead.`);
translation = this.getTranslation(key, attr, data, true);
} }
} }
return Localization.escapeHTML(translation); return Localization.escapeHTML(translation);
} }
static logTranslationMissingOrBroken(key, attr, data, useDefault) {
let usedLocale = useDefault
? Localization.defaultLocale.toUpperCase()
: Localization.locale.toUpperCase();
console.warn(`Missing or broken translation for language ${usedLocale}.\n`, 'key:', key, 'attr:', attr, 'data:', data);
}
static logHelpCall() { static logHelpCall() {
console.log("Help translating PairDrop: https://hosted.weblate.org/engage/pairdrop/"); console.log("Help translating PairDrop: https://hosted.weblate.org/engage/pairdrop/");
} }
static logHelpCallKey(key) { static logHelpCallKey(key, attr) {
console.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${Localization.locale.toLowerCase()}/?q=${key}`); let locale = Localization.locale.toLowerCase();
let keyComplete = !attr || attr === "text"
? key
: `${key}_${attr}`;
console.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${locale}/?q=${keyComplete}`);
} }
static escapeHTML(unsafeText) { static escapeHTML(unsafeText) {
+37 -25
View File
@@ -56,13 +56,16 @@ class PairDrop {
await this.backgroundCanvas.fadeIn(); await this.backgroundCanvas.fadeIn();
// Load deferred assets // Load deferred assets
console.log("Load deferred assets...");
await this.loadDeferredAssets(); await this.loadDeferredAssets();
console.log("Loading of deferred assets completed."); console.log("Loading of deferred assets completed.");
console.log("Hydrate UI...");
await this.hydrate(); await this.hydrate();
console.log("UI hydrated."); console.log("UI hydrated.");
// Evaluate url params as soon as ws is connected // Evaluate url params as soon as ws is connected
console.log("Evaluate URL params as soon as websocket connection is established.");
Events.on('ws-connected', _ => this.evaluateUrlParams(), {once: true}); Events.on('ws-connected', _ => this.evaluateUrlParams(), {once: true});
} }
@@ -102,36 +105,40 @@ class PairDrop {
} }
} }
async loadDeferredAssets() { loadDeferredAssets() {
console.log("Load deferred assets"); const stylePromises = this.deferredStyles.map(url => this.loadAndApplyStylesheet(url));
for (const url of this.deferredStyles) { const scriptPromises = this.deferredScripts.map(url => this.loadAndApplyScript(url));
await this.loadAndApplyStylesheet(url);
} return Promise.all([...stylePromises, ...scriptPromises]);
for (const url of this.deferredScripts) {
await this.loadAndApplyScript(url);
}
} }
loadStyleSheet(url) { loadStyleSheet(url) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let stylesheet = document.createElement('link'); let stylesheet = document.createElement('link');
stylesheet.rel = 'stylesheet'; stylesheet.rel = 'preload';
stylesheet.as = 'style';
stylesheet.href = url; stylesheet.href = url;
stylesheet.type = 'text/css'; stylesheet.onload = _ => {
stylesheet.onload = resolve; stylesheet.onload = null;
stylesheet.rel = 'stylesheet';
resolve();
};
stylesheet.onerror = reject; stylesheet.onerror = reject;
document.head.appendChild(stylesheet); document.head.appendChild(stylesheet);
}); });
} }
async loadAndApplyStylesheet(url) { loadAndApplyStylesheet(url) {
try { return new Promise( async (resolve) => {
await this.loadStyleSheet(url); try {
console.log(`Stylesheet loaded successfully: ${url}`); await this.loadStyleSheet(url);
} catch (error) { console.log(`Stylesheet loaded successfully: ${url}`);
console.error('Error loading stylesheet:', error); resolve();
} } catch (error) {
console.error('Error loading stylesheet:', error);
}
});
} }
loadScript(url) { loadScript(url) {
@@ -145,13 +152,16 @@ class PairDrop {
}); });
} }
async loadAndApplyScript(url) { loadAndApplyScript(url) {
try { return new Promise( async (resolve) => {
await this.loadScript(url); try {
console.log(`Script loaded successfully: ${url}`); await this.loadScript(url);
} catch (error) { console.log(`Script loaded successfully: ${url}`);
console.error('Error loading script:', error); resolve();
} } catch (error) {
console.error('Error loading script:', error);
}
});
} }
async hydrate() { async hydrate() {
@@ -223,6 +233,8 @@ class PairDrop {
// remove url params from url // remove url params from url
const urlWithoutParams = getUrlWithoutArguments(); const urlWithoutParams = getUrlWithoutArguments();
window.history.replaceState({}, "Rewrite URL", urlWithoutParams); window.history.replaceState({}, "Rewrite URL", urlWithoutParams);
console.log("URL params evaluated.");
} }
} }
+1 -1
View File
@@ -132,7 +132,7 @@ class HeaderUI {
this.$header.classList.remove('overflow-expanded'); this.$header.classList.remove('overflow-expanded');
const rtlLocale = Localization.isCurrentLocaleRtl(); const rtlLocale = Localization.currentLocaleIsRtl();
let icon; let icon;
const $headerIconsShown = document.querySelectorAll('body > header:first-of-type > *:not([hidden])'); const $headerIconsShown = document.querySelectorAll('body > header:first-of-type > *:not([hidden])');
+155 -68
View File
@@ -172,31 +172,34 @@ class PeersUI {
} }
_onDrop(e) { _onDrop(e) {
e.preventDefault();
if (this.shareMode.active || Dialog.anyDialogShown()) return; if (this.shareMode.active || Dialog.anyDialogShown()) return;
if (!$$('x-peer') || !$$('x-peer').contains(e.target)) { e.preventDefault();
if (e.dataTransfer.files.length > 0) {
Events.fire('activate-share-mode', {files: e.dataTransfer.files});
} else {
for (let i=0; i<e.dataTransfer.items.length; i++) {
if (e.dataTransfer.items[i].type === "text/plain") {
e.dataTransfer.items[i].getAsString(text => {
Events.fire('activate-share-mode', {text: text});
});
}
}
}
}
this._onDragEnd(); this._onDragEnd();
if ($$('x-peer') || !$$('x-peer').contains(e.target)) return; // dropped on peer
const files = e.dataTransfer.files;
const text = e.dataTransfer.getData("text");
if (files.length > 0) {
Events.fire('activate-share-mode', {
files: files
});
}
else if(text.length > 0) {
Events.fire('activate-share-mode', {
text: text
});
}
} }
_onDragOver(e) { _onDragOver(e) {
e.preventDefault();
if (this.shareMode.active || Dialog.anyDialogShown()) return; if (this.shareMode.active || Dialog.anyDialogShown()) return;
e.preventDefault();
this.$xInstructions.setAttribute('drop-bg', true); this.$xInstructions.setAttribute('drop-bg', true);
this.$xNoPeers.setAttribute('drop-bg', true); this.$xNoPeers.setAttribute('drop-bg', true);
} }
@@ -590,6 +593,9 @@ class PeerUI {
_onFilesSelected(e) { _onFilesSelected(e) {
const $input = e.target; const $input = e.target;
const files = $input.files; const files = $input.files;
if (files.length === 0) return;
Events.fire('files-selected', { Events.fire('files-selected', {
files: files, files: files,
to: this._peer.id to: this._peer.id
@@ -630,29 +636,28 @@ class PeerUI {
} }
_onDrop(e) { _onDrop(e) {
e.preventDefault();
if (PeerUI._shareMode.active || Dialog.anyDialogShown()) return; if (PeerUI._shareMode.active || Dialog.anyDialogShown()) return;
if (e.dataTransfer.files.length > 0) { e.preventDefault();
Events.fire('files-selected', {
files: e.dataTransfer.files,
to: this._peer.id
});
} else {
for (let i=0; i<e.dataTransfer.items.length; i++) {
if (e.dataTransfer.items[i].type === "text/plain") {
e.dataTransfer.items[i].getAsString(text => {
Events.fire('send-text', {
text: text,
to: this._peer.id
});
});
}
}
}
this._onDragEnd(); this._onDragEnd();
const peerId = this._peer.id;
const files = e.dataTransfer.files;
const text = e.dataTransfer.getData("text");
if (files.length > 0) {
Events.fire('files-selected', {
files: files,
to: peerId
});
}
else if (text.length > 0) {
Events.fire('send-text', {
text: text,
to: peerId
});
}
} }
_onDragOver() { _onDragOver() {
@@ -1896,6 +1901,8 @@ class SendTextDialog extends Dialog {
this.$submit = this.$el.querySelector('button[type="submit"]'); this.$submit = this.$el.querySelector('button[type="submit"]');
this.$form.addEventListener('submit', e => this._onSubmit(e)); this.$form.addEventListener('submit', e => this._onSubmit(e));
this.$text.addEventListener('input', _ => this._onInput()); this.$text.addEventListener('input', _ => this._onInput());
this.$text.addEventListener('paste', e => this._onPaste(e));
this.$text.addEventListener('drop', e => this._onDrop(e));
Events.on('text-recipient', e => this._onRecipient(e.detail.peerId, e.detail.deviceName)); Events.on('text-recipient', e => this._onRecipient(e.detail.peerId, e.detail.deviceName));
Events.on('keydown', e => this._onKeyDown(e)); Events.on('keydown', e => this._onKeyDown(e));
@@ -1914,6 +1921,40 @@ class SendTextDialog extends Dialog {
} }
} }
async _onDrop(e) {
e.preventDefault()
const text = e.dataTransfer.getData("text");
const selection = window.getSelection();
if (selection.rangeCount) {
selection.deleteFromDocument();
selection.getRangeAt(0).insertNode(document.createTextNode(text));
}
this._onInput();
}
async _onPaste(e) {
e.preventDefault()
const text = (e.clipboardData || window.clipboardData).getData('text');
const selection = window.getSelection();
if (selection.rangeCount) {
selection.deleteFromDocument();
const textNode = document.createTextNode(text);
const range = document.createRange();
range.setStart(textNode, textNode.length);
range.collapse(true);
selection.getRangeAt(0).insertNode(textNode);
selection.removeAllRanges();
selection.addRange(range);
}
this._onInput();
}
_textEmpty() { _textEmpty() {
return !this.$text.innerText || this.$text.innerText === "\n"; return !this.$text.innerText || this.$text.innerText === "\n";
} }
@@ -1978,12 +2019,15 @@ class ReceiveTextDialog extends Dialog {
this._receiveTextQueue = []; this._receiveTextQueue = [];
} }
selectionEmpty() {
return !window.getSelection().toString()
}
async _onKeyDown(e) { async _onKeyDown(e) {
if (!this.isShown()) return if (!this.isShown()) return
if (e.code === "KeyC" && (e.ctrlKey || e.metaKey)) { if (e.code === "KeyC" && (e.ctrlKey || e.metaKey) && this.selectionEmpty()) {
await this._onCopy() await this._onCopy()
this.hide();
} }
else if (e.code === "Escape") { else if (e.code === "Escape") {
this.hide(); this.hide();
@@ -1994,12 +2038,22 @@ class ReceiveTextDialog extends Dialog {
window.blop.play(); window.blop.play();
this._receiveTextQueue.push({text: text, peerId: peerId}); this._receiveTextQueue.push({text: text, peerId: peerId});
this._setDocumentTitleMessages(); this._setDocumentTitleMessages();
changeFavicon("images/favicon-96x96-notification.png");
if (this.isShown()) return; if (this.isShown()) return;
this._dequeueRequests(); this._dequeueRequests();
} }
_dequeueRequests() { _dequeueRequests() {
if (!this._receiveTextQueue.length) return; if (!this._receiveTextQueue.length) {
this.$text.innerHTML = "";
return;
}
this._setDocumentTitleMessages();
changeFavicon("images/favicon-96x96-notification.png");
let {text, peerId} = this._receiveTextQueue.shift(); let {text, peerId} = this._receiveTextQueue.shift();
this._showReceiveTextDialog(text, peerId); this._showReceiveTextDialog(text, peerId);
} }
@@ -2010,26 +2064,68 @@ class ReceiveTextDialog extends Dialog {
this.$displayName.classList.add($(peerId).ui._badgeClassName()); this.$displayName.classList.add($(peerId).ui._badgeClassName());
this.$text.innerText = text; this.$text.innerText = text;
this.$text.classList.remove('text-center');
// Beautify text if text is short // Beautify text if text is not too long
if (text.length < 2000) { if (this.$text.innerText.length <= 300000) {
// replace urls with actual links // Hacky workaround to replace URLs with link nodes in all cases
this.$text.innerHTML = this.$text.innerHTML.replace(/((https?:\/\/|www)[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\-._~:\/?#\[\]@!$&'()*+,;=]+)/g, url => { // 1. Use text variable, find all valid URLs via regex and replace URLs with placeholder
return `<a href="${url}" target="_blank">${url}</a>`; // 2. Use html variable, find placeholders with regex and replace them with link nodes
});
let $textShadow = document.createElement('div');
$textShadow.innerText = text;
let linkNodes = {};
let searchHTML = $textShadow.innerHTML;
const p = "@";
const pRgx = new RegExp(`${p}\\d+`, 'g');
let occP = searchHTML.match(pRgx) || [];
let m = 0;
const allowedDomainChars = "a-zA-Z0-9áàäčçđéèêŋńñóòôöšŧüžæøåëìíîïðùúýþćěłřśţźǎǐǒǔǥǧǩǯəʒâûœÿãõāēīōūăąĉċďĕėęĝğġģĥħĩĭįıĵķĸĺļľņňŏőŕŗŝşťũŭůűųŵŷżאבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ";
const urlRgx = new RegExp(`(^|\\n|\\s|["><\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.])(((https?:\\/\\/)?(?:[${allowedDomainChars}](?:[${allowedDomainChars}-]{0,61}[${allowedDomainChars}])?\\.)+[${allowedDomainChars}][${allowedDomainChars}-]{0,61}[${allowedDomainChars}])(:?\\d*)\\/?([${allowedDomainChars}_\\/\\-#.]*)(\\?([${allowedDomainChars}\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.]*))?)`, 'g');
$textShadow.innerText = text.replace(urlRgx,
(match, whitespaceOrSpecial, url, g3, scheme) => {
let link = url;
// prefix www.example.com with http protocol to prevent it from being a relative link
if (!scheme && link.startsWith('www')) {
link = "http://" + link
}
if (isUrlValid(link)) {
// link is valid -> replace with link node placeholder
// find linkNodePlaceholder that is not yet present in text node
m++;
while (occP.includes(`${p}${m}`)) {
m++;
}
let linkNodePlaceholder = `${p}${m}`;
// add linkNodePlaceholder to text node and save a reference to linkNodes object
linkNodes[linkNodePlaceholder] = `<a href="${link}" target="_blank">${url}</a>`;
return `${whitespaceOrSpecial}${linkNodePlaceholder}`;
}
// link is not valid -> do not replace
return match;
});
this.$text.innerHTML = $textShadow.innerHTML.replace(pRgx,
(m) => {
let urlNode = linkNodes[m];
return urlNode ? urlNode : m;
});
} }
this._evaluateOverflowing(this.$text); this._evaluateOverflowing(this.$text);
this._setDocumentTitleMessages();
changeFavicon("images/favicon-96x96-notification.png");
this.show(); this.show();
} }
_setDocumentTitleMessages() { _setDocumentTitleMessages() {
document.title = !this._receiveTextQueue.length document.title = this._receiveTextQueue.length <= 1
? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop` ? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop`
: `${ Localization.getTranslation("document-titles.message-received-plural", null, {count: this._receiveTextQueue.length + 1}) } - PairDrop`; : `${ Localization.getTranslation("document-titles.message-received-plural", null, {count: this._receiveTextQueue.length + 1}) } - PairDrop`;
} }
@@ -2049,7 +2145,10 @@ class ReceiveTextDialog extends Dialog {
hide() { hide() {
super.hide(); super.hide();
setTimeout(() => this._dequeueRequests(), 500); setTimeout(() => {
this._dequeueRequests();
this.$text.innerHTML = "";
}, 500);
} }
} }
@@ -2420,14 +2519,9 @@ class Notifications {
_downloadNotification(files) { _downloadNotification(files) {
if (document.visibilityState !== 'visible') { if (document.visibilityState !== 'visible') {
let imagesOnly = true; let imagesOnly = files.every(file => file.type.split('/')[0] === 'image');
for(let i=0; i<files.length; i++) {
if (files[i].type.split('/')[0] !== 'image') {
imagesOnly = false;
break;
}
}
let title; let title;
if (files.length === 1) { if (files.length === 1) {
title = `${files[0].name}`; title = `${files[0].name}`;
} }
@@ -2452,15 +2546,8 @@ class Notifications {
_requestNotification(request, peerId) { _requestNotification(request, peerId) {
if (document.visibilityState !== 'visible') { if (document.visibilityState !== 'visible') {
let imagesOnly = true; let imagesOnly = request.header.every(header => header.mime.split('/')[0] === 'image');
for(let i=0; i<request.header.length; i++) { let displayName = $(peerId).querySelector('.name').textContent;
if (request.header[i].mime.split('/')[0] !== 'image') {
imagesOnly = false;
break;
}
}
let displayName = $(peerId).querySelector('.name').textContent
let descriptor; let descriptor;
if (request.header.length === 1) { if (request.header.length === 1) {
+10
View File
@@ -583,4 +583,14 @@ async function decodeBase64Text(base64) {
if (!base64) throw new Error('Base64 is empty'); if (!base64) throw new Error('Base64 is empty');
return decodeURIComponent(escape(window.atob(base64))) return decodeURIComponent(escape(window.atob(base64)))
}
function isUrlValid(url) {
try {
let urlObj = new URL(url);
return true;
}
catch (e) {
return false;
}
} }
+4 -3
View File
@@ -1,4 +1,4 @@
const cacheVersion = 'v1.10.1'; const cacheVersion = 'v1.10.7';
const cacheTitle = `pairdrop-cache-${cacheVersion}`; const cacheTitle = `pairdrop-cache-${cacheVersion}`;
const forceFetch = false; // FOR DEVELOPMENT: Set to true to always update assets instead of using cached versions const forceFetch = false; // FOR DEVELOPMENT: Set to true to always update assets instead of using cached versions
const relativePathsToCache = [ const relativePathsToCache = [
@@ -35,6 +35,7 @@ const relativePathsToCache = [
'lang/id.json', 'lang/id.json',
'lang/it.json', 'lang/it.json',
'lang/ja.json', 'lang/ja.json',
'lang/kn.json',
'lang/nb.json', 'lang/nb.json',
'lang/nl.json', 'lang/nl.json',
'lang/pt-BR.json', 'lang/pt-BR.json',
@@ -192,7 +193,7 @@ const evaluateRequestData = function (request) {
const objectStoreRequest = objectStore.add(fileObjects[i]); const objectStoreRequest = objectStore.add(fileObjects[i]);
objectStoreRequest.onsuccess = _ => { objectStoreRequest.onsuccess = _ => {
if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share-target=files'); if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share_target=files');
} }
} }
} }
@@ -201,7 +202,7 @@ const evaluateRequestData = function (request) {
} }
} }
else { else {
let urlArgument = '?share-target=text'; let urlArgument = '?share_target=text';
if (title) urlArgument += `&title=${title}`; if (title) urlArgument += `&title=${title}`;
if (text) urlArgument += `&text=${text}`; if (text) urlArgument += `&text=${text}`;
+7 -6
View File
@@ -12,10 +12,10 @@
display: block; display: block;
overflow: auto; overflow: auto;
resize: none; resize: none;
line-height: 16px;
max-height: 350px; max-height: 350px;
word-break: break-word; word-break: break-word;
word-wrap: anywhere; word-wrap: anywhere;
white-space: pre-wrap;
} }
.textarea:before { .textarea:before {
@@ -335,6 +335,7 @@ x-dialog x-paper {
display: flex; display: flex;
margin: auto; margin: auto;
flex-direction: column; flex-direction: column;
width: 100%;
max-width: 450px; max-width: 450px;
z-index: 3; z-index: 3;
border-radius: 30px; border-radius: 30px;
@@ -382,10 +383,6 @@ x-dialog:not([show]) x-paper {
transform: scale(0.1); transform: scale(0.1);
} }
x-dialog a {
color: var(--primary-color);
}
/* Pair Devices Dialog & Public Room Dialog */ /* Pair Devices Dialog & Public Room Dialog */
.input-key-container { .input-key-container {
@@ -784,7 +781,7 @@ x-dialog x-paper {
background-color: var(--bg-color-secondary) !important; background-color: var(--bg-color-secondary) !important;
} }
.textarea * { .textarea *:not(a) {
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;
color: unset !important; color: unset !important;
@@ -797,6 +794,10 @@ x-dialog x-paper {
font-weight: unset !important; font-weight: unset !important;
} }
x-dialog a {
color: var(--primary-color);
}
/* Image/Video/Audio Preview */ /* Image/Video/Audio Preview */
.file-preview { .file-preview {
margin-bottom: 15px; margin-bottom: 15px;
+4 -1
View File
@@ -626,12 +626,15 @@ x-dialog:not([show]) x-background {
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: -1;
opacity: 0; opacity: 0;
background-color: var(--accent-color); background-color: var(--accent-color);
transition: opacity 300ms; transition: opacity 300ms;
} }
.icon-button:before {
z-index: -1;
}
.btn:not([disabled]):hover:before, .btn:not([disabled]):hover:before,
.icon-button:hover:before { .icon-button:hover:before {
opacity: 0.3; opacity: 0.3;
+12 -2
View File
@@ -32,10 +32,14 @@ process.on('unhandledRejection', (reason, promise) => {
// Evaluate arguments for deployment with Docker and Node.js // Evaluate arguments for deployment with Docker and Node.js
let conf = {}; let conf = {};
conf.debugMode = process.env.DEBUG_MODE === "true"; conf.debugMode = process.env.DEBUG_MODE === "true";
conf.port = process.env.PORT || 3000; conf.port = process.env.PORT || 3000;
conf.wsFallback = process.argv.includes('--include-ws-fallback') || process.env.WS_FALLBACK === "true"; conf.wsFallback = process.argv.includes('--include-ws-fallback') || process.env.WS_FALLBACK === "true";
conf.rtcConfig = process.env.RTC_CONFIG
conf.rtcConfig = process.env.RTC_CONFIG && process.env.RTC_CONFIG !== "false"
? JSON.parse(fs.readFileSync(process.env.RTC_CONFIG, 'utf8')) ? JSON.parse(fs.readFileSync(process.env.RTC_CONFIG, 'utf8'))
: { : {
"sdpSemantics": "unified-plan", "sdpSemantics": "unified-plan",
@@ -47,7 +51,10 @@ conf.rtcConfig = process.env.RTC_CONFIG
}; };
conf.signalingServer = process.env.SIGNALING_SERVER || false; conf.signalingServer = process.env.SIGNALING_SERVER && process.env.SIGNALING_SERVER !== "false"
? process.env.SIGNALING_SERVER
: false;
conf.ipv6Localize = parseInt(process.env.IPV6_LOCALIZE) || false; conf.ipv6Localize = parseInt(process.env.IPV6_LOCALIZE) || false;
let rateLimit = false; let rateLimit = false;
@@ -61,6 +68,7 @@ else {
} }
} }
conf.rateLimit = rateLimit; conf.rateLimit = rateLimit;
conf.buttons = { conf.buttons = {
"donation_button": { "donation_button": {
"active": process.env.DONATION_BUTTON_ACTIVE, "active": process.env.DONATION_BUTTON_ACTIVE,
@@ -96,8 +104,10 @@ conf.buttons = {
// Evaluate arguments for deployment with Node.js only // Evaluate arguments for deployment with Node.js only
conf.autoStart = process.argv.includes('--auto-restart'); conf.autoStart = process.argv.includes('--auto-restart');
conf.localhostOnly = process.argv.includes('--localhost-only'); conf.localhostOnly = process.argv.includes('--localhost-only');
// Validate configuration // Validate configuration
if (conf.ipv6Localize) { if (conf.ipv6Localize) {
if (!(0 < conf.ipv6Localize && conf.ipv6Localize < 8)) { if (!(0 < conf.ipv6Localize && conf.ipv6Localize < 8)) {