Compare commits

..

87 Commits

Author SHA1 Message Date
schlagmichdoch 2d15271cf2 WIP: Implement WS fallback as real fallback whenever RTC fails after three retries 2024-02-23 12:51:35 +01:00
schlagmichdoch 52198c7efb Fix WSPeers should disconnect on 'peer-left' message, indifferent from 'disconnect' flag 2024-02-22 17:43:11 +01:00
schlagmichdoch 07e46e472e Prevent flickering of text on load by adding defer="true" to deferred style sheets 2024-02-22 15:30:09 +01:00
schlagmichdoch 00f1a20177 Round progress to 4th digit to prevent weird progress bar behavior on reconnect 2024-02-17 12:27:29 +01:00
schlagmichdoch 3c8848d406 Add STATE_TRANSFER_REQUEST_RECEIVED and close transfer request dialog if requesting peer reloads 2024-02-17 12:27:29 +01:00
schlagmichdoch 0d17ada58b NoSleep: Move evaluation if any peer is still busy to the PeerManager 2024-02-17 12:27:28 +01:00
schlagmichdoch 74bd7dd406 Check if RAM would be exceeded before using navigator.share() 2024-02-17 12:27:28 +01:00
schlagmichdoch f4a947527d Move service worker digestion into separate class and add static function to check if it is supported by the browser. Change ram-exceed-ios waring accordingly. 2024-02-17 12:26:21 +01:00
schlagmichdoch 90f10910aa Fix _fileReceived getting called twice 2024-02-15 18:02:23 +01:00
schlagmichdoch aacf24c31f Fix reconnecting by always accepting new ice candidates 2024-02-15 18:02:23 +01:00
schlagmichdoch c0e5b66d41 Fix share menu error detection on iOS 2024-02-15 18:02:23 +01:00
schlagmichdoch 42bd71a3dc Add error status and check if too many bytes are received 2024-02-15 18:02:23 +01:00
schlagmichdoch a98499ea5a Move header comparison to _onTransferHeader function as there is no benefit in doing it after file is received 2024-02-15 18:02:23 +01:00
schlagmichdoch 7c471910ef Tidy up Peer classes 2024-02-15 18:02:15 +01:00
schlagmichdoch da558ddceb Move beforeunload event to Peer class to include it to the WSPeer; Add reset method to Peer class to prevent returning the "unfinished-transfers" warning when closing the page after a peer has left during transfer 2024-02-15 15:18:25 +01:00
schlagmichdoch 1df8fe258e Tidy up zipper functions 2024-02-15 15:18:25 +01:00
schlagmichdoch 65936a4d7d Truncate file used by the sw-file-digester.js after processing 2024-02-15 15:18:25 +01:00
schlagmichdoch 7c6062e1e0 Solve "transfer-complete" and "receive-complete" status detection via css instead of adding a new class 2024-02-13 18:24:08 +01:00
schlagmichdoch 902b5c6b8f Refactor file transfer 2024-02-09 04:11:36 +01:00
schlagmichdoch 19d33e11d8 Implement fallback to download if navigator.share() fails. Refactor ReceiveFileDialog 2024-02-09 04:11:36 +01:00
schlagmichdoch d8908e01ea Add alert for iOS when receiving big files using a private tab 2024-02-09 04:11:36 +01:00
schlagmichdoch 2d2cfec5f0 Add missing checks for transfer states 2024-02-09 04:11:36 +01:00
schlagmichdoch 40a12b5501 Fix progress animation 2024-02-09 04:11:36 +01:00
schlagmichdoch 5ee8bb871e Move file creation to serviceworker to prevent loading everything into RAM 2024-02-09 04:11:36 +01:00
schlagmichdoch ef3c338dad Activate NoSleep on file transfers instead of on click and deactivate when transfer is finished 2024-02-09 04:11:32 +01:00
schlagmichdoch 6d95f3f4e2 Fix canceling file selector on Windows Edge sometimes blocks UI (#257) 2024-02-09 01:59:30 +01:00
schlagmichdoch c33d49702e Animate progress circle and show complete status in blue for 10s 2024-02-09 01:56:23 +01:00
schlagmichdoch 1d62a9ff49 Add state management to network peers 2024-02-09 01:55:37 +01:00
schlagmichdoch 3dd40e238a Refactor _downloadNotification function 2024-02-09 01:55:37 +01:00
schlagmichdoch 417d5421a6 Refactor _displayFiles function; Only show ReceiveFileDialog if share menu is used OR if automatic download has not worked 2024-02-09 01:55:37 +01:00
schlagmichdoch 7af51bbd5f Tidy up chunker code 2024-02-09 01:55:37 +01:00
schlagmichdoch 88739107e4 Remove limit for sending to iOS devices (fixes #211) 2024-02-09 01:55:37 +01:00
schlagmichdoch 6de97e7ff1 Put all log prompts into new Logger class; Only log debugging logs to console if PairDrop is in debug mode; Implement activation of debug mode via URL argument (?debug=true) 2024-02-09 01:55:37 +01:00
schlagmichdoch b61de4eb87 send transfer abortion in some cases; Clarify variable names 2024-02-09 01:55:37 +01:00
schlagmichdoch cfe5b4afda Prevent full datachannel buffer on file end 2024-02-09 01:55:37 +01:00
schlagmichdoch 91fc2b7bf5 Add speed log to browser console 2024-02-09 01:55:37 +01:00
schlagmichdoch c670b39732 Fix byte size conversion 2024-02-09 01:55:37 +01:00
schlagmichdoch e5a09b6be1 Include label in x-peer size transformation; Prevent use of transparency for status & displayName; 2024-02-09 01:55:27 +01:00
schlagmichdoch 1d81b744ea Put blop sound into separate function and only play if on desktop 2024-02-05 21:08:10 +01:00
schlagmichdoch c37412cfd3 Fix variable should be static 2024-02-05 21:08:10 +01:00
schlagmichdoch a5dc8b6da2 Split transfer into message and data transfer and rewrite FileChunkerLogic completely. Condense all Relaying of the Websocket Fallback into one message type 'ws-relay' 2024-02-05 21:08:06 +01:00
schlagmichdoch d81c03a560 Prefill room secrets entry with displayName given by server to prevent displayName undefined in EditPairedDevices Dialog (fixes #221) 2024-02-05 02:16:25 +01:00
schlagmichdoch f22abca783 Implement new status 'connecting', automatic reconnect on disconnect and auto resume of transfer + sending of queued messages. (fixes #260 and #247) 2024-02-05 02:16:17 +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 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
42 changed files with 2649 additions and 1234 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.2 Version: v1.10.6
**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.2 Version: v1.10.6
**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 }}
+85 -91
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.
You want to quickly send a file from your phone to your laptop? Send a file from your phone to your laptop?
<br>You want to share photos in original quality with friends that use a mixture of Android and iOS? <br>Share photos in original quality with friends using Android and iOS?
<br>You want to share private files peer to peer between Linux systems? <br>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) <img src="docs/pairdrop_screenshot_mobile.gif" alt="Screenshot GIF showing PairDrop in use" style="width: 300px">
## Differences to Snapdrop ## Differences to the [Snapdrop](https://github.com/RobinLinus/snapdrop) it is based on
<details><summary>Click to expand</summary> <details><summary>List view</summary>
### Paired Devices and Public Rooms - Internet Transfer ### Paired Devices and Public Rooms Internet Transfer
* Transfer files over the internet between paired devices or by entering temporary public rooms. * 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 in complex network environments (public Wi-Fi, company network, iCloud 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).
+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.6/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.6/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.2", "version": "1.10.6",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "pairdrop", "name": "pairdrop",
"version": "1.10.2", "version": "1.10.6",
"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.2", "version": "1.10.6",
"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

+4 -4
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>
@@ -447,7 +447,7 @@
<div class="center file-preview"></div> <div class="center file-preview"></div>
<div class="row-reverse center btn-row wrap"> <div class="row-reverse center btn-row wrap">
<button id="share-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.share" data-i18n-attrs="text" hidden></button> <button id="share-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.share" data-i18n-attrs="text" hidden></button>
<button id="download-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.download" data-i18n-attrs="text" autofocus disabled></button> <button id="download-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.download" data-i18n-attrs="text" autofocus disabled hidden></button>
<button class="btn btn-rounded btn-grey" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button> <button class="btn btn-rounded btn-grey" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
</div> </div>
</x-paper> </x-paper>
@@ -582,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.2</div> <div class="font-subheading">v1.10.6</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">
@@ -744,7 +744,7 @@
<script src="scripts/ui-main.js" defer></script> <script src="scripts/ui-main.js" defer></script>
<script src="scripts/main.js" defer></script> <script src="scripts/main.js" defer></script>
<!-- Sounds --> <!-- Sounds -->
<audio id="blop" autobuffer="true"> <audio id="blop" preload="metadata" disableremoteplayback="true" x-webkit-airplay="deny" muted>
<source src="sounds/blop.mp3" type="audio/mpeg"> <source src="sounds/blop.mp3" type="audio/mpeg">
<source src="sounds/blop.ogg" type="audio/ogg"> <source src="sounds/blop.ogg" type="audio/ogg">
</audio> </audio>
+2 -2
View File
@@ -48,7 +48,6 @@
"pairing-cleared": "جميع الأجهزة غير مقترنة", "pairing-cleared": "جميع الأجهزة غير مقترنة",
"notifications-enabled": "تم تمكين الإشعارات", "notifications-enabled": "تم تمكين الإشعارات",
"online-requirement-pairing": "يجب أن تكون متصلاً بالإنترنت لإقران الأجهزة", "online-requirement-pairing": "يجب أن تكون متصلاً بالإنترنت لإقران الأجهزة",
"ios-memory-limit": "لا يمكن إرسال ملفات إلى iOS إلا بحجم يصل إلى 200 ميجابايت مرة واحدة",
"online-requirement-public-room": "يجب أن تكون متصلاً بالإنترنت لإنشاء غرفة عامة", "online-requirement-public-room": "يجب أن تكون متصلاً بالإنترنت لإنشاء غرفة عامة",
"copied-text-error": "فشلت الكتابة من الحافظة. انسخ يدويًا!", "copied-text-error": "فشلت الكتابة من الحافظة. انسخ يدويًا!",
"download-successful": "تم تحميل {{descriptor}}", "download-successful": "تم تحميل {{descriptor}}",
@@ -66,7 +65,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": "انقر لإرسال الملفات أو انقر لفترة طويلة لإرسال رسالة",
-1
View File
@@ -144,7 +144,6 @@
"pairing-cleared": "Tots els dispositius desvinculats", "pairing-cleared": "Tots els dispositius desvinculats",
"notifications-enabled": "Notificacions habilitades", "notifications-enabled": "Notificacions habilitades",
"online-requirement-pairing": "Has d'estar en línia per vincular dispositius", "online-requirement-pairing": "Has d'estar en línia per vincular dispositius",
"ios-memory-limit": "Tan sols és possible enviar fitxers de fins a 200 MB a iOS",
"online-requirement-public-room": "Cal que estiguis en línia per poder crear una sala pública", "online-requirement-public-room": "Cal que estiguis en línia per poder crear una sala pública",
"room-url-copied-to-clipboard": "Enllaç a la sala pública copiat al porta-retalls", "room-url-copied-to-clipboard": "Enllaç a la sala pública copiat al porta-retalls",
"copied-text-error": "L'escriptura al porta-retalls ha fallat. Copiar manualment!", "copied-text-error": "L'escriptura al porta-retalls ha fallat. Copiar manualment!",
+1 -2
View File
@@ -138,7 +138,6 @@
"message-transfer-completed": "Nachricht übertragen", "message-transfer-completed": "Nachricht übertragen",
"rate-limit-join-key": "Rate Limit erreicht. Warte 10 Sekunden und versuche es erneut.", "rate-limit-join-key": "Rate Limit erreicht. Warte 10 Sekunden und versuche es erneut.",
"selected-peer-left": "Ausgewählter Peer ist gegangen", "selected-peer-left": "Ausgewählter Peer ist gegangen",
"ios-memory-limit": "Für Übertragungen an iOS Geräte beträgt die maximale Dateigröße 200 MB",
"public-room-left": "Öffentlichen Raum {{publicRoomId}} verlassen", "public-room-left": "Öffentlichen Raum {{publicRoomId}} verlassen",
"copied-to-clipboard-error": "Konnte nicht kopieren. Kopiere manuell.", "copied-to-clipboard-error": "Konnte nicht kopieren. Kopiere manuell.",
"public-room-id-invalid": "Ungültige Raum-ID", "public-room-id-invalid": "Ungültige Raum-ID",
@@ -152,7 +151,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",
+10 -3
View File
@@ -158,11 +158,13 @@
"connecting": "Connecting…", "connecting": "Connecting…",
"files-incorrect": "Files are incorrect", "files-incorrect": "Files are incorrect",
"file-transfer-completed": "File transfer completed", "file-transfer-completed": "File transfer completed",
"ios-memory-limit": "Sending files to iOS is only possible up to 200 MB at once",
"message-transfer-completed": "Message transfer completed", "message-transfer-completed": "Message transfer completed",
"unfinished-transfers-warning": "There are unfinished transfers. Are you sure you want to close PairDrop?", "unfinished-transfers-warning": "There are unfinished transfers. Are you sure you want to close PairDrop?",
"rate-limit-join-key": "Rate limit reached. Wait 10 seconds and try again.", "rate-limit-join-key": "Rate limit reached. Wait 10 seconds and try again.",
"selected-peer-left": "Selected peer left" "selected-peer-left": "Selected peer left",
"error-sharing-size": "Files too big to be shared. They can be downloaded instead.",
"error-sharing-default": "Error while sharing. It can be downloaded instead.",
"ram-exceed-ios": "One of the files is bigger than 250 MB and will crash the page on iOS. Use https and do not use private tabs on the iOS device to prevent this."
}, },
"document-titles": { "document-titles": {
"file-received": "File Received", "file-received": "File Received",
@@ -176,9 +178,14 @@
"click-to-send-share-mode": "Click to send {{descriptor}}", "click-to-send-share-mode": "Click to send {{descriptor}}",
"click-to-send": "Click to send files or right click to send a message", "click-to-send": "Click to send files or right click to send a message",
"connection-hash": "To verify the security of the end-to-end encryption, compare this security number on both devices", "connection-hash": "To verify the security of the end-to-end encryption, compare this security number on both devices",
"connecting": "Connecting…",
"preparing": "Preparing…", "preparing": "Preparing…",
"waiting": "Waiting…", "waiting": "Waiting…",
"processing": "Processing…", "processing": "Processing…",
"transferring": "Transferring…" "transferring": "Sending…",
"receiving": "Receiving…",
"transfer-complete": "Sent",
"receive-complete": "Received",
"error": "Error"
} }
} }
-1
View File
@@ -64,7 +64,6 @@
"pairing-cleared": "Todos los dispositivos han sido desemparejados", "pairing-cleared": "Todos los dispositivos han sido desemparejados",
"notifications-enabled": "Notificaciones habilitadas", "notifications-enabled": "Notificaciones habilitadas",
"online-requirement-pairing": "Debes estar en línea para emparejar dispositivos", "online-requirement-pairing": "Debes estar en línea para emparejar dispositivos",
"ios-memory-limit": "Enviar archivos a iOS sólo admite hasta 200 MB a la vez",
"online-requirement-public-room": "Debes estar en línea para crear una sala pública", "online-requirement-public-room": "Debes estar en línea para crear una sala pública",
"copied-text-error": "Error al escribir en el portapapeles. ¡Cópielo manualmente!", "copied-text-error": "Error al escribir en el portapapeles. ¡Cópielo manualmente!",
"download-successful": "{{descriptor}} descargado", "download-successful": "{{descriptor}} descargado",
-1
View File
@@ -137,7 +137,6 @@
"connecting": "Connexion…", "connecting": "Connexion…",
"files-incorrect": "Les fichiers sont incorrects", "files-incorrect": "Les fichiers sont incorrects",
"file-transfer-completed": "Transfert de fichier terminé", "file-transfer-completed": "Transfert de fichier terminé",
"ios-memory-limit": "L'envoi de fichiers vers iOS n'est possible que jusqu'à 200 Mo à la fois",
"message-transfer-completed": "Transfert de message terminé", "message-transfer-completed": "Transfert de message terminé",
"unfinished-transfers-warning": "Il y a des transferts inachevés. Êtes-vous sûr de vouloir fermer PairDrop ?", "unfinished-transfers-warning": "Il y a des transferts inachevés. Êtes-vous sûr de vouloir fermer PairDrop ?",
"rate-limit-join-key": "Limite de débit atteinte. Attendez 10 secondes et réessayez.", "rate-limit-join-key": "Limite de débit atteinte. Attendez 10 secondes et réessayez.",
+16 -7
View File
@@ -48,7 +48,6 @@
"pairing-cleared": "Semua Perangkat dilepaskan", "pairing-cleared": "Semua Perangkat dilepaskan",
"notifications-enabled": "Notifikasi diaktifkan", "notifications-enabled": "Notifikasi diaktifkan",
"online-requirement-pairing": "Anda harus online untuk memasangkan perangkat", "online-requirement-pairing": "Anda harus online untuk memasangkan perangkat",
"ios-memory-limit": "Mengirim file ke iOS hanya dapat dilakukan hingga 200 MB sekaligus",
"online-requirement-public-room": "Anda harus online untuk membuat ruang publik", "online-requirement-public-room": "Anda harus online untuk membuat ruang publik",
"copied-text-error": "Menyalin ke papan klip gagal. Salinlah secara manual!", "copied-text-error": "Menyalin ke papan klip gagal. Salinlah secara manual!",
"download-successful": "{{descriptor}} diunduh", "download-successful": "{{descriptor}} diunduh",
@@ -58,7 +57,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 +68,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 +84,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 +116,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 +130,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 +149,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",
+2 -2
View File
@@ -40,7 +40,8 @@
"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!"
}, },
"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.",
@@ -128,7 +129,6 @@
"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 abbinare dispositivi",
"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",
+23 -5
View File
@@ -48,7 +48,6 @@
"pairing-cleared": "全てのデバイスのペア設定を解除しました", "pairing-cleared": "全てのデバイスのペア設定を解除しました",
"notifications-enabled": "通知が有効です", "notifications-enabled": "通知が有効です",
"online-requirement-pairing": "デバイスをペア設定するにはオンラインである必要があります", "online-requirement-pairing": "デバイスをペア設定するにはオンラインである必要があります",
"ios-memory-limit": "iOSへのファイル送信は一度に200MBまでしかできません",
"online-requirement-public-room": "パブリックルームを作成するにはオンラインである必要があります", "online-requirement-public-room": "パブリックルームを作成するにはオンラインである必要があります",
"copied-text-error": "クリップボードにコピーできませんでした。手動でコピーしてください。", "copied-text-error": "クリップボードにコピーできませんでした。手動でコピーしてください。",
"download-successful": "{{descriptor}}をダウンロードしました", "download-successful": "{{descriptor}}をダウンロードしました",
@@ -69,7 +68,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 +84,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 +149,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 +166,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": "ファイルの転送がリクエストされました",
+7 -3
View File
@@ -13,7 +13,8 @@
"about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ತೆರೆಯಿರಿ", "about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ತೆರೆಯಿರಿ",
"theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ", "theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ",
"edit-share-mode": "ಎಡಿಟ್ ಮಾಡಿ", "edit-share-mode": "ಎಡಿಟ್ ಮಾಡಿ",
"cancel-share-mode": "ರದ್ದುಗೊಳಿಸಿ" "cancel-share-mode": "ರದ್ದುಗೊಳಿಸಿ",
"expand_title": "ಹೆಡರ್ ಬಟನ್ ಸಾಲನ್ನು ವಿಸ್ತರಿಸಿ"
}, },
"dialogs": { "dialogs": {
"message_placeholder": "ಪಠ್ಯ", "message_placeholder": "ಪಠ್ಯ",
@@ -127,7 +128,6 @@
"pairing-cleared": "ಎಲ್ಲಾ ಸಾಧನಗಳನ್ನು ಜೋಡಿಯಾಗಿ ತೆಗೆಯಲಾಗಿದೆ", "pairing-cleared": "ಎಲ್ಲಾ ಸಾಧನಗಳನ್ನು ಜೋಡಿಯಾಗಿ ತೆಗೆಯಲಾಗಿದೆ",
"notifications-enabled": "ಸೂಚನೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ", "notifications-enabled": "ಸೂಚನೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ",
"online-requirement-pairing": "ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಲು ನೀವು ಆನ್‌ಲೈನ್‌ ಇರಬೇಕು", "online-requirement-pairing": "ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಲು ನೀವು ಆನ್‌ಲೈನ್‌ ಇರಬೇಕು",
"ios-memory-limit": "iOSಗೆ ಫೈಲ್‌ಗಳನ್ನು ಕಳುಹಿಸುವುದು ಒಂದೇ ಬಾರಿಗೆ 200 MB ವರೆಗೆ ಮಾತ್ರ ಸಾಧ್ಯವಾಗಿದೆ",
"online-requirement-public-room": "ಸಾರ್ವಜನಿಕ ಕೊಠಡಿಯನ್ನು ರಚಿಸಲು ನೀವು ಆನ್‌ಲೈನ್‌ ಇರಬೇಕು", "online-requirement-public-room": "ಸಾರ್ವಜನಿಕ ಕೊಠಡಿಯನ್ನು ರಚಿಸಲು ನೀವು ಆನ್‌ಲೈನ್‌ ಇರಬೇಕು",
"room-url-copied-to-clipboard": "ಸಾರ್ವಜನಿಕ ಕೊಠಡಿಯ ಲಿಂಕ್ ಅನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ನಕಲಿಸಲಾಗಿದೆ", "room-url-copied-to-clipboard": "ಸಾರ್ವಜನಿಕ ಕೊಠಡಿಯ ಲಿಂಕ್ ಅನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ನಕಲಿಸಲಾಗಿದೆ",
"copied-text-error": "ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ಬರೆಯುವುದು ವಿಫಲವಾಗಿದೆ. ಕೈಯಾರೆ ನಕಲಿಸಿ!", "copied-text-error": "ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ಬರೆಯುವುದು ವಿಫಲವಾಗಿದೆ. ಕೈಯಾರೆ ನಕಲಿಸಿ!",
@@ -173,7 +173,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": "ಫೈಲ್ ವರ್ಗಾವಣೆಗೆ ವಿನಂತಿಸಲಾಗಿದೆ",
-1
View File
@@ -116,7 +116,6 @@
"request-title": "{{name}} ønsker å overføre {{count}} {{descriptor}}", "request-title": "{{name}} ønsker å overføre {{count}} {{descriptor}}",
"message-received": "Melding mottatt av {{name}} - Klikk for å åpne", "message-received": "Melding mottatt av {{name}} - Klikk for å åpne",
"files-incorrect": "Filene er uriktige", "files-incorrect": "Filene er uriktige",
"ios-memory-limit": "Forsendelse av filer til iOS er kun mulig opptil 200 MB av gangen",
"unfinished-transfers-warning": "Lukk med ufullførte overføringer?", "unfinished-transfers-warning": "Lukk med ufullførte overføringer?",
"rate-limit-join-key": "Forsøksgrense overskredet. Vent 10 sek. og prøv igjen." "rate-limit-join-key": "Forsøksgrense overskredet. Vent 10 sek. og prøv igjen."
}, },
-1
View File
@@ -48,7 +48,6 @@
"pairing-cleared": "Alle apparaten ontkoppeld", "pairing-cleared": "Alle apparaten ontkoppeld",
"notifications-enabled": "Meldingen geactiveerd", "notifications-enabled": "Meldingen geactiveerd",
"online-requirement-pairing": "U moet online zijn om apparaten te koppelen", "online-requirement-pairing": "U moet online zijn om apparaten te koppelen",
"ios-memory-limit": "Bestandsoverdrachten naar iOS kunnen slechts met 200 MB per keer",
"online-requirement-public-room": "U moet online zijn om een openbare kamer te maken", "online-requirement-public-room": "U moet online zijn om een openbare kamer te maken",
"copied-text-error": "Schrijven naar klembord mislukt. Kopieer handmatig!", "copied-text-error": "Schrijven naar klembord mislukt. Kopieer handmatig!",
"download-successful": "{{descriptor}} downloaden", "download-successful": "{{descriptor}} downloaden",
-1
View File
@@ -153,7 +153,6 @@
"connecting": "Conectando…", "connecting": "Conectando…",
"files-incorrect": "Os arquivos estão incorretos", "files-incorrect": "Os arquivos estão incorretos",
"file-transfer-completed": "Transferência de arquivo concluída", "file-transfer-completed": "Transferência de arquivo concluída",
"ios-memory-limit": "Enviar arquivos para iOS só é possível até 200 MB de uma vez",
"message-transfer-completed": "Transferência de mensagem concluída", "message-transfer-completed": "Transferência de mensagem concluída",
"unfinished-transfers-warning": "Há transferências inacabadas. Tem certeza de que deseja fechar o PairDrop?", "unfinished-transfers-warning": "Há transferências inacabadas. Tem certeza de que deseja fechar o PairDrop?",
"rate-limit-join-key": "Limite de taxa atingido. Aguarde 10 segundos e tente novamente.", "rate-limit-join-key": "Limite de taxa atingido. Aguarde 10 segundos e tente novamente.",
+29 -11
View File
@@ -48,7 +48,6 @@
"pairing-cleared": "Toate dispozitivele sunt decuplate", "pairing-cleared": "Toate dispozitivele sunt decuplate",
"notifications-enabled": "Notificări activate", "notifications-enabled": "Notificări activate",
"online-requirement-pairing": "Trebuie să fiți online pentru a asocia dispozitivele", "online-requirement-pairing": "Trebuie să fiți online pentru a asocia dispozitivele",
"ios-memory-limit": "Trimiterea de fișiere pe iOS este posibilă doar până la 200 MB simultan",
"online-requirement-public-room": "Trebuie să fiți online pentru a crea o cameră publică", "online-requirement-public-room": "Trebuie să fiți online pentru a crea o cameră publică",
"copied-text-error": "Scrierea în clipboard a eșuat. Copiați manual!", "copied-text-error": "Scrierea în clipboard a eșuat. Copiați manual!",
"download-successful": "{{descriptor}} descărcat", "download-successful": "{{descriptor}} descărcat",
@@ -58,7 +57,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 +68,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 +84,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 +100,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 +116,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 +130,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 +149,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 +166,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",
-1
View File
@@ -121,7 +121,6 @@
"online-requirement": "Для сопряжения устройств вам нужно быть в сети.", "online-requirement": "Для сопряжения устройств вам нужно быть в сети.",
"files-incorrect": "Файлы неверны", "files-incorrect": "Файлы неверны",
"message-transfer-completed": "Передача сообщения завершена", "message-transfer-completed": "Передача сообщения завершена",
"ios-memory-limit": "Отправка файлов на iOS устройства возможна только до 200 МБ за один раз",
"selected-peer-left": "Выбранный узел вышел", "selected-peer-left": "Выбранный узел вышел",
"request-title": "{{name}} хотел бы передать {{count}} {{descriptor}}", "request-title": "{{name}} хотел бы передать {{count}} {{descriptor}}",
"rate-limit-join-key": "Достигнут предел скорости. Подождите 10 секунд и повторите попытку.", "rate-limit-join-key": "Достигнут предел скорости. Подождите 10 секунд и повторите попытку.",
+7 -3
View File
@@ -12,7 +12,8 @@
"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",
@@ -144,7 +145,6 @@
"pairing-cleared": "Tüm cihazlar eşleştirmeden çıkarıldı", "pairing-cleared": "Tüm cihazlar eşleştirmeden çıkarıldı",
"notifications-enabled": "Bildirimler etkinleştirildi", "notifications-enabled": "Bildirimler etkinleştirildi",
"online-requirement-pairing": "Cihazları eşleştirmek için çevrimiçi olmanız lazım", "online-requirement-pairing": "Cihazları eşleştirmek için çevrimiçi olmanız lazım",
"ios-memory-limit": "iOS'a tek seferde sadece 200MB'a kadar dosya gönderebilirsin",
"online-requirement-public-room": "Genel oda oluşturmak için çevrimiçi olmanız lazım", "online-requirement-public-room": "Genel oda oluşturmak için çevrimiçi olmanız lazım",
"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!",
@@ -166,7 +166,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 -3
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": "展示的名字已经永久变更",
@@ -149,7 +154,6 @@
"files-incorrect": "文件不正确", "files-incorrect": "文件不正确",
"file-transfer-completed": "文件传输已完成", "file-transfer-completed": "文件传输已完成",
"connecting": "连接中…", "connecting": "连接中…",
"ios-memory-limit": "向 iOS 发送文件 一次最多只能发送 200 MB",
"rate-limit-join-key": "已达连接限制。请等待 10秒 后再试。", "rate-limit-join-key": "已达连接限制。请等待 10秒 后再试。",
"public-room-left": "已退出公共房间 {{publicRoomId}}", "public-room-left": "已退出公共房间 {{publicRoomId}}",
"copied-to-clipboard-error": "无法复制。请手动复制。", "copied-to-clipboard-error": "无法复制。请手动复制。",
+1 -1
View File
@@ -10,7 +10,7 @@ class BrowserTabsConnector {
} }
_onMessage(e) { _onMessage(e) {
console.log('Broadcast:', e.data) Logger.debug('Broadcast:', e.data)
switch (e.data.type) { switch (e.data.type) {
case 'self-display-name-changed': case 'self-display-name-changed':
Events.fire('self-display-name-changed', e.data.detail); Events.fire('self-display-name-changed', e.data.detail);
+7 -7
View File
@@ -67,7 +67,7 @@ class Localization {
Localization.$htmlRoot.setAttribute('lang', locale); Localization.$htmlRoot.setAttribute('lang', locale);
console.log("Page successfully translated", Logger.debug("Page successfully translated",
`System language: ${Localization.systemLocale}`, `System language: ${Localization.systemLocale}`,
`Selected language: ${locale}` `Selected language: ${locale}`
); );
@@ -145,7 +145,7 @@ class Localization {
translation = translationObj[lastKey]; translation = translationObj[lastKey];
} catch (e) { } catch (e) {
console.error(e); Logger.error(e);
} }
if (!translation) { if (!translation) {
@@ -179,7 +179,7 @@ class Localization {
} }
catch (e) { catch (e) {
// Log warnings and help calls // Log warnings and help calls
console.warn(e); Logger.warn(e);
Localization.logTranslationMissingOrBroken(key, attr, data, useDefault); Localization.logTranslationMissingOrBroken(key, attr, data, useDefault);
Localization.logHelpCallKey(key, attr); Localization.logHelpCallKey(key, attr);
Localization.logHelpCall(); Localization.logHelpCall();
@@ -192,7 +192,7 @@ class Localization {
else { else {
// Is not default locale yet // Is not default locale yet
// Get translation for default language with same arguments // Get translation for default language with same arguments
console.log(`Using default language ${Localization.defaultLocale.toUpperCase()} instead.`); Logger.debug(`Using default language ${Localization.defaultLocale.toUpperCase()} instead.`);
translation = this.getTranslation(key, attr, data, true); translation = this.getTranslation(key, attr, data, true);
} }
} }
@@ -205,11 +205,11 @@ class Localization {
? Localization.defaultLocale.toUpperCase() ? Localization.defaultLocale.toUpperCase()
: Localization.locale.toUpperCase(); : Localization.locale.toUpperCase();
console.warn(`Missing or broken translation for language ${usedLocale}.\n`, 'key:', key, 'attr:', attr, 'data:', data); Logger.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/"); Logger.warn("Help translating PairDrop: https://hosted.weblate.org/engage/pairdrop/");
} }
static logHelpCallKey(key, attr) { static logHelpCallKey(key, attr) {
@@ -219,7 +219,7 @@ class Localization {
? key ? key
: `${key}_${attr}`; : `${key}_${attr}`;
console.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${locale}/?q=${keyComplete}`); Logger.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${locale}/?q=${keyComplete}`);
} }
static escapeHTML(unsafeText) { static escapeHTML(unsafeText) {
+39 -13
View File
@@ -1,3 +1,23 @@
class Logger {
static debug(message, ...optionalParams) {
if (window.debugMode) {
console.debug("DEBUG:", message, ...optionalParams);
}
}
static log(message, ...optionalParams) {
console.log("LOG:", message, ...optionalParams);
}
static warn(message, ...optionalParams) {
console.warn("WARN:", message, ...optionalParams);
}
static error(message, ...optionalParams) {
console.error("ERROR:", message, ...optionalParams);
}
}
class PairDrop { class PairDrop {
constructor() { constructor() {
@@ -34,14 +54,14 @@ class PairDrop {
this.initialize() this.initialize()
.then(_ => { .then(_ => {
console.log("Initialization completed."); Logger.log("Initialization completed.");
}); });
} }
async initialize() { async initialize() {
// Translate page before fading in // Translate page before fading in
await this.localization.setInitialTranslation() await this.localization.setInitialTranslation()
console.log("Initial translation successful."); Logger.log("Initial translation successful.");
// Show "Loading..." until connected to WsServer // Show "Loading..." until connected to WsServer
await this.footerUI.showLoading(); await this.footerUI.showLoading();
@@ -56,16 +76,16 @@ class PairDrop {
await this.backgroundCanvas.fadeIn(); await this.backgroundCanvas.fadeIn();
// Load deferred assets // Load deferred assets
console.log("Load deferred assets..."); Logger.log("Load deferred assets...");
await this.loadDeferredAssets(); await this.loadDeferredAssets();
console.log("Loading of deferred assets completed."); Logger.log("Loading of deferred assets completed.");
console.log("Hydrate UI..."); Logger.log("Hydrate UI...");
await this.hydrate(); await this.hydrate();
console.log("UI hydrated."); Logger.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."); Logger.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});
} }
@@ -74,7 +94,7 @@ class PairDrop {
navigator.serviceWorker navigator.serviceWorker
.register('service-worker.js') .register('service-worker.js')
.then(serviceWorker => { .then(serviceWorker => {
console.log('Service Worker registered'); Logger.log('Service Worker registered');
window.serviceWorker = serviceWorker window.serviceWorker = serviceWorker
}); });
} }
@@ -117,6 +137,7 @@ class PairDrop {
let stylesheet = document.createElement('link'); let stylesheet = document.createElement('link');
stylesheet.rel = 'preload'; stylesheet.rel = 'preload';
stylesheet.as = 'style'; stylesheet.as = 'style';
stylesheet.defer = true;
stylesheet.href = url; stylesheet.href = url;
stylesheet.onload = _ => { stylesheet.onload = _ => {
stylesheet.onload = null; stylesheet.onload = null;
@@ -133,10 +154,10 @@ class PairDrop {
return new Promise( async (resolve) => { return new Promise( async (resolve) => {
try { try {
await this.loadStyleSheet(url); await this.loadStyleSheet(url);
console.log(`Stylesheet loaded successfully: ${url}`); Logger.log(`Stylesheet loaded successfully: ${url}`);
resolve(); resolve();
} catch (error) { } catch (error) {
console.error('Error loading stylesheet:', error); Logger.error('Error loading stylesheet:', error);
} }
}); });
} }
@@ -156,10 +177,10 @@ class PairDrop {
return new Promise( async (resolve) => { return new Promise( async (resolve) => {
try { try {
await this.loadScript(url); await this.loadScript(url);
console.log(`Script loaded successfully: ${url}`); Logger.log(`Script loaded successfully: ${url}`);
resolve(); resolve();
} catch (error) { } catch (error) {
console.error('Error loading script:', error); Logger.error('Error loading script:', error);
} }
}); });
} }
@@ -229,12 +250,17 @@ class PairDrop {
this.publicRoomDialog._createPublicRoom(); this.publicRoomDialog._createPublicRoom();
} }
} }
else if (urlParams.has("debug") && urlParams.get("debug") === "true") {
window.debugMode = true;
}
if (!window.debugMode) {
// 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."); Logger.log("URL params evaluated.");
} }
} }
+1296 -480
View File
File diff suppressed because it is too large Load Diff
+24 -25
View File
@@ -7,19 +7,18 @@ class PersistentStorage {
const DBOpenRequest = window.indexedDB.open('pairdrop_store', 5); const DBOpenRequest = window.indexedDB.open('pairdrop_store', 5);
DBOpenRequest.onerror = e => { DBOpenRequest.onerror = e => {
PersistentStorage.logBrowserNotCapable(); PersistentStorage.logBrowserNotCapable();
console.log('Error initializing database: '); Logger.error('Error initializing database:', e);
console.log(e)
}; };
DBOpenRequest.onsuccess = _ => { DBOpenRequest.onsuccess = _ => {
console.log('Database initialised.'); Logger.debug('Database initialised.');
}; };
DBOpenRequest.onupgradeneeded = async e => { DBOpenRequest.onupgradeneeded = async e => {
const db = e.target.result; const db = e.target.result;
const txn = e.target.transaction; const txn = e.target.transaction;
db.onerror = e => console.log('Error loading database: ' + e); db.onerror = e => Logger.error('Error loading database:', e);
console.log(`Upgrading IndexedDB database from version ${e.oldVersion} to version ${e.newVersion}`); Logger.debug(`Upgrading IndexedDB database from version ${e.oldVersion} to version ${e.newVersion}`);
if (e.oldVersion === 0) { if (e.oldVersion === 0) {
// initiate v1 // initiate v1
@@ -54,7 +53,7 @@ class PersistentStorage {
} }
static logBrowserNotCapable() { static logBrowserNotCapable() {
console.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed."); Logger.log("This browser does not support IndexedDB. Paired devices will be gone after the browser is closed.");
} }
static set(key, value) { static set(key, value) {
@@ -66,7 +65,7 @@ class PersistentStorage {
const objectStore = transaction.objectStore('keyval'); const objectStore = transaction.objectStore('keyval');
const objectStoreRequest = objectStore.put(value, key); const objectStoreRequest = objectStore.put(value, key);
objectStoreRequest.onsuccess = _ => { objectStoreRequest.onsuccess = _ => {
console.log(`Request successful. Added key-pair: ${key} - ${value}`); Logger.debug(`Request successful. Added key-pair: ${key} - ${value}`);
resolve(value); resolve(value);
}; };
} }
@@ -85,7 +84,7 @@ class PersistentStorage {
const objectStore = transaction.objectStore('keyval'); const objectStore = transaction.objectStore('keyval');
const objectStoreRequest = objectStore.get(key); const objectStoreRequest = objectStore.get(key);
objectStoreRequest.onsuccess = _ => { objectStoreRequest.onsuccess = _ => {
console.log(`Request successful. Retrieved key-pair: ${key} - ${objectStoreRequest.result}`); Logger.debug(`Request successful. Retrieved key-pair: ${key} - ${objectStoreRequest.result}`);
resolve(objectStoreRequest.result); resolve(objectStoreRequest.result);
} }
} }
@@ -104,7 +103,7 @@ class PersistentStorage {
const objectStore = transaction.objectStore('keyval'); const objectStore = transaction.objectStore('keyval');
const objectStoreRequest = objectStore.delete(key); const objectStoreRequest = objectStore.delete(key);
objectStoreRequest.onsuccess = _ => { objectStoreRequest.onsuccess = _ => {
console.log(`Request successful. Deleted key: ${key}`); Logger.debug(`Request successful. Deleted key: ${key}`);
resolve(); resolve();
}; };
} }
@@ -128,7 +127,7 @@ class PersistentStorage {
'auto_accept': false 'auto_accept': false
}); });
objectStoreRequest.onsuccess = e => { objectStoreRequest.onsuccess = e => {
console.log(`Request successful. RoomSecret added: ${e.target.result}`); Logger.debug(`Request successful. RoomSecret added: ${e.target.result}`);
resolve(); resolve();
} }
} }
@@ -145,7 +144,7 @@ class PersistentStorage {
for (let i = 0; i < roomSecrets.length; i++) { for (let i = 0; i < roomSecrets.length; i++) {
secrets.push(roomSecrets[i].secret); secrets.push(roomSecrets[i].secret);
} }
console.log(`Request successful. Retrieved ${secrets.length} room_secrets`); Logger.debug(`Request successful. Retrieved ${secrets.length} room_secrets`);
return(secrets); return(secrets);
} catch (e) { } catch (e) {
this.logBrowserNotCapable(); this.logBrowserNotCapable();
@@ -182,13 +181,13 @@ class PersistentStorage {
objectStoreRequestKey.onsuccess = e => { objectStoreRequestKey.onsuccess = e => {
const key = e.target.result; const key = e.target.result;
if (!key) { if (!key) {
console.log(`Nothing to retrieve. Entry for room_secret not existing: ${roomSecret}`); Logger.debug(`Nothing to retrieve. Entry for room_secret not existing: ${roomSecret}`);
resolve(); resolve();
return; return;
} }
const objectStoreRequestRetrieval = objectStore.get(key); const objectStoreRequestRetrieval = objectStore.get(key);
objectStoreRequestRetrieval.onsuccess = e => { objectStoreRequestRetrieval.onsuccess = e => {
console.log(`Request successful. Retrieved entry for room_secret: ${key}`); Logger.debug(`Request successful. Retrieved entry for room_secret: ${key}`);
resolve({ resolve({
"entry": e.target.result, "entry": e.target.result,
"key": key "key": key
@@ -215,14 +214,14 @@ class PersistentStorage {
const objectStoreRequestKey = objectStore.index("secret").getKey(roomSecret); const objectStoreRequestKey = objectStore.index("secret").getKey(roomSecret);
objectStoreRequestKey.onsuccess = e => { objectStoreRequestKey.onsuccess = e => {
if (!e.target.result) { if (!e.target.result) {
console.log(`Nothing to delete. room_secret not existing: ${roomSecret}`); Logger.debug(`Nothing to delete. room_secret not existing: ${roomSecret}`);
resolve(); resolve();
return; return;
} }
const key = e.target.result; const key = e.target.result;
const objectStoreRequestDeletion = objectStore.delete(key); const objectStoreRequestDeletion = objectStore.delete(key);
objectStoreRequestDeletion.onsuccess = _ => { objectStoreRequestDeletion.onsuccess = _ => {
console.log(`Request successful. Deleted room_secret: ${key}`); Logger.debug(`Request successful. Deleted room_secret: ${key}`);
resolve(roomSecret); resolve(roomSecret);
} }
objectStoreRequestDeletion.onerror = e => { objectStoreRequestDeletion.onerror = e => {
@@ -245,7 +244,7 @@ class PersistentStorage {
const objectStore = transaction.objectStore('room_secrets'); const objectStore = transaction.objectStore('room_secrets');
const objectStoreRequest = objectStore.clear(); const objectStoreRequest = objectStore.clear();
objectStoreRequest.onsuccess = _ => { objectStoreRequest.onsuccess = _ => {
console.log('Request successful. All room_secrets cleared'); Logger.debug('Request successful. All room_secrets cleared');
resolve(); resolve();
}; };
} }
@@ -255,15 +254,15 @@ class PersistentStorage {
}) })
} }
static updateRoomSecretNames(roomSecret, displayName, deviceName) { static updateRoomSecretDisplayName(roomSecret, displayName) {
return this.updateRoomSecret(roomSecret, undefined, displayName, deviceName); return this.updateRoomSecret(roomSecret, null, displayName, null);
} }
static updateRoomSecretAutoAccept(roomSecret, autoAccept) { static updateRoomSecretAutoAccept(roomSecret, autoAccept) {
return this.updateRoomSecret(roomSecret, undefined, undefined, undefined, autoAccept); return this.updateRoomSecret(roomSecret, null, null, null, autoAccept);
} }
static updateRoomSecret(roomSecret, updatedRoomSecret = undefined, updatedDisplayName = undefined, updatedDeviceName = undefined, updatedAutoAccept = undefined) { static updateRoomSecret(roomSecret, updatedRoomSecret = null, updatedDisplayName = null, updatedDeviceName = null, updatedAutoAccept = null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const DBOpenRequest = window.indexedDB.open('pairdrop_store'); const DBOpenRequest = window.indexedDB.open('pairdrop_store');
DBOpenRequest.onsuccess = e => { DBOpenRequest.onsuccess = e => {
@@ -278,16 +277,16 @@ class PersistentStorage {
const objectStore = transaction.objectStore('room_secrets'); const objectStore = transaction.objectStore('room_secrets');
// Do not use `updatedRoomSecret ?? roomSecretEntry.entry.secret` to ensure compatibility with older browsers // Do not use `updatedRoomSecret ?? roomSecretEntry.entry.secret` to ensure compatibility with older browsers
const updatedRoomSecretEntry = { const updatedRoomSecretEntry = {
'secret': updatedRoomSecret !== undefined ? updatedRoomSecret : roomSecretEntry.entry.secret, 'secret': updatedRoomSecret !== null ? updatedRoomSecret : roomSecretEntry.entry.secret,
'display_name': updatedDisplayName !== undefined ? updatedDisplayName : roomSecretEntry.entry.display_name, 'display_name': updatedDisplayName !== null ? updatedDisplayName : roomSecretEntry.entry.display_name,
'device_name': updatedDeviceName !== undefined ? updatedDeviceName : roomSecretEntry.entry.device_name, 'device_name': updatedDeviceName !== null ? updatedDeviceName : roomSecretEntry.entry.device_name,
'auto_accept': updatedAutoAccept !== undefined ? updatedAutoAccept : roomSecretEntry.entry.auto_accept 'auto_accept': updatedAutoAccept !== null ? updatedAutoAccept : roomSecretEntry.entry.auto_accept
}; };
const objectStoreRequestUpdate = objectStore.put(updatedRoomSecretEntry, roomSecretEntry.key); const objectStoreRequestUpdate = objectStore.put(updatedRoomSecretEntry, roomSecretEntry.key);
objectStoreRequestUpdate.onsuccess = e => { objectStoreRequestUpdate.onsuccess = e => {
console.log(`Request successful. Updated room_secret: ${roomSecretEntry.key}`); Logger.debug(`Request successful. Updated room_secret: ${roomSecretEntry.key}`);
resolve({ resolve({
"entry": updatedRoomSecretEntry, "entry": updatedRoomSecretEntry,
"key": roomSecretEntry.key "key": roomSecretEntry.key
+79
View File
@@ -0,0 +1,79 @@
self.addEventListener('message', async e => {
try {
switch (e.data.type) {
case "check-support":
await checkSupport();
break;
case "part":
await onPart(e.data.name, e.data.buffer, e.data.offset);
break;
case "get-file":
await onGetFile(e.data.name);
break;
case "delete-file":
await onDeleteFile(e.data.name);
break;
}
}
catch (e) {
self.postMessage({type: "error", error: e});
}
})
async function checkSupport() {
try {
await getAccessHandle("test.txt");
self.postMessage({type: "support", supported: true});
}
catch (e) {
self.postMessage({type: "support", supported: false});
}
}
async function getFileHandle(fileName) {
const root = await navigator.storage.getDirectory();
return await root.getFileHandle(fileName, {create: true});
}
async function getAccessHandle(fileName) {
const fileHandle = await getFileHandle(fileName);
// Create FileSystemSyncAccessHandle on the file.
return await fileHandle.createSyncAccessHandle();
}
async function onPart(fileName, buffer, offset) {
const accessHandle = await getAccessHandle(fileName);
// Write the message to the end of the file.
let encodedMessage = new DataView(buffer);
accessHandle.write(encodedMessage, { at: offset });
// Always close FileSystemSyncAccessHandle if done.
accessHandle.close(); accessHandle.close();
self.postMessage({type: "part", part: encodedMessage});
encodedMessage = null;
}
async function onGetFile(fileName) {
const fileHandle = await getFileHandle(fileName);
let file = await fileHandle.getFile();
self.postMessage({type: "file", file: file});
}
async function onDeleteFile(fileName) {
const accessHandle = await getAccessHandle(fileName);
// Truncate the file to 0 bytes
accessHandle.truncate(0);
// Persist changes to disk.
accessHandle.flush();
// Always close FileSystemSyncAccessHandle if done.
accessHandle.close();
self.postMessage({type: "file-deleted"});
}
+3 -3
View File
@@ -238,7 +238,7 @@ class FooterUI {
if (!displayName) return; if (!displayName) return;
console.log("Retrieved edited display name:", displayName) Logger.debug("Retrieved edited display name:", displayName)
Events.fire('self-display-name-changed', displayName); Events.fire('self-display-name-changed', displayName);
} }
@@ -275,7 +275,7 @@ class FooterUI {
Events.fire('notify-user', Localization.getTranslation("notifications.display-name-changed-permanently")); Events.fire('notify-user', Localization.getTranslation("notifications.display-name-changed-permanently"));
}) })
.catch(_ => { .catch(_ => {
console.log("This browser does not support IndexedDB. Use localStorage instead."); Logger.debug("This browser does not support IndexedDB. Use localStorage instead.");
localStorage.setItem('edited_display_name', newDisplayName); localStorage.setItem('edited_display_name', newDisplayName);
Events.fire('notify-user', Localization.getTranslation("notifications.display-name-changed-temporarily")); Events.fire('notify-user', Localization.getTranslation("notifications.display-name-changed-temporarily"));
}) })
@@ -287,7 +287,7 @@ class FooterUI {
else { else {
PersistentStorage.delete('edited_display_name') PersistentStorage.delete('edited_display_name')
.catch(_ => { .catch(_ => {
console.log("This browser does not support IndexedDB. Use localStorage instead.") Logger.debug("This browser does not support IndexedDB. Use localStorage instead.")
localStorage.removeItem('edited_display_name'); localStorage.removeItem('edited_display_name');
}) })
.finally(() => { .finally(() => {
+738 -360
View File
File diff suppressed because it is too large Load Diff
+59 -23
View File
@@ -62,41 +62,67 @@ window.isMobile = window.iOS || window.android;
// Helper functions // Helper functions
const audioPlayer = (() => {
const blop = document.getElementById('blop');
blop.addEventListener('ended', _ => {
blop.muted = true
});
return {
playBlop() {
if (window.isMobile) return;
blop.muted = false;
blop.play();
}
}
})();
const zipper = (() => { const zipper = (() => {
let zipWriter;
return { return {
createNewZipWriter() { async getObjectUrlOfZipFile(files, onZipProgressCallback){
zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true, level: 0 }); try {
}, const zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"));
addFile(file, options) {
return zipWriter.add(file.name, new zip.BlobReader(file), options); let bytesProcessed = 0;
}, for (let i = 0; i < files.length; i++) {
async getBlobURL() { await zipWriter.add(
if (zipWriter) { files[i].name,
const blobURL = URL.createObjectURL(await zipWriter.close()); new zip.BlobReader(files[i]),
zipWriter = null; {
return blobURL; onprogress: (progress) => onZipProgressCallback(bytesProcessed + progress)
} }
else { );
throw new Error("Zip file closed"); bytesProcessed += files[i].size;
} }
},
async getZipFile(filename = "archive.zip") { return URL.createObjectURL(await zipWriter.close());
if (zipWriter) {
const file = new File([await zipWriter.close()], filename, {type: "application/zip"});
zipWriter = null;
return file;
} }
else { catch (e) {
throw new Error("Zip file closed"); Logger.error(e);
return false;
} }
}, },
async getEntries(file, options) { async getEntries(file, options) {
try {
return await (new zip.ZipReader(new zip.BlobReader(file))).getEntries(options); return await (new zip.ZipReader(new zip.BlobReader(file))).getEntries(options);
}
catch (e) {
Logger.error(e);
return false;
}
}, },
async getData(entry, options) { async getData(entry, options) {
try {
return await entry.getData(new zip.BlobWriter(), options); return await entry.getData(new zip.BlobWriter(), options);
}
catch (e) {
Logger.error(e);
return false;
}
}, },
}; };
@@ -521,7 +547,7 @@ function getThumbnailAsDataUrl(file, width = undefined, height = undefined, qual
let dataUrl = canvas.toDataURL("image/jpeg", quality); let dataUrl = canvas.toDataURL("image/jpeg", quality);
resolve(dataUrl); resolve(dataUrl);
} catch (e) { } catch (e) {
console.error(e); Logger.error(e);
reject(new Error(`Could not create an image thumbnail from type ${file.type}`)); reject(new Error(`Could not create an image thumbnail from type ${file.type}`));
} }
}) })
@@ -584,3 +610,13 @@ async function decodeBase64Text(base64) {
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;
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
const cacheVersion = 'v1.10.2'; const cacheVersion = 'v1.10.6';
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 = [
@@ -193,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');
} }
} }
} }
@@ -202,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}`;
+31 -16
View File
@@ -16,6 +16,7 @@
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 {
@@ -104,6 +105,8 @@ x-peer {
padding: 8px; padding: 8px;
align-content: start; align-content: start;
flex-wrap: wrap; flex-wrap: wrap;
transition: transform 150ms;
will-change: transform;
} }
x-peer input[type="file"] { x-peer input[type="file"] {
@@ -121,8 +124,6 @@ x-peer label {
x-peer x-icon { x-peer x-icon {
--icon-size: 40px; --icon-size: 40px;
margin-bottom: 4px; margin-bottom: 4px;
transition: transform 150ms;
will-change: transform;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -148,7 +149,7 @@ x-peer:not(.type-ip):not(.type-secret).type-public-id .icon-wrapper {
.highlight-wrapper { .highlight-wrapper {
align-self: center; align-self: center;
align-items: center; align-items: center;
margin: 7px auto 0; margin: 10px auto 0;
height: 6px; height: 6px;
} }
@@ -187,14 +188,16 @@ x-peer:not(.type-public-id) .highlight-room-public-id {
display: none; display: none;
} }
x-peer:not([status]):hover x-icon, x-peer:is(:not([status]), [status$=-complete], [status=error]):hover,
x-peer:not([status]):focus x-icon { x-peer:is(:not([status]), [status$=-complete], [status=error]):focus {
transform: scale(1.05); transform: scale(1.05);
} }
x-peer[status] x-icon { x-peer[status]:not([status$=-complete]) x-icon {
box-shadow: none; box-shadow: none;
opacity: 0.8; }
x-peer[status] {
transform: scale(1); transform: scale(1);
} }
@@ -237,7 +240,7 @@ x-peer.ws-peer .highlight-wrapper {
.status, .status,
.device-name { .device-name {
opacity: 0.7; color: color-mix(in srgb, rgb(var(--text-color)) 30%, grey);
white-space: nowrap; white-space: nowrap;
} }
@@ -246,14 +249,22 @@ x-peer[status] .device-name {
display: none; display: none;
} }
x-peer[status] { x-peer[status]:not([status$=-complete]):not([status=error]) {
pointer-events: none; pointer-events: none;
} }
x-peer x-icon { x-peer {
animation: pop 600ms ease-out 1; animation: pop 600ms ease-out 1;
} }
x-peer[status$=-complete] .status {
color: var(--primary-color);
}
x-peer[status=error] .status {
color: var(--error-color);
}
@keyframes pop { @keyframes pop {
0% { 0% {
transform: scale(0.7); transform: scale(0.7);
@@ -335,6 +346,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 +394,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 {
@@ -747,7 +755,6 @@ x-dialog .dialog-subheader {
top: -8px; top: -8px;
clip: rect(0px, 80px, 80px, 40px); clip: rect(0px, 80px, 80px, 40px);
--progress: rotate(0deg); --progress: rotate(0deg);
transition: transform 200ms;
} }
.circle { .circle {
@@ -761,6 +768,10 @@ x-dialog .dialog-subheader {
transform: var(--progress); transform: var(--progress);
} }
.animate .circle {
transition: transform 200ms;
}
.over50 { .over50 {
clip: rect(auto, auto, auto, auto); clip: rect(auto, auto, auto, auto);
} }
@@ -784,7 +795,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 +808,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;
+1
View File
@@ -921,6 +921,7 @@ x-peers:empty~x-instructions {
body { body {
/* Constant colors */ /* Constant colors */
--primary-color: #4285f4; --primary-color: #4285f4;
--error-color: #ff6b6b;
--paired-device-color: #00a69c; --paired-device-color: #00a69c;
--public-room-color: #ed9d01; --public-room-color: #ed9d01;
--accent-color: var(--primary-color); --accent-color: var(--primary-color);
+4 -14
View File
@@ -89,22 +89,12 @@ export default class PairDropWsServer {
this._onLeavePublicRoom(sender); this._onLeavePublicRoom(sender);
break; break;
case 'signal': case 'signal':
this._signalAndRelay(sender, message); this._signalAndWsRelay(sender, message);
break; break;
case 'request': case 'ws-relay':
case 'header':
case 'partition':
case 'partition-received':
case 'progress':
case 'files-transfer-response':
case 'file-transfer-complete':
case 'message-transfer-complete':
case 'text':
case 'display-name-changed':
case 'ws-chunk':
// relay ws-fallback // relay ws-fallback
if (this._conf.wsFallback) { if (this._conf.wsFallback) {
this._signalAndRelay(sender, message); this._signalAndWsRelay(sender, message);
} }
else { else {
console.log("Websocket fallback is not activated on this instance.") console.log("Websocket fallback is not activated on this instance.")
@@ -112,7 +102,7 @@ export default class PairDropWsServer {
} }
} }
_signalAndRelay(sender, message) { _signalAndWsRelay(sender, message) {
const room = message.roomType === 'ip' const room = message.roomType === 'ip'
? sender.ip ? sender.ip
: message.roomId; : message.roomId;