mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2026-04-06 18:03:48 +00:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6287c4cf0 | ||
|
|
c83e55b448 | ||
|
|
49160f9b02 | ||
|
|
7be2830a08 | ||
|
|
1f3dd080a0 | ||
|
|
5d709966af | ||
|
|
99b0c6ff01 | ||
|
|
76e08927de | ||
|
|
9118b0ae06 | ||
|
|
b36105b1cf | ||
|
|
ad4f727d19 | ||
|
|
3fa0873bc4 | ||
|
|
a03482bc7f | ||
|
|
40aa46fdd9 | ||
|
|
9003094e49 | ||
|
|
0459a361c3 | ||
|
|
10a669d7c6 | ||
|
|
3fbca72d74 | ||
|
|
f048c4f1bd | ||
|
|
6c1672ba25 | ||
|
|
caf19bdb45 | ||
|
|
5dcda58ce5 | ||
|
|
59360fb047 | ||
|
|
2e15a018da | ||
|
|
041261be2a | ||
|
|
f152645452 | ||
|
|
a7f5d336c3 | ||
|
|
c9e4510f65 | ||
|
|
70f74923e6 | ||
|
|
6217042f12 | ||
|
|
4659ef2041 | ||
|
|
a21881b7ca | ||
|
|
f589e9471e | ||
|
|
067117159a | ||
|
|
d901ca031a | ||
|
|
21fa6f07d8 | ||
|
|
f49b800f9e | ||
|
|
1a9fa8e60a | ||
|
|
79cc8e5590 | ||
|
|
89addd6649 | ||
|
|
ff883fb994 | ||
|
|
ccb2170287 | ||
|
|
3454eebf37 | ||
|
|
b6203288bf | ||
|
|
bea0fa5b9c | ||
|
|
48090ec41c | ||
|
|
229084fab3 | ||
|
|
d58f380565 | ||
|
|
676c68b6e7 | ||
|
|
dd0dc21db5 | ||
|
|
4e72339479 | ||
|
|
c3e92d7d4c | ||
|
|
b90924af68 | ||
|
|
4f80ab4401 | ||
|
|
f299c90f47 | ||
|
|
6737dcacf7 | ||
|
|
5d39bf4a76 | ||
|
|
5c70c873ab | ||
|
|
b336c75b72 | ||
|
|
b3f5619f2d | ||
|
|
939ca3d35d | ||
|
|
c2ee459231 | ||
|
|
c08b324d6a | ||
|
|
d3a623d352 | ||
|
|
d8f9532039 | ||
|
|
9847feeb52 | ||
|
|
ae75cdbc62 | ||
|
|
e2299f1d0f | ||
|
|
e06fa47c96 | ||
|
|
09451caf86 | ||
|
|
16921cb855 | ||
|
|
9b8d824bfc | ||
|
|
211328c2f7 | ||
|
|
224e6f0db9 | ||
|
|
a3690994b8 | ||
|
|
866d8a0e16 | ||
|
|
132b2ffa65 | ||
|
|
b084a9b83b | ||
|
|
77f2866893 | ||
|
|
4a5a2ceb67 | ||
|
|
214d557feb |
4
.github/ISSUE_TEMPLATE/bug-report.md
vendored
4
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -36,7 +36,7 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Bug occurs on official PairDrop instance https://pairdrop.net/**
|
||||
No | Yes
|
||||
Version: v1.10.0
|
||||
Version: v1.10.7
|
||||
|
||||
**Bug occurs on self-hosted PairDrop instance**
|
||||
No | Yes
|
||||
@@ -44,7 +44,7 @@ No | Yes
|
||||
**Self-Hosted Setup**
|
||||
Proxy: Nginx | Apache2
|
||||
Deployment: docker run | docker compose | npm run start:prod
|
||||
Version: v1.10.0
|
||||
Version: v1.10.7
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
7
.github/workflows/zip-release.yml
vendored
7
.github/workflows/zip-release.yml
vendored
@@ -19,17 +19,18 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Archive Release
|
||||
uses: thedoctor0/zip-release@b57d897cb5d60cb78b51a507f63fa184cfe35554 # v0.7.6
|
||||
with:
|
||||
type: 'zip'
|
||||
filename: 'pairdrop-cli.zip'
|
||||
path: 'pairdrop-cli'
|
||||
directory: 'pairdrop-cli'
|
||||
exclusions: '*.git* /*node_modules/* .editorconfig'
|
||||
- name: Upload Release
|
||||
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
|
||||
with:
|
||||
artifacts: "pairdrop-cli.zip"
|
||||
artifacts: "pairdrop-cli/pairdrop-cli.zip"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
178
README.md
178
README.md
@@ -3,133 +3,127 @@
|
||||
<img src="public/images/android-chrome-512x512.png" alt="Logo" width="150" height="150">
|
||||
</a>
|
||||
|
||||
<h1>PairDrop</h1>
|
||||
# _Send it_, with [PairDrop](https://pairdrop.net)
|
||||
|
||||
<p>
|
||||
Local file sharing in your browser. Inspired by Apple's AirDrop.
|
||||
<br />
|
||||
<a href="https://pairdrop.net"><strong>Explore »</strong></a>
|
||||
Local file sharing <a href="https://pairdrop.net"><strong>in your web browser</strong></a>.
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://github.com/schlagmichdoch/PairDrop/issues">Report Bug</a>
|
||||
·
|
||||
<a href="https://github.com/schlagmichdoch/PairDrop/issues">Request Feature</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>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## 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
|
||||
- Send images, documents or text via peer to peer connection to devices on the same local network.
|
||||
- Internet Transfers
|
||||
- Join temporary public rooms to transfer files easily over the internet!
|
||||
- Web-Application
|
||||
- As it is web based, it runs on all devices.
|
||||
- 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.
|
||||
- Internet transfers
|
||||
- Join temporary public rooms to transfer files easily over the Internet.
|
||||
- Web-app
|
||||
- Works on all devices with a modern web-browser.
|
||||
|
||||
Send a file from your phone to your laptop?
|
||||
<br>Share photos in original quality with friends using Android and iOS?
|
||||
<br>Share private files peer-to-peer between Linux systems?
|
||||
|
||||
You want to quickly send a file from your phone to your laptop?
|
||||
<br>You want to share photos in original quality with friends that use a mixture of Android and iOS?
|
||||
<br>You want to share private files peer to peer between Linux systems?
|
||||
<br>AirDrop is unreliable again?
|
||||
<br>_Send it with PairDrop!_
|
||||
<img src="docs/pairdrop_screenshot_mobile.gif" alt="Screenshot GIF showing PairDrop in use" style="width: 300px">
|
||||
|
||||
Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop)
|
||||
## Differences to the [Snapdrop](https://github.com/RobinLinus/snapdrop) it is based on
|
||||
<details><summary>List view</summary>
|
||||
|
||||
## Differences to Snapdrop
|
||||
<details><summary>Click to expand</summary>
|
||||
|
||||
### Paired Devices and Public Rooms - Internet Transfer
|
||||
* Transfer files over the internet between paired devices or by entering temporary public rooms.
|
||||
* Connect to devices in complex network environments (public Wi-Fi, company network, Apple Private Relay, VPN etc.).
|
||||
### Paired Devices and Public Rooms — Internet Transfer
|
||||
* Transfer files over the Internet between paired devices or by entering temporary public rooms.
|
||||
* Connect to devices in complex network environments (public Wi-Fi, company network, iCloud Private Relay, VPN, etc.).
|
||||
* 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.
|
||||
* 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
|
||||
* 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.
|
||||
* Paired devices are persistent. You find your devices even after reopening PairDrop.
|
||||
* You can edit and unpair devices easily
|
||||
* Ideal to always connect easily to your own devices
|
||||
|
||||
Always connect to known devices
|
||||
|
||||
* Pair devices via a 6-digit code or a QR-Code.
|
||||
* 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
|
||||
* 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)
|
||||
* Files are transferred only after a request is accepted first. On transfer completion files are downloaded automatically if possible.
|
||||
Connect to others in complex network situations, or over the Internet.
|
||||
|
||||
* 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
|
||||
* On iOS and Android, in addition to downloading, files can be shared or saved to the gallery via the Share menu.
|
||||
* Multiple files are transferred at once with an overall progress indicator
|
||||
* 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.
|
||||
|
||||
### 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 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 files directly via command-line interface](docs/how-to.md#send-directly-via-command-line-interface)
|
||||
* [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 directly from the "Share" menu on iOS](docs/how-to.md#send-directly-from-share-menu-on-ios)
|
||||
* [Send directly from the "Share" menu on Android](docs/how-to.md#send-directly-from-share-menu-on-android)
|
||||
* [Send directly via the command-line interface](docs/how-to.md#send-directly-via-command-line-interface)
|
||||
|
||||
### Other changes
|
||||
* Change your display name permanently to easily differentiate your devices
|
||||
* [Paste files/text and choose the recipient afterwords ](https://github.com/RobinLinus/snapdrop/pull/534)
|
||||
### Other Changes
|
||||
* Change your display name to easily differentiate your devices.
|
||||
* [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)
|
||||
* Warn user before PairDrop is closed on file transfer
|
||||
* 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))
|
||||
* Switch theme back to auto/system after darkmode or lightmode is enabled
|
||||
* [Video and audio preview](https://github.com/RobinLinus/snapdrop/pull/455) (Thanks [@victorwads](https://github.com/victorwads))
|
||||
* Switch theme back to auto/system after dark or light mode is on
|
||||
* 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))
|
||||
* 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)
|
||||
* Built-in translations via [Weblate](https://hosted.weblate.org/engage/pairdrop/)
|
||||
* Airy design (Thanks [@Avieshek](https://linktr.ee/avieshek/))
|
||||
* When hosting PairDrop yourself, you can [set your own STUN/TURN servers](docs/host-your-own.md#specify-stunturn-servers)
|
||||
* Translations.
|
||||
|
||||
</details>
|
||||
|
||||
## Screenshots
|
||||
<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
|
||||
## Translate PairDrop on [Hosted Weblate](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>
|
||||
|
||||
## 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
|
||||
[pull request](https://github.com/schlagmichdoch/pairdrop/pulls) but follow
|
||||
[pull request](https://github.com/schlagmichdoch/pairdrop/pulls), following the
|
||||
[Contributing Guidelines](CONTRIBUTING.md).
|
||||
|
||||
@@ -399,7 +399,8 @@ RTC_CONFIG="rtc_config.json"
|
||||
|
||||
You can host an instance that uses another signaling server
|
||||
This can be useful if you don't want to trust the client files that are hosted on another instance but still want to connect to devices that use https://pairdrop.net.
|
||||
### Host Websocket Server (for VPN)
|
||||
|
||||
### Specify Signaling Server
|
||||
|
||||
```bash
|
||||
SIGNALING_SERVER="pairdrop.net"
|
||||
@@ -415,10 +416,48 @@ SIGNALING_SERVER="pairdrop.net"
|
||||
> E.g. host your own client files under *pairdrop.your-domain.com* but use the official signaling server under *pairdrop.net*
|
||||
> This way devices connecting to *pairdrop.your-domain.com* and *pairdrop.net* can discover each other.
|
||||
>
|
||||
> Beware that the version of your PairDrop server is compatible with the version of the signaling server.
|
||||
> Beware that the version of your PairDrop server must be compatible with the version of the signaling server.
|
||||
>
|
||||
> `WS_SERVER` must be a valid url without the protocol prefix.
|
||||
> `SIGNALING_SERVER` must be a valid url without the protocol prefix.
|
||||
> Examples of valid values: `pairdrop.net`, `pairdrop.your-domain.com:3000`, `your-domain.com/pairdrop`
|
||||
|
||||
<br>
|
||||
|
||||
### Customizable buttons for the _About PairDrop_ page
|
||||
|
||||
```bash
|
||||
DONATION_BUTTON_ACTIVE=true
|
||||
DONATION_BUTTON_LINK="https://www.buymeacoffee.com/pairdrop"
|
||||
DONATION_BUTTON_TITLE="Buy me a coffee"
|
||||
TWITTER_BUTTON_ACTIVE=true
|
||||
TWITTER_BUTTON_LINK="https://twitter.com/account"
|
||||
TWITTER_BUTTON_TITLE="Find me on Twitter"
|
||||
MASTODON_BUTTON_ACTIVE=true
|
||||
MASTODON_BUTTON_LINK="https://mastodon.social/account"
|
||||
MASTODON_BUTTON_TITLE="Find me on Mastodon"
|
||||
BLUESKY_BUTTON_ACTIVE=true
|
||||
BLUESKY_BUTTON_LINK="https://bsky.app/profile/account"
|
||||
BLUESKY_BUTTON_TITLE="Find me on Bluesky"
|
||||
CUSTOM_BUTTON_ACTIVE=true
|
||||
CUSTOM_BUTTON_LINK="https://your-custom-social-network.net/account"
|
||||
CUSTOM_BUTTON_TITLE="Find me on this custom social network"
|
||||
PRIVACYPOLICY_BUTTON_ACTIVE=true
|
||||
PRIVACYPOLICY_BUTTON_LINK="https://link-to-your-privacy-policy.net"
|
||||
PRIVACYPOLICY_BUTTON_TITLE="Open our privacy policy"
|
||||
```
|
||||
|
||||
> Default: unset
|
||||
>
|
||||
> By default, clients will show the default button configuration: GitHub, BuyMeACoffee, Twitter, and FAQ on GitHub.
|
||||
>
|
||||
> The GitHub and FAQ on GitHub buttons are essential, so they are always shown.
|
||||
>
|
||||
> The other buttons can be customized:
|
||||
>
|
||||
> * `*_BUTTON_ACTIVE`: set this to `true` to show a natively hidden button or to `false` to hide a normally shown button
|
||||
> * `*_BUTTON_LINK`: set this to any URL to overwrite the href attribute of the button
|
||||
> * `*_BUTTON_TITLE`: set this to overwrite the hover title of the button. This will prevent the title from being translated.
|
||||
|
||||
<br>
|
||||
|
||||
## Healthcheck
|
||||
|
||||
@@ -24,7 +24,7 @@ This opens PairDrop in the default browser where you can choose the receiver.
|
||||
```bash
|
||||
pairdrop -h
|
||||
```
|
||||
```bash
|
||||
```
|
||||
Send files or text with PairDrop via command-line interface.
|
||||
Current domain: https://pairdrop-dev.onrender.com/
|
||||
|
||||
@@ -35,44 +35,61 @@ Send text: pairdrop -t "text"
|
||||
Specify domain: pairdrop -d "https://pairdrop.net/"
|
||||
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>
|
||||
|
||||
### 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)
|
||||
2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/`
|
||||
3. Make sure the bash file `/usr/local/bin/pairdrop-cli/pairdrop` is executable. Otherwise, use `chmod +x pairdrop`
|
||||
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/`
|
||||
|
||||
<br>
|
||||
|
||||
#### Mac
|
||||
1. add bash file to `/usr/local/bin`
|
||||
```shell
|
||||
wget "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.10.7/pairdrop-cli.zip"
|
||||
```
|
||||
or
|
||||
```shell
|
||||
curl -LO "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.10.7/pairdrop-cli.zip"
|
||||
```
|
||||
2. Unzip the archive to a folder of your choice e.g. `/usr/share/pairdrop-cli/`
|
||||
```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>
|
||||
|
||||
#### Windows
|
||||
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`
|
||||
3. Search for and open `Edit environment variables for your account`
|
||||
4. Click `Environment Variables…`
|
||||
5. Under *System Variables* select `Path` and click *Edit...*
|
||||
6. Click *New*, insert the preferred folder (`C:\Program Files\pairdrop-cli`), click *OK* until all windows are closed
|
||||
7. Reopen Command prompt window
|
||||
3. Inside this folder, copy the file _.pairdrop-cli-config.example_ to _.pairdrop-cli-config_
|
||||
4. Search for and open `Edit environment variables for your account`
|
||||
5. Click `Environment Variables…`
|
||||
6. Under _System Variables_ select `Path` and click _Edit..._
|
||||
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/).
|
||||
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 \
|
||||
pairdrop-cli (the bash file) via the Git Bash.
|
||||
|
||||
Then, you can also use pairdrop-cli from the default Windows Command Prompt
|
||||
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>
|
||||
|
||||
@@ -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:
|
||||
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\`
|
||||
3. Copy the shortcut _send with PairDrop.lnk_
|
||||
4. Hit Windows Key+R, type: `shell:sendto` and hit Enter.
|
||||
5. Paste the copied shortcut into the directory
|
||||
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: \
|
||||
3. Inside this folder, copy the file _.pairdrop-cli-config.example_ to _.pairdrop-cli-config_
|
||||
4. Copy the shortcut _send with PairDrop.lnk_
|
||||
5. Hit Windows Key+R, type: `shell:sendto` and hit Enter.
|
||||
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"`
|
||||
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
|
||||
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
|
||||
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)
|
||||
2. Unzip the archive to a folder of your choice e.g. `/usr/local/bin/pairdrop-cli/`
|
||||
3. Copy the shell file _send-with-pairdrop.sh_ to `/home/<user>/.local/share/nautilus/scripts/`
|
||||
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`)
|
||||
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:
|
||||
1. Register _pairdrop_ as executable via [guide above](#linux).
|
||||
2. Copy the shell file _send-with-pairdrop_ to `~/.local/share/nautilus/scripts/` to include it in the context menu
|
||||
```shell
|
||||
cp /usr/share/pairdrop-cli/send-with-pairdrop ~/.local/share/nautilus/scripts/
|
||||
```
|
||||
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>
|
||||
|
||||
@@ -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)
|
||||
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))
|
||||
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)
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.10.0",
|
||||
"version": "1.10.7",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pairdrop",
|
||||
"version": "1.10.0",
|
||||
"version": "1.10.7",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"express-rate-limit": "^7.1.5",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"unique-names-generator": "^4.3.0",
|
||||
"ws": "^8.15.0"
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=15"
|
||||
@@ -640,9 +640,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz",
|
||||
"integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==",
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
|
||||
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
@@ -1102,9 +1102,9 @@
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.15.0.tgz",
|
||||
"integrity": "sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw==",
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
|
||||
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.10.0",
|
||||
"version": "1.10.7",
|
||||
"type": "module",
|
||||
"description": "",
|
||||
"main": "server/index.js",
|
||||
@@ -15,7 +15,7 @@
|
||||
"express-rate-limit": "^7.1.5",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"unique-names-generator": "^4.3.0",
|
||||
"ws": "^8.15.0"
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=15"
|
||||
|
||||
1
pairdrop-cli/.pairdrop-cli-config.example
Normal file
1
pairdrop-cli/.pairdrop-cli-config.example
Normal file
@@ -0,0 +1 @@
|
||||
DOMAIN=https://pairdrop.net/
|
||||
@@ -1,6 +1,9 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# PairDrop version when this file was last changed
|
||||
version="v1.10.4"
|
||||
|
||||
############################################################
|
||||
# Help #
|
||||
############################################################
|
||||
@@ -17,7 +20,7 @@ help()
|
||||
echo -e "Specify domain:\t\t$(basename "$0") -d \"https://pairdrop.net/\""
|
||||
echo -e "Show this help text:\t$(basename "$0") (-h|--help)"
|
||||
echo
|
||||
echo "This pairdrop-cli version was released alongside v1.10.0"
|
||||
echo "This pairdrop-cli version was released alongside ${version}"
|
||||
}
|
||||
|
||||
openPairDrop()
|
||||
@@ -337,12 +340,15 @@ popd > '/dev/null';
|
||||
|
||||
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" ] &&
|
||||
specifyDomain "https://pairdrop.net/" &&
|
||||
[ ! -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
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# edit this to point to the pairdrop-cli executable
|
||||
pathToPairDropCli="/usr/local/bin/pairdrop-cli/pairdrop"
|
||||
|
||||
# Initialize an array
|
||||
lines=()
|
||||
|
||||
@@ -17,4 +14,4 @@ length=${#lines[@]}
|
||||
# Remove the last entry
|
||||
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 |
@@ -35,6 +35,7 @@
|
||||
<meta property="og:image" content="images/logo_transparent_512x512.png">
|
||||
<!-- Resources -->
|
||||
<link rel="preload" href="lang/en.json" as="fetch">
|
||||
<link rel="preload" href="fonts/OpenSans/static/OpenSans-Medium.ttf" as="font" type="font/ttf" crossorigin>
|
||||
<link rel="stylesheet" type="text/css" href="styles/styles-main.css">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
</head>
|
||||
@@ -138,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>
|
||||
</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.routed" data-i18n-attrs="text"></span>
|
||||
<span data-i18n-key="footer.webrtc" data-i18n-attrs="text"></span>
|
||||
@@ -191,6 +192,11 @@
|
||||
<span> - </span>
|
||||
<span>(Arabic)</span>
|
||||
</button>
|
||||
<button class="btn fw wrap" value="ca">
|
||||
<span>Català</span>
|
||||
<span> - </span>
|
||||
<span>(Catalan)</span>
|
||||
</button>
|
||||
<button class="btn fw wrap" value="de">
|
||||
<span>Deutsch</span>
|
||||
<span> - </span>
|
||||
@@ -219,6 +225,11 @@
|
||||
<span> - </span>
|
||||
<span>(Italian)</span>
|
||||
</button>
|
||||
<button class="btn fw wrap" value="kn">
|
||||
<span>ಕನ್ನಡ</span>
|
||||
<span> - </span>
|
||||
<span>(Kannada)</span>
|
||||
</button>
|
||||
<button class="btn fw wrap" value="nl">
|
||||
<span>Nederlands</span>
|
||||
<span> - </span>
|
||||
@@ -571,7 +582,7 @@
|
||||
</svg>
|
||||
<div class="title-wrapper" dir="ltr">
|
||||
<h1>PairDrop</h1>
|
||||
<div class="font-subheading">v1.10.0</div>
|
||||
<div class="font-subheading">v1.10.7</div>
|
||||
</div>
|
||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
|
||||
<div class="row">
|
||||
@@ -580,16 +591,36 @@
|
||||
<use xlink:href="#github"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://www.buymeacoffee.com/pairdrop" rel="noreferrer" data-i18n-key="about.buy-me-a-coffee" data-i18n-attrs="title">
|
||||
<a class="icon-button" id="donation-btn" target="_blank" href="https://www.buymeacoffee.com/pairdrop" rel="noreferrer" data-i18n-key="about.buy-me-a-coffee" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#monetarization"></use>
|
||||
<use xlink:href="#donation"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" rel="noreferrer" data-i18n-key="about.tweet" data-i18n-attrs="title">
|
||||
<a class="icon-button" id="twitter-btn" target="_blank" href="https://twitter.com/intent/tweet?text=https%3A%2F%2Fpairdrop.net%20by%20https%3A%2F%2Fgithub.com%2Fschlagmichdoch%2F&" rel="noreferrer" data-i18n-key="about.tweet" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#twitter"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" id="mastodon-btn" target="_blank" rel="noreferrer" data-i18n-key="about.mastodon" data-i18n-attrs="title" hidden>
|
||||
<svg class="icon">
|
||||
<use xlink:href="#mastodon"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" id="bluesky-btn" target="_blank" rel="noreferrer" data-i18n-key="about.bluesky" data-i18n-attrs="title" hidden>
|
||||
<svg class="icon">
|
||||
<use xlink:href="#bluesky"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" id="custom-btn" target="_blank" rel="noreferrer" data-i18n-key="about.custom" data-i18n-attrs="title" hidden>
|
||||
<svg class="icon">
|
||||
<use xlink:href="#custom"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" id="privacypolicy-btn" target="_blank" rel="noreferrer" data-i18n-key="about.privacypolicy" data-i18n-attrs="title" hidden>
|
||||
<svg class="icon">
|
||||
<use xlink:href="#privacypolicy"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="icon-button" target="_blank" href="https://github.com/schlagmichdoch/pairdrop/blob/master/docs/faq.md" rel="noreferrer" data-i18n-key="about.faq" data-i18n-attrs="title">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#help-outline"></use>
|
||||
@@ -637,7 +668,7 @@
|
||||
<path d="M18 1.01L8 1c-1.1 0-2 .9-2 2v3h2V5h10v14H8v-1H6v3c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V3c0-1.1-.9-1.99-2-1.99zM10 15h2V8H5v2h3.59L3 15.59 4.41 17 10 11.41z"></path>
|
||||
<path fill="none" d="M0 0h24v24H0V0z"></path>
|
||||
</symbol>
|
||||
<symbol id="monetarization">
|
||||
<symbol id="donation">
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1.41 16.09V20h-2.67v-1.93c-1.71-.36-3.16-1.46-3.27-3.4h1.96c.1 1.05.82 1.87 2.65 1.87 1.96 0 2.4-.98 2.4-1.59 0-.83-.44-1.61-2.67-2.14-2.48-.6-4.18-1.62-4.18-3.67 0-1.72 1.39-2.84 3.11-3.21V4h2.67v1.95c1.86.45 2.79 1.86 2.85 3.39H14.3c-.05-1.11-.64-1.87-2.22-1.87-1.5 0-2.4.68-2.4 1.64 0 .84.65 1.39 2.67 1.91s4.18 1.39 4.18 3.91c-.01 1.83-1.38 2.83-3.12 3.16z"></path>
|
||||
</symbol>
|
||||
@@ -687,15 +718,31 @@
|
||||
<path d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z"></path>
|
||||
</symbol>
|
||||
<symbol id="caret" viewBox="0 0 320 512">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M137.4 374.6c12.5 12.5 32.8 12.5 45.3 0l128-128c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8L32 192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l128 128z"></path>
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||
<path d="M137.4 374.6c12.5 12.5 32.8 12.5 45.3 0l128-128c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8L32 192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l128 128z"></path>
|
||||
</symbol>
|
||||
<symbol id="mastodon" viewBox="0 0 448 512">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||
<path d="M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54a102.5 102.5 0 0 1 -.9-13.9c85.6 20.9 158.7 9.1 178.8 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H90.2c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"></path>
|
||||
</symbol>
|
||||
<symbol id="bluesky" viewBox="0 0 448 512">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||
<path d="M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96z"></path>
|
||||
</symbol>
|
||||
<symbol id="custom" viewBox="0 0 512 512">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||
<path d="M418.4 157.9c35.3-8.3 61.6-40 61.6-77.9c0-44.2-35.8-80-80-80c-43.4 0-78.7 34.5-80 77.5L136.2 151.1C121.7 136.8 101.9 128 80 128c-44.2 0-80 35.8-80 80s35.8 80 80 80c12.2 0 23.8-2.7 34.1-7.6L259.7 407.8c-2.4 7.6-3.7 15.8-3.7 24.2c0 44.2 35.8 80 80 80s80-35.8 80-80c0-27.7-14-52.1-35.4-66.4l37.8-207.7zM156.3 232.2c2.2-6.9 3.5-14.2 3.7-21.7l183.8-73.5c3.6 3.5 7.4 6.7 11.6 9.5L317.6 354.1c-5.5 1.3-10.8 3.1-15.8 5.5L156.3 232.2z"></path>
|
||||
</symbol>
|
||||
<symbol id="privacypolicy" viewBox="0 0 512 512">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||
<path d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8V444.8C394 378 431.1 230.1 432 141.4L256 66.8l0 0z"></path>
|
||||
</symbol>
|
||||
|
||||
</svg>
|
||||
<!-- Scripts -->
|
||||
<script src="scripts/localization.js"></script>
|
||||
<script src="scripts/persistent-storage.js"></script>
|
||||
<script src="scripts/ui-main.js"></script>
|
||||
<script src="scripts/main.js"></script>
|
||||
<script src="scripts/localization.js" defer></script>
|
||||
<script src="scripts/persistent-storage.js" defer></script>
|
||||
<script src="scripts/ui-main.js" defer></script>
|
||||
<script src="scripts/main.js" defer></script>
|
||||
<!-- Sounds -->
|
||||
<audio id="blop" autobuffer="true">
|
||||
<source src="sounds/blop.mp3" type="audio/mpeg">
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
"language-selector_title": "إختر اللغة",
|
||||
"about_title": "حول PairDrop",
|
||||
"about_aria-label": "افتح حول PairDrop",
|
||||
"theme-light_title": "إستخدم دائماً المظهر الفاتح"
|
||||
"theme-light_title": "إستخدم دائماً المظهر الفاتح",
|
||||
"edit-share-mode": "ت٧ارف"
|
||||
},
|
||||
"instructions": {
|
||||
"x-instructions_mobile": "انقر لإرسال الملفات أو انقر لفترة طويلة لإرسال رسالة",
|
||||
|
||||
@@ -6,7 +6,16 @@
|
||||
"no-peers-title": "Obre PairDrop a altres dispositius per enviar arxius",
|
||||
"x-instructions_data-drop-peer": "Allibera per enviar a un company",
|
||||
"x-instructions_data-drop-bg": "Allibera per seleccionar recipient",
|
||||
"no-peers_data-drop-bg": "Allibera per seleccionar destinatari"
|
||||
"no-peers_data-drop-bg": "Allibera per seleccionar destinatari",
|
||||
"activate-share-mode-base": "Obre PairDrop a altres dispositius per enviar",
|
||||
"activate-share-mode-shared-files-plural": "{{count}} fitxers compartits",
|
||||
"x-instructions-share-mode_desktop": "Clica per enviar {{descriptor}}",
|
||||
"activate-share-mode-shared-file": "fitxer compartit",
|
||||
"activate-share-mode-and-other-file": "i 1 altre fitxer",
|
||||
"x-instructions-share-mode_mobile": "Toca per enviar {{descriptor}}",
|
||||
"activate-share-mode-and-other-files-plural": "i {{count}} fitxers més",
|
||||
"activate-share-mode-shared-text": "text compartit",
|
||||
"webrtc-requirement": "Per utilitzar aquesta instància de PairDrop cal habilitar WebRTC!"
|
||||
},
|
||||
"header": {
|
||||
"theme-auto_title": "Adapta el tema al del sistema automàticament",
|
||||
@@ -22,5 +31,149 @@
|
||||
"about_title": "Sobre PairDrop",
|
||||
"about_aria-label": "Obre Sobre PairDrop",
|
||||
"theme-light_title": "Utilitza sempre el mode clar"
|
||||
},
|
||||
"dialogs": {
|
||||
"message_placeholder": "Text",
|
||||
"base64-paste-to-send": "Enganxa el contingut del porta-retalls aquí per compartir {{type}}",
|
||||
"auto-accept-instructions-2": "per acceptar automàticament tots els fitxers enviats des d'aquell dispositiu.",
|
||||
"receive-text-title": "Missatge Rebut",
|
||||
"edit-paired-devices-title": "Edita els Dispositius Vinculats",
|
||||
"cancel": "Cancel·lar",
|
||||
"auto-accept-instructions-1": "Activar",
|
||||
"pair-devices-title": "Vincula Dispositius Permanentment",
|
||||
"download": "Descarregar",
|
||||
"title-file": "Fitxer",
|
||||
"close-toast_title": "Tanca notificació",
|
||||
"base64-processing": "Processant…",
|
||||
"decline": "Rebutjar",
|
||||
"receive-title": "{{descriptor}} Rebut",
|
||||
"share-text-checkbox": "Mostra sempre aquesta finestra de diàleg en compartir text",
|
||||
"leave": "Marxar",
|
||||
"message_title": "Introdueix el missatge a enviar",
|
||||
"join": "Unir-se",
|
||||
"title-image-plural": "Imatges",
|
||||
"send": "Enviar",
|
||||
"base64-title-files": "Compartir Fitxers",
|
||||
"base64-tap-to-paste": "Toca aquí per compartir {{type}}",
|
||||
"base64-text": "text",
|
||||
"copy": "Copiar",
|
||||
"file-other-description-image": "i 1 altra imatge",
|
||||
"pair-devices-qr-code_title": "Clica per copiar l'enllaç per vincular aquest dispositiu",
|
||||
"approve": "aprovar",
|
||||
"temporary-public-room-title": "Sala Pública Temporal",
|
||||
"base64-files": "fitxers",
|
||||
"paired-device-removed": "Dispositiu vinculat eliminat.",
|
||||
"has-sent": "ha enviat:",
|
||||
"share-text-title": "Compartir Missatge de Text",
|
||||
"file-other-description-file": "i 1 altre fitxer",
|
||||
"public-room-qr-code_title": "Clica per copiar l'enllaç a la sala pública",
|
||||
"close": "Tancar",
|
||||
"system-language": "Idioma del Sistema",
|
||||
"share-text-subtitle": "Edita el missatge abans d'enviar:",
|
||||
"unpair": "Desvincular",
|
||||
"title-image": "Imatge",
|
||||
"file-other-description-file-plural": "i {{count}} altres fitxers",
|
||||
"would-like-to-share": "voldria compartir",
|
||||
"base64-title-text": "Compartir Text",
|
||||
"send-message-to": "Per a:",
|
||||
"language-selector-title": "Establir idioma",
|
||||
"pair": "Vincular",
|
||||
"hr-or": "O",
|
||||
"scan-qr-code": "o escaneja el codi QR.",
|
||||
"input-key-on-this-device": "Introdueix aquesta clau a un altre dispositiu",
|
||||
"download-again": "Descarregar de nou",
|
||||
"accept": "Acceptar",
|
||||
"paired-devices-wrapper_data-empty": "No hi ha dispositius vinculats.",
|
||||
"enter-key-from-another-device": "Introdueix la clau d'un altre dispositiu aquí.",
|
||||
"share": "Compartir",
|
||||
"auto-accept": "auto-acceptar",
|
||||
"title-file-plural": "Fitxers",
|
||||
"send-message-title": "Enviar Missatge",
|
||||
"input-room-id-on-another-device": "Introdueix aquest ID de sala a un altre dispositiu",
|
||||
"file-other-description-image-plural": "i {{count}} altres imatges",
|
||||
"enter-room-id-from-another-device": "Introdueix l'ID de sala d'un altre dispositiu per unir-t'hi."
|
||||
},
|
||||
"footer": {
|
||||
"webrtc": "si WebRTC no està disponible.",
|
||||
"public-room-devices_title": "Pots ser descobert per dispositius en aquesta sala pública independentment de la xarxa.",
|
||||
"display-name_data-placeholder": "Carregant…",
|
||||
"display-name_title": "Edita el nom del teu dispositiu permanentment",
|
||||
"traffic": "El trànsit és",
|
||||
"paired-devices_title": "Pots ser descobert per dispositius emparellats en qualsevol moment, independentment de la xarxa.",
|
||||
"public-room-devices": "a la sala {{roomId}}",
|
||||
"paired-devices": "per dispositius vinculats",
|
||||
"on-this-network": "En aquesta xarxa",
|
||||
"routed": "encaminat a través del servidor",
|
||||
"discovery": "Pots ser descobert:",
|
||||
"on-this-network_title": "Pots ser descobert per qualsevol usuari en aquesta xarxa.",
|
||||
"known-as": "Ets conegut com a:"
|
||||
},
|
||||
"notifications": {
|
||||
"request-title": "{{name}} voldria transferir {{count}} {{descriptor}}",
|
||||
"unfinished-transfers-warning": "Hi ha transferències pendents. Estàs segur que vols tancar PairDrop?",
|
||||
"message-received": "Missatge rebut per {{name}} - Fes clic per copiar",
|
||||
"notifications-permissions-error": "El permís per notificacions ha estat bloquejat, ja que l'usuari ha refusat la sol·licitud diverses vegades. Això es pot restablir a Informació de Pàgina, a on es pot accedir clicant la icona amb el cadenat que hi ha al costat de la barra de l'URL.",
|
||||
"rate-limit-join-key": "S'ha arribat al límit de ràtio. Espera 10 segons i torna-ho a intentar.",
|
||||
"pair-url-copied-to-clipboard": "Enllaç per vincular aquest dispositiu copiat al porta-retalls",
|
||||
"connecting": "Connectant…",
|
||||
"pairing-key-invalidated": "Clau {{key}} invalidada",
|
||||
"pairing-key-invalid": "Clau no vàlida",
|
||||
"connected": "Connectat",
|
||||
"pairing-not-persistent": "Els dispositius vinculats no són persistents",
|
||||
"text-content-incorrect": "El contingut del text és incorrecte",
|
||||
"message-transfer-completed": "Transferència de missatge completada",
|
||||
"file-transfer-completed": "Transferència de fitxers completada",
|
||||
"file-content-incorrect": "El contingut del fitxer és incorrecte",
|
||||
"files-incorrect": "Els fitxers són incorrectes",
|
||||
"selected-peer-left": "L'usuari seleccionat ha marxat",
|
||||
"link-received": "Enllaç rebut per {{name}} - Fes clic per obrir",
|
||||
"online": "Tornes a estar en línia",
|
||||
"public-room-left": "Has sortit de la sala pública {{publicRoomId}}",
|
||||
"copied-text": "Text copiat al porta-retalls",
|
||||
"display-name-random-again": "El nom d'usuari ha estat generat novament generat aleatòriament",
|
||||
"display-name-changed-permanently": "El nom d'usuari està canviat permanentment",
|
||||
"copied-to-clipboard-error": "Còpia impossible. Copiar manualment.",
|
||||
"pairing-success": "Dispositius vinculats",
|
||||
"clipboard-content-incorrect": "El contingut del porta-retalls és incorrecte",
|
||||
"display-name-changed-temporarily": "El nom d'usuari està canviat només per aquesta sessió",
|
||||
"copied-to-clipboard": "Copiat al porta-retalls",
|
||||
"offline": "No estàs en línia",
|
||||
"pairing-tabs-error": "No es poden vincular dues pestanyes d'un navegador",
|
||||
"public-room-id-invalid": "ID de sala no vàlid",
|
||||
"click-to-download": "Clica per descarregar",
|
||||
"pairing-cleared": "Tots els dispositius desvinculats",
|
||||
"notifications-enabled": "Notificacions habilitades",
|
||||
"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",
|
||||
"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!",
|
||||
"download-successful": "{{descriptor}} descarregat",
|
||||
"click-to-show": "Clica per mostrar"
|
||||
},
|
||||
"peer-ui": {
|
||||
"processing": "Processant…",
|
||||
"click-to-send-share-mode": "Clica per enviar {{descriptor}}",
|
||||
"click-to-send": "Fes clic per enviar fitxers o fes clic dret per enviar un missatge",
|
||||
"waiting": "Esperant…",
|
||||
"connection-hash": "Per verificar la seguretat del xifratge de punta a punta, compara aquest número de seguretat en ambdós dispositius",
|
||||
"preparing": "Preparant…",
|
||||
"transferring": "Transferint…"
|
||||
},
|
||||
"about": {
|
||||
"claim": "La manera més fàcil de compartir fitxers entre dispositius",
|
||||
"tweet_title": "Tuiteja sobre PairDrop",
|
||||
"close-about_aria-label": "Tanca Sobre PairDrop",
|
||||
"buy-me-a-coffee_title": "Convida'm a un cafè!",
|
||||
"github_title": "PairDrop a GitHub",
|
||||
"faq_title": "Preguntes freqüents"
|
||||
},
|
||||
"document-titles": {
|
||||
"file-transfer-requested": "Transferència de Fitxers Sol·licitada",
|
||||
"image-transfer-requested": "Transferència d'Imatges Sol·licitada",
|
||||
"message-received-plural": "{{count}} Missatges Rebuts",
|
||||
"message-received": "Missatge Rebut",
|
||||
"file-received": "Fitxer Rebut",
|
||||
"file-received-plural": "{{count}} Fitxers Rebuts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"cancel-share-mode": "Fertig",
|
||||
"language-selector_title": "Sprache Wählen",
|
||||
"join-public-room_title": "Öffentlichen Raum temporär betreten",
|
||||
"edit-share-mode": "Bearbeiten"
|
||||
"edit-share-mode": "Bearbeiten",
|
||||
"expand_title": "Schaltflächenzeile ausklappen"
|
||||
},
|
||||
"dialogs": {
|
||||
"share": "Teilen",
|
||||
@@ -81,7 +82,11 @@
|
||||
"close-about_aria-label": "Schließe Über PairDrop",
|
||||
"github_title": "PairDrop auf GitHub",
|
||||
"buy-me-a-coffee_title": "Kauf mir einen Kaffee!",
|
||||
"claim": "Der einfachste Weg, Dateien zwischen Geräten zu übertragen"
|
||||
"claim": "Der einfachste Weg, Dateien zwischen Geräten zu übertragen",
|
||||
"bluesky_title": "Folge uns auf BlueSky",
|
||||
"privacypolicy_title": "Öffne unsere Datenschutzerklärung",
|
||||
"mastodon_title": "Schreibe über PairDrop auf Mastodon",
|
||||
"custom_title": "Folge uns"
|
||||
},
|
||||
"footer": {
|
||||
"known-as": "Du wirst angezeigt als:",
|
||||
@@ -147,7 +152,7 @@
|
||||
"x-instructions_desktop": "Klicke, um Dateien zu senden oder benutze einen Rechtsklick, um eine Nachricht zu senden",
|
||||
"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-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_mobile": "Tippe zum Senden von {{descriptor}}",
|
||||
"x-instructions_data-drop-peer": "Hier ablegen, um an Peer zu senden",
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"edit-paired-devices_title": "Edit paired devices",
|
||||
"join-public-room_title": "Join public room temporarily",
|
||||
"cancel-share-mode": "Cancel",
|
||||
"edit-share-mode": "Edit"
|
||||
"edit-share-mode": "Edit",
|
||||
"expand_title": "Expand header button row"
|
||||
},
|
||||
"instructions": {
|
||||
"no-peers_data-drop-bg": "Release to select recipient",
|
||||
@@ -114,6 +115,10 @@
|
||||
"github_title": "PairDrop on GitHub",
|
||||
"buy-me-a-coffee_title": "Buy me a coffee!",
|
||||
"tweet_title": "Tweet about PairDrop",
|
||||
"mastodon_title": "Write about PairDrop on Mastodon",
|
||||
"bluesky_title": "Follow us on BlueSky",
|
||||
"custom_title": "Follow us",
|
||||
"privacypolicy_title": "Open our privacy policy",
|
||||
"faq_title": "Frequently asked questions"
|
||||
},
|
||||
"notifications": {
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"join-public-room_title": "Unirse a una sala pública temporalmente",
|
||||
"notification_title": "Activar notificaciones",
|
||||
"edit-paired-devices_title": "Editar dispositivos emparejados",
|
||||
"theme-light_title": "Siempre usar tema claro"
|
||||
"theme-light_title": "Siempre usar tema claro",
|
||||
"expand_title": "Ampliar la fila de botones de la cabecera",
|
||||
"edit-share-mode": "Editar"
|
||||
},
|
||||
"footer": {
|
||||
"webrtc": "si WebRTC no está disponible.",
|
||||
@@ -73,9 +75,9 @@
|
||||
},
|
||||
"instructions": {
|
||||
"x-instructions_mobile": "Toque para enviar archivos o toque prologádamente para enviar un mensaje",
|
||||
"x-instructions-share-mode_desktop": "Haga clic para enviar",
|
||||
"x-instructions-share-mode_desktop": "Haga clic para enviar {{descriptor}}",
|
||||
"activate-share-mode-and-other-files-plural": "y {{count}} archivos diferentes",
|
||||
"x-instructions-share-mode_mobile": "Toca para enviar",
|
||||
"x-instructions-share-mode_mobile": "Toque para enviar {{descriptor}}",
|
||||
"activate-share-mode-base": "Abra PairDrop en otros dispositivos para enviar",
|
||||
"no-peers-subtitle": "Empareje dispositivos o ingrese a una sala pública para que lo puedan encontrar en otras redes",
|
||||
"activate-share-mode-shared-text": "texto compartido",
|
||||
@@ -84,7 +86,10 @@
|
||||
"x-instructions_data-drop-peer": "Liberar para enviar a un par",
|
||||
"x-instructions_data-drop-bg": "Liberar para seleccionar destinatario",
|
||||
"no-peers_data-drop-bg": "Liberar para seleccionar destinatario",
|
||||
"webrtc-requirement": "Para utilizar esta instancia de PairDrop, ¡WebRTC debe estar activado!"
|
||||
"webrtc-requirement": "Para utilizar esta instancia de PairDrop, ¡WebRTC debe estar activado!",
|
||||
"activate-share-mode-shared-files-plural": "{{count}} archivos compartidos",
|
||||
"activate-share-mode-shared-file": "archivo compartido",
|
||||
"activate-share-mode-and-other-file": "y 1 archivo más"
|
||||
},
|
||||
"peer-ui": {
|
||||
"processing": "Procesando…",
|
||||
@@ -96,7 +101,7 @@
|
||||
"transferring": "Transferiendo…"
|
||||
},
|
||||
"dialogs": {
|
||||
"base64-paste-to-send": "Pegar aquí para enviar {{type}}",
|
||||
"base64-paste-to-send": "Pegar el portapapeles aquí para compartir {{type}}",
|
||||
"auto-accept-instructions-2": "para aceptar automáticamente todos los archivos enviados desde ese dispositivo.",
|
||||
"receive-text-title": "Mensaje Recibido",
|
||||
"edit-paired-devices-title": "Editar Dispositivos Emparejados",
|
||||
@@ -112,7 +117,7 @@
|
||||
"join": "Unirse",
|
||||
"title-image-plural": "Imágenes",
|
||||
"send": "Enviar",
|
||||
"base64-tap-to-paste": "Toca aquí para pegar {{type}}",
|
||||
"base64-tap-to-paste": "Pulse aquí para compartir {{type}}",
|
||||
"base64-text": "texto",
|
||||
"copy": "Copiar",
|
||||
"file-other-description-image": "y una imagen mas",
|
||||
@@ -146,7 +151,15 @@
|
||||
"message_title": "Insertar el mensaje a enviar",
|
||||
"pair-devices-qr-code_title": "Haz clic para copiar el enlace para emparejar este dispositivo",
|
||||
"public-room-qr-code_title": "Haz clic para copiar el enlace a la sala pública",
|
||||
"message_placeholder": "Texto"
|
||||
"message_placeholder": "Texto",
|
||||
"close-toast_title": "Cerrar la notificación",
|
||||
"share-text-checkbox": "Mostrar siempre este cuadro de diálogo al compartir texto",
|
||||
"base64-title-files": "Compartir archivos",
|
||||
"approve": "aprobar",
|
||||
"paired-device-removed": "Se ha eliminado el dispositivo emparejado.",
|
||||
"share-text-title": "Compartir un mensaje de texto",
|
||||
"share-text-subtitle": "Edita el mensaje antes de enviarlo:",
|
||||
"base64-title-text": "Compartir el texto"
|
||||
},
|
||||
"about": {
|
||||
"claim": "La forma más sencilla de transferir archivos entre dispositivos",
|
||||
@@ -154,7 +167,11 @@
|
||||
"close-about_aria-label": "Cerrar Sobre PairDrop",
|
||||
"buy-me-a-coffee_title": "¡Cómprame un café!",
|
||||
"github_title": "PairDrop en GitHub",
|
||||
"faq_title": "Preguntas frecuentes"
|
||||
"faq_title": "Preguntas frecuentes",
|
||||
"bluesky_title": "Síganos en BlueSky",
|
||||
"privacypolicy_title": "Abrir nuestra política de privacidad",
|
||||
"mastodon_title": "Escriba sobre PairDrop en Mastodon",
|
||||
"custom_title": "Síguenos en"
|
||||
},
|
||||
"document-titles": {
|
||||
"file-transfer-requested": "Transferencia de archivos solicitada",
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"room-url-copied-to-clipboard": "Tautan ke ruang publik disalin ke papan klip"
|
||||
},
|
||||
"header": {
|
||||
"cancel-share-mode": "Selesai",
|
||||
"cancel-share-mode": "Batalkan",
|
||||
"theme-auto_title": "Sesuaikan tema dengan sistem",
|
||||
"install_title": "Instal PairDrop",
|
||||
"theme-dark_title": "Selalu gunakan tema gelap",
|
||||
@@ -69,7 +69,9 @@
|
||||
"language-selector_title": "Atur Bahasa",
|
||||
"about_title": "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": {
|
||||
"x-instructions_mobile": "Ketuk untuk mengirim file atau ketuk lama untuk mengirim pesan",
|
||||
@@ -83,7 +85,11 @@
|
||||
"no-peers-title": "Buka PairDrop di perangkat lain untuk berkirim file",
|
||||
"x-instructions_data-drop-peer": "Lepaskan untuk mengirim ke rekan",
|
||||
"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": {
|
||||
"processing": "Memproses…",
|
||||
@@ -111,7 +117,7 @@
|
||||
"join": "Gabung",
|
||||
"title-image-plural": "Gambar",
|
||||
"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",
|
||||
"copy": "Salin",
|
||||
"file-other-description-image": "dan 1 gambar lainnya",
|
||||
@@ -125,7 +131,7 @@
|
||||
"title-image": "Gambar",
|
||||
"file-other-description-file-plural": "dan {{count}} file lainnya",
|
||||
"would-like-to-share": "ingin berbagi",
|
||||
"send-message-to": "Kirim pesan ke",
|
||||
"send-message-to": "Ke:",
|
||||
"language-selector-title": "Pilih Bahasa",
|
||||
"pair": "Pasangkan",
|
||||
"hr-or": "ATAU",
|
||||
@@ -144,7 +150,11 @@
|
||||
"enter-room-id-from-another-device": "Masukkan room ID dari perangkat lain untuk bergabung dengan room.",
|
||||
"message_title": "Masukkan pesan untuk dikirim",
|
||||
"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": {
|
||||
"claim": "Cara termudah untuk mentransfer file lintas perangkat",
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"display-name_data-placeholder": "Caricamento…",
|
||||
"display-name_title": "Modifica il nome del tuo dispositivo permanentemente",
|
||||
"traffic": "Il traffico è",
|
||||
"paired-devices_title": "Puoi essere rilevato dai dispositivi abbinati in ogni momento, indipendentemente dalla rete.",
|
||||
"paired-devices_title": "Puoi essere rilevato dai dispositivi associati in ogni momento, indipendentemente dalla rete.",
|
||||
"public-room-devices": "nella stanza {{roomId}}",
|
||||
"paired-devices": "da dispositivi abbinati",
|
||||
"paired-devices": "da dispositivi associati",
|
||||
"on-this-network": "su questa rete",
|
||||
"routed": "instradato attraverso il server",
|
||||
"discovery": "Puoi essere rilevato:",
|
||||
@@ -15,7 +15,7 @@
|
||||
"known-as": "Sei visibile come:"
|
||||
},
|
||||
"header": {
|
||||
"cancel-share-mode": "Fatto",
|
||||
"cancel-share-mode": "Annulla",
|
||||
"theme-auto_title": "Adatta il tema al sistema automaticamente",
|
||||
"install_title": "Installa PairDrop",
|
||||
"theme-dark_title": "Usa sempre il tema scuro",
|
||||
@@ -26,13 +26,15 @@
|
||||
"language-selector_title": "Imposta Lingua",
|
||||
"about_title": "Informazioni su PairDrop",
|
||||
"about_aria-label": "Apri Informazioni su PairDrop",
|
||||
"theme-light_title": "Usa sempre il tema chiaro"
|
||||
"theme-light_title": "Usa sempre il tema chiaro",
|
||||
"edit-share-mode": "Modifica",
|
||||
"expand_title": "Espandi la riga dei pulsanti nell'intestazione"
|
||||
},
|
||||
"instructions": {
|
||||
"x-instructions_mobile": "Tocca per inviare file o tocco prolungato per inviare un messaggio",
|
||||
"x-instructions-share-mode_desktop": "Clicca per inviare",
|
||||
"x-instructions-share-mode_desktop": "Clicca per inviare {{descriptor}}",
|
||||
"activate-share-mode-and-other-files-plural": "e altri {{count}} files",
|
||||
"x-instructions-share-mode_mobile": "Tocca per inviare",
|
||||
"x-instructions-share-mode_mobile": "Tocca per inviare {{descriptor}}",
|
||||
"activate-share-mode-base": "Apri PairDrop su altri dispositivi per inviare",
|
||||
"no-peers-subtitle": "Abbina dispositivi o entra in una stanza pubblica per essere rilevabile su altre reti",
|
||||
"activate-share-mode-shared-text": "testo condiviso",
|
||||
@@ -40,23 +42,27 @@
|
||||
"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-bg": "Rilascia per selezionare il destinatario",
|
||||
"no-peers_data-drop-bg": "Rilascia per selezionare il destinatario"
|
||||
"no-peers_data-drop-bg": "Rilascia per selezionare il destinatario",
|
||||
"webrtc-requirement": "Per usare questa istanza di PairDrop, devi attivare WebRTC!",
|
||||
"activate-share-mode-shared-file": "file condiviso",
|
||||
"activate-share-mode-shared-files-plural": "{{count}} files condivisi",
|
||||
"activate-share-mode-and-other-file": "ed 1 altro file"
|
||||
},
|
||||
"dialogs": {
|
||||
"auto-accept-instructions-2": "per accettare automaticamente tutti i files inviati da quel dispositivo.",
|
||||
"edit-paired-devices-title": "Modifica Dispositivi Abbinati",
|
||||
"edit-paired-devices-title": "Modifica Dispositivi Associati",
|
||||
"cancel": "Annulla",
|
||||
"auto-accept-instructions-1": "Attiva",
|
||||
"pair-devices-title": "Abbina Dispositivi Permanentemente",
|
||||
"pair-devices-title": "Associa Dispositivi Permanentemente",
|
||||
"temporary-public-room-title": "Stanza Pubblica Temporanea",
|
||||
"close": "Chiudi",
|
||||
"unpair": "Dissocia",
|
||||
"pair": "Abbina",
|
||||
"pair": "Associa",
|
||||
"scan-qr-code": "o scannerizza il codice QR.",
|
||||
"input-key-on-this-device": "Inserisci questo codice su un altro dispositivo",
|
||||
"paired-devices-wrapper_data-empty": "Nessun dispositivo abbinato.",
|
||||
"paired-devices-wrapper_data-empty": "Nessun dispositivo associato.",
|
||||
"enter-key-from-another-device": "Inserisci il codice dell'altro dispositivo qui.",
|
||||
"auto-accept": "accetta-automaticamente",
|
||||
"auto-accept": "accetta automaticamente",
|
||||
"input-room-id-on-another-device": "Inserisci l'ID di questa stanza su un altro dispositivo",
|
||||
"enter-room-id-from-another-device": "Inserisci l'ID stanza da un altro dispositivo per accedere alla stanza.",
|
||||
"base64-paste-to-send": "Incolla qui per inviare {{type}}",
|
||||
@@ -70,7 +76,7 @@
|
||||
"join": "Unisciti",
|
||||
"title-image-plural": "Immagini",
|
||||
"send": "Invia",
|
||||
"base64-tap-to-paste": "Tocca qui per incollare {{type}}",
|
||||
"base64-tap-to-paste": "Tocca qui per condividere {{type}}",
|
||||
"base64-text": "testo",
|
||||
"copy": "Copia",
|
||||
"file-other-description-image": "e 1 altra immagine",
|
||||
@@ -81,7 +87,7 @@
|
||||
"title-image": "Immagine",
|
||||
"file-other-description-file-plural": "e altri {{count}} files",
|
||||
"would-like-to-share": "vorrebbe condividere",
|
||||
"send-message-to": "Invia un messaggio a",
|
||||
"send-message-to": "A:",
|
||||
"language-selector-title": "Imposta Lingua",
|
||||
"hr-or": "OPPURE",
|
||||
"download-again": "Scarica ancora",
|
||||
@@ -91,11 +97,20 @@
|
||||
"send-message-title": "Invia Messaggio",
|
||||
"file-other-description-image-plural": "e {{count}} altre immagini",
|
||||
"message_title": "Inserire messaggio da inviare",
|
||||
"pair-devices-qr-code_title": "Clicca per copiare il link di abbinamento di questo dispositivo",
|
||||
"public-room-qr-code_title": "Clicca per copirare il link della stanza pubblica"
|
||||
"pair-devices-qr-code_title": "Clicca per copiare il link di associazione a questo dispositivo",
|
||||
"public-room-qr-code_title": "Clicca per copirare il link della stanza pubblica",
|
||||
"message_placeholder": "Testo",
|
||||
"paired-device-removed": "Il dispositivo associato è stato rimosso.",
|
||||
"base64-title-files": "Condividi Files",
|
||||
"base64-title-text": "Condividi Testo",
|
||||
"share-text-subtitle": "Modifica messaggio prima dell'invio:",
|
||||
"share-text-checkbox": "Mostra sempre questa casella di dialogo quando si condivide del testo",
|
||||
"approve": "accetta",
|
||||
"share-text-title": "Condividi Messaggio di Testo",
|
||||
"close-toast_title": "Chiudi notifica"
|
||||
},
|
||||
"notifications": {
|
||||
"request-title": "{{name}} vorrebbe trasferire {{count}} {{descriptor}}",
|
||||
"request-title": "{{name}} vorrebbe inviare {{count}} {{descriptor}}",
|
||||
"unfinished-transfers-warning": "Ci sono dei trasferimenti in corso. Sei sicuro di voler chiudere PairDrop?",
|
||||
"message-received": "Messaggio ricevuto da {{name}} - Clicca per copiare",
|
||||
"rate-limit-join-key": "Limite raggiunto. Aspetta 10 secondi e riprova.",
|
||||
@@ -103,22 +118,22 @@
|
||||
"pairing-key-invalidated": "Il codice {{key}} è stato invalidato",
|
||||
"pairing-key-invalid": "Codice non valido",
|
||||
"connected": "Connesso",
|
||||
"pairing-not-persistent": "I dispositivi abbinati non sono persistenti",
|
||||
"text-content-incorrect": "Il contenuto testuale non è corretto",
|
||||
"pairing-not-persistent": "I dispositivi associati non sono permanenti",
|
||||
"text-content-incorrect": "Il contenuto di testo è errato",
|
||||
"message-transfer-completed": "Trasferimento del messaggio completato",
|
||||
"file-transfer-completed": "Trasferimento file completato",
|
||||
"file-content-incorrect": "Il contenuto del file non è corretto",
|
||||
"files-incorrect": "I file non sono corretti",
|
||||
"selected-peer-left": "Peer selezionato ha abbandonato",
|
||||
"file-content-incorrect": "Il contenuto del file è errato",
|
||||
"files-incorrect": "I file sono errati",
|
||||
"selected-peer-left": "Il peer selezionato ha abbandonato",
|
||||
"link-received": "Link ricevuto da {{name}} - Clicca per aprire",
|
||||
"online": "Sei di nuovo online",
|
||||
"public-room-left": "Ha lasciato la stanza pubblica {{publicRoomId}}",
|
||||
"public-room-left": "Hai abbandonato la stanza pubblica {{publicRoomId}}",
|
||||
"copied-text": "Testo copiato negli appunti",
|
||||
"display-name-random-again": "Il nome visualizzato è generato casualmente un'altra volta",
|
||||
"display-name-changed-permanently": "Il nome visualizzato è cambiato permanentemente",
|
||||
"copied-to-clipboard-error": "La copia non è possibile. Copia manualmente.",
|
||||
"pairing-success": "Dispositivi abbinati",
|
||||
"clipboard-content-incorrect": "Il contenuto copiato non è corretto",
|
||||
"display-name-random-again": "Il nome visualizzato viene di nuovo generato casualmente",
|
||||
"display-name-changed-permanently": "Il nome visualizzato è cambiato definitivamente",
|
||||
"copied-to-clipboard-error": "La funzione di copia non è possibile. Copia manualmente.",
|
||||
"pairing-success": "Dispositivi associati",
|
||||
"clipboard-content-incorrect": "Il contenuto copiato è errato",
|
||||
"display-name-changed-temporarily": "Il nome visualizzato è cambiato solo per questa sessione",
|
||||
"copied-to-clipboard": "Copiato negli appunti",
|
||||
"offline": "Sei offline",
|
||||
@@ -127,14 +142,14 @@
|
||||
"click-to-download": "Clicca per scaricare",
|
||||
"pairing-cleared": "Tutti i dispositivi sono stati dissociati",
|
||||
"notifications-enabled": "Notifiche attivate",
|
||||
"online-requirement-pairing": "Devi essere online per abbinare dispositivi",
|
||||
"online-requirement-pairing": "Devi essere online per associare dispositivi",
|
||||
"ios-memory-limit": "L'invio di file a dispositivi iOS è possibile solo 200 MB alla volta",
|
||||
"online-requirement-public-room": "Devi essere online per creare una stanza pubblica",
|
||||
"copied-text-error": "Scrittura negli appunti fallita. Copia manualmente!",
|
||||
"download-successful": "{{descriptor}} scaricato",
|
||||
"click-to-show": "Clicca per mostrare",
|
||||
"notifications-permissions-error": "Il permesso all'invio delle notifiche è stato negato poiché l'utente ha ignorato varie volte le richieste di permesso. Ciò può essere ripristinato nelle \"informazioni sito\" cliccando sull'icona a forma di lucchetto vicino alla barra degli indirizzi.",
|
||||
"pair-url-copied-to-clipboard": "Link di abbinamento copiato negli appunti",
|
||||
"pair-url-copied-to-clipboard": "Link di associazione copiato negli appunti",
|
||||
"room-url-copied-to-clipboard": "Link della stanza copiato negli appunti"
|
||||
},
|
||||
"peer-ui": {
|
||||
@@ -150,14 +165,18 @@
|
||||
"claim": "Il modo più semplice per trasferire files tra dispositivi",
|
||||
"tweet_title": "Twitta riguardo PairDrop",
|
||||
"close-about_aria-label": "Chiudi Informazioni su PairDrop",
|
||||
"buy-me-a-coffee_title": "Comprami un caffè!",
|
||||
"buy-me-a-coffee_title": "Offrimi un caffè!",
|
||||
"github_title": "PairDrop su GitHub",
|
||||
"faq_title": "Domande Frequenti"
|
||||
"faq_title": "Domande Frequenti",
|
||||
"mastodon_title": "Scrivi su Mastodon di PairDrop",
|
||||
"bluesky_title": "Seguici su BlueSky",
|
||||
"custom_title": "Seguici",
|
||||
"privacypolicy_title": "Apri la nostra policy sulla privacy"
|
||||
},
|
||||
"document-titles": {
|
||||
"file-transfer-requested": "Trasferimento File Richiesto",
|
||||
"image-transfer-requested": "Trasferimento Immagine Richiesto",
|
||||
"message-received-plural": "{{count}} Messaggi ricevuti",
|
||||
"message-received-plural": "{{count}} Messaggi Ricevuti",
|
||||
"message-received": "Messaggio ricevuto",
|
||||
"file-received": "File Ricevuto",
|
||||
"file-received-plural": "{{count}} Files Ricevuti"
|
||||
|
||||
@@ -69,7 +69,9 @@
|
||||
"language-selector_title": "言語を設定",
|
||||
"about_title": "PairDropについて",
|
||||
"about_aria-label": "PairDropについてを開く",
|
||||
"theme-light_title": "常にライトテーマを使用する"
|
||||
"theme-light_title": "常にライトテーマを使用する",
|
||||
"edit-share-mode": "編集",
|
||||
"expand_title": "ヘッダーボタン列を拡大する"
|
||||
},
|
||||
"instructions": {
|
||||
"x-instructions_mobile": "タップしてファイルを送信または長押ししてメッセージを送信します",
|
||||
@@ -83,7 +85,11 @@
|
||||
"no-peers-title": "他のデバイスでPairDropを開いてファイルを送信します",
|
||||
"x-instructions_data-drop-peer": "離すとこの相手に送信します",
|
||||
"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": {
|
||||
"processing": "処理中…",
|
||||
@@ -144,7 +150,16 @@
|
||||
"enter-room-id-from-another-device": "他のデバイスに表示された参加したいルームのIDを入力します。",
|
||||
"message_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": {
|
||||
"claim": "デバイス間でファイルを転送する最も簡単な方法",
|
||||
@@ -152,7 +167,11 @@
|
||||
"close-about_aria-label": "PairDropについてを閉じる",
|
||||
"buy-me-a-coffee_title": "コーヒーをおごってください!",
|
||||
"github_title": "GitHubでPairDropを見る",
|
||||
"faq_title": "FAQ"
|
||||
"faq_title": "FAQ",
|
||||
"mastodon_title": "MastodonにPairDropについて書く",
|
||||
"bluesky_title": "BlueSkyでフォロー",
|
||||
"custom_title": "フォロー",
|
||||
"privacypolicy_title": "プライバシーポリシーを開く"
|
||||
},
|
||||
"document-titles": {
|
||||
"file-transfer-requested": "ファイルの転送がリクエストされました",
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
"edit-paired-devices_title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ",
|
||||
"language-selector_title": "ಭಾಷೆಯನ್ನು ಆಯ್ಕೆ ಮಾಡಿ",
|
||||
"about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ತೆರೆಯಿರಿ",
|
||||
"theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ"
|
||||
"theme-light_title": "ಯಾವಾಗಲೂ ಲೈಟ್ ಥೀಮ್ ಅನ್ನು ಬಳಸಿ",
|
||||
"edit-share-mode": "ಎಡಿಟ್ ಮಾಡಿ",
|
||||
"cancel-share-mode": "ರದ್ದುಗೊಳಿಸಿ",
|
||||
"expand_title": "ಹೆಡರ್ ಬಟನ್ ಸಾಲನ್ನು ವಿಸ್ತರಿಸಿ"
|
||||
},
|
||||
"dialogs": {
|
||||
"message_placeholder": "ಪಠ್ಯ",
|
||||
"base64-paste-to-send": "{{type}} ಕಳುಹಿಸಲು ಇಲ್ಲಿ ಅಂಟಿಸಿ",
|
||||
"base64-paste-to-send": "{{type}} ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಕ್ಲಿಪ್ಬೋರ್ಡ್ ಅನ್ನು ಇಲ್ಲಿ ಅಂಟಿಸಿ",
|
||||
"auto-accept-instructions-2": "ಆ ಸಾಧನದಿಂದ ಕಳುಹಿಸಲಾದ ಎಲ್ಲಾ ಫೈಲ್ಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸ್ವೀಕರಿಸಲು.",
|
||||
"receive-text-title": "ಸಂದೇಶವನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ",
|
||||
"edit-paired-devices-title": "ಜೋಡಿಯಾಗಿರುವ ಸಾಧನಗಳನ್ನು ಎಡಿಟ್ ಮಾಡಿ",
|
||||
@@ -32,7 +35,7 @@
|
||||
"join": "ಸೇರಿಕೊಳ್ಳಿ",
|
||||
"title-image-plural": "ಚಿತ್ರಗಳು",
|
||||
"send": "ಕಳುಹಿಸಿ",
|
||||
"base64-tap-to-paste": "{{type}} ಅಂಟಿಸಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ",
|
||||
"base64-tap-to-paste": "{{type}} ಹಂಚಿಕೊಳ್ಳಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ",
|
||||
"base64-text": "ಪಠ್ಯ",
|
||||
"copy": "ನಕಲು ಮಾಡಿ",
|
||||
"file-other-description-image": "ಮತ್ತು ಇನ್ನೊಂದು ಚಿತ್ರ",
|
||||
@@ -64,7 +67,15 @@
|
||||
"send-message-title": "ಸಂದೇಶ ಕಳುಹಿಸಿ",
|
||||
"input-room-id-on-another-device": "ಇನ್ನೊಂದು ಸಾಧನದಲ್ಲಿ ಈ ರೂಮ್ ಐಡಿಯನ್ನು ನಮೂದಿಸಿ",
|
||||
"file-other-description-image-plural": "ಮತ್ತು {{count}} ಇತರ ಚಿತ್ರಗಳು",
|
||||
"enter-room-id-from-another-device": "ಕೊಠಡಿ ಸೇರಲು ಇನ್ನೊಂದು ಸಾಧನದಿಂದ ರೂಮ್ ಐಡಿ ನಮೂದಿಸಿ."
|
||||
"enter-room-id-from-another-device": "ಕೊಠಡಿ ಸೇರಲು ಇನ್ನೊಂದು ಸಾಧನದಿಂದ ರೂಮ್ ಐಡಿ ನಮೂದಿಸಿ.",
|
||||
"close-toast_title": "ಅಧಿಸೂಚನೆಯನ್ನು ಮುಚ್ಚಿರಿ",
|
||||
"share-text-checkbox": "ಪಠ್ಯವನ್ನು ಹಂಚಿಕೊಳ್ಳುವಾಗ ಯಾವಾಗಲೂ ಈ ಡೈಲಾಗ್ ಅನ್ನು ತೋರಿಸಿ",
|
||||
"base64-title-files": "ಫೈಲ್ಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ",
|
||||
"approve": "ಅನುಮೋದಿಸಿ",
|
||||
"paired-device-removed": "ಜೋಡಿಸಲಾದ ಸಾಧನವನ್ನು ತೆಗೆದುಹಾಕಲಾಗಿದೆ.",
|
||||
"share-text-title": "ಪಠ್ಯ ಸಂದೇಶವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ",
|
||||
"share-text-subtitle": "ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವ ಮೊದಲು ಎಡಿಟ್ ಮಾಡಿ:",
|
||||
"base64-title-text": "ಪಠ್ಯವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ"
|
||||
},
|
||||
"footer": {
|
||||
"webrtc": "WebRTC ಲಭ್ಯವಿಲ್ಲದಿದ್ದರೆ.",
|
||||
@@ -137,7 +148,15 @@
|
||||
"x-instructions_data-drop-peer": "ಪೀರ್ಗೆ ಕಳುಹಿಸಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
|
||||
"x-instructions_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
|
||||
"no-peers_data-drop-bg": "ಸ್ವೀಕರಿಸುವವರನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬಿಡುಗಡೆ ಮಾಡಿ",
|
||||
"webrtc-requirement": "ಈ PairDrop ನಿದರ್ಶನವನ್ನು ಬಳಸಲು, WebRTC ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು!"
|
||||
"webrtc-requirement": "ಈ PairDrop ನಿದರ್ಶನವನ್ನು ಬಳಸಲು, WebRTC ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು!",
|
||||
"activate-share-mode-base": "ಕಳುಹಿಸಲು ಇತರ ಸಾಧನಗಳಲ್ಲಿ PairDrop ತೆರೆಯಿರಿ",
|
||||
"activate-share-mode-shared-files-plural": "{{count}} ಹಂಚಿದ ಫೈಲ್ಗಳು",
|
||||
"x-instructions-share-mode_desktop": "{{descriptor}} ಕಳುಹಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ",
|
||||
"activate-share-mode-shared-file": "ಹಂಚಿದ ಫೈಲ್",
|
||||
"activate-share-mode-and-other-file": "ಮತ್ತು ಇತರ 1 ಫೈಲ್",
|
||||
"x-instructions-share-mode_mobile": "{{descriptor}} ಕಳುಹಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ",
|
||||
"activate-share-mode-and-other-files-plural": "ಮತ್ತು ಇತರ {{count}} ಫೈಲ್ಗಳು",
|
||||
"activate-share-mode-shared-text": "ಹಂಚಿದ ಪಠ್ಯ"
|
||||
},
|
||||
"peer-ui": {
|
||||
"processing": "ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲಾಗುತ್ತಿದೆ…",
|
||||
@@ -146,7 +165,8 @@
|
||||
"waiting": "ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ…",
|
||||
"connection-hash": "ಎಂಡ್-ಟು-ಎಂಡ್ ಎನ್ಕ್ರಿಪ್ಶನ್ನ ಭದ್ರತೆಯನ್ನು ಪರಿಶೀಲಿಸಲು, ಎರಡೂ ಸಾಧನಗಳಲ್ಲಿ ಈ ಭದ್ರತಾ ಸಂಖ್ಯೆಯನ್ನು ಹೋಲಿಸಿ",
|
||||
"preparing": "ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…",
|
||||
"transferring": "ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ…"
|
||||
"transferring": "ವರ್ಗಾಯಿಸಲಾಗುತ್ತಿದೆ…",
|
||||
"click-to-send-share-mode": "{{descriptor}} ಕಳುಹಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"
|
||||
},
|
||||
"about": {
|
||||
"claim": "ಸಾಧನಗಳಾದ್ಯಂತ ಫೈಲ್ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸುಲಭವಾದ ಮಾರ್ಗ",
|
||||
@@ -154,7 +174,11 @@
|
||||
"close-about_aria-label": "PairDrop ಕುರಿತು ಪುಟವನ್ನು ಮುಚ್ಚಿ",
|
||||
"buy-me-a-coffee_title": "ನನಗೆ ಕಾಫಿ ಖರೀದಿಸಿ!",
|
||||
"github_title": "GitHub ನಲ್ಲಿ PairDrop",
|
||||
"faq_title": "ಪದೇ ಪದೇ ಕೇಳಲಾಗುವ ಪ್ರಶ್ನೆಗಳು"
|
||||
"faq_title": "ಪದೇ ಪದೇ ಕೇಳಲಾಗುವ ಪ್ರಶ್ನೆಗಳು",
|
||||
"bluesky_title": "BlueSky ನಲ್ಲಿ ನಮ್ಮನ್ನು ಅನುಸರಿಸಿ",
|
||||
"privacypolicy_title": "ನಮ್ಮ ಗೌಪ್ಯತೆ ನೀತಿ ತೆರೆಯಿರಿ",
|
||||
"mastodon_title": "Mastodon ನಲ್ಲಿ PairDrop ಕುರಿತು ಬರೆಯಿರಿ",
|
||||
"custom_title": "ನಮ್ಮನ್ನು ಅನುಸರಿಸಿ"
|
||||
},
|
||||
"document-titles": {
|
||||
"file-transfer-requested": "ಫೈಲ್ ವರ್ಗಾವಣೆಗೆ ವಿನಂತಿಸಲಾಗಿದೆ",
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
"pair-device_title": "Emparelhar seus dispositivos permanentemente",
|
||||
"edit-paired-devices_title": "Editar dispositivos emparelhados",
|
||||
"join-public-room_title": "Entrar em uma sala pública temporariamente",
|
||||
"cancel-share-mode": "Concluído"
|
||||
"cancel-share-mode": "Concluído",
|
||||
"edit-share-mode": "Editar"
|
||||
},
|
||||
"instructions": {
|
||||
"no-peers_data-drop-bg": "Solte para selecionar o destinatário",
|
||||
@@ -25,7 +26,11 @@
|
||||
"x-instructions-share-mode_mobile": "Toque para enviar",
|
||||
"activate-share-mode-base": "Abra o PairDrop em outros dispositivos para enviar",
|
||||
"activate-share-mode-and-other-files-plural": "e {{count}} outros arquivos",
|
||||
"activate-share-mode-shared-text": "texto compartilhado"
|
||||
"activate-share-mode-shared-text": "texto compartilhado",
|
||||
"activate-share-mode-shared-files-plural": "{{count}} arquivos compartilhados",
|
||||
"activate-share-mode-shared-file": "arquivo compartilhado",
|
||||
"activate-share-mode-and-other-file": "e 1 outro arquivo",
|
||||
"webrtc-requirement": "Para usar essa instância do PairDrop, o WebRTC deve estar habilitado!"
|
||||
},
|
||||
"footer": {
|
||||
"known-as": "Você é conhecido como:",
|
||||
@@ -69,14 +74,14 @@
|
||||
"share": "Compartilhar",
|
||||
"download": "Baixar",
|
||||
"send-message-title": "Enviar Mensagem",
|
||||
"send-message-to": "Enviar uma Mensagem para",
|
||||
"send-message-to": "Para:",
|
||||
"message_title": "Insira a mensagem a ser enviada",
|
||||
"send": "Enviar",
|
||||
"receive-text-title": "Mensagem Recebida",
|
||||
"copy": "Copiar",
|
||||
"base64-processing": "Processando…",
|
||||
"base64-tap-to-paste": "Toque aqui para colar {{type}}",
|
||||
"base64-paste-to-send": "Cole aqui para enviar {{type}}",
|
||||
"base64-tap-to-paste": "Toque aqui para compartilhar {{type}}",
|
||||
"base64-paste-to-send": "Cole da área de transferência aqui para compartilhar {{type}}",
|
||||
"base64-text": "texto",
|
||||
"base64-files": "arquivos",
|
||||
"file-other-description-image": "e mais 1 imagem",
|
||||
@@ -92,7 +97,16 @@
|
||||
"language-selector-title": "Definir idioma",
|
||||
"system-language": "Idioma do sistema",
|
||||
"public-room-qr-code_title": "Clique para copiar o link da sala pública",
|
||||
"pair-devices-qr-code_title": "Clique para copiar o link para emparelhar este dispositivo"
|
||||
"pair-devices-qr-code_title": "Clique para copiar o link para emparelhar este dispositivo",
|
||||
"message_placeholder": "Texto",
|
||||
"close-toast_title": "Fechar notificação",
|
||||
"share-text-checkbox": "Sempre exibir essa mensagem ao compartilhar texto",
|
||||
"base64-title-files": "Compartilhar arquivos",
|
||||
"approve": "aprovar",
|
||||
"paired-device-removed": "Dispositivo pareado foi removido.",
|
||||
"share-text-title": "Compartilhar Mensagem de Texto",
|
||||
"share-text-subtitle": "Editar mensagem antes de enviar:",
|
||||
"base64-title-text": "Compartilhar texto"
|
||||
},
|
||||
"about": {
|
||||
"close-about_aria-label": "Fechar Sobre o PairDrop",
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
"room-url-copied-to-clipboard": "Link către sala publică copiat în clipboard"
|
||||
},
|
||||
"header": {
|
||||
"cancel-share-mode": "Gata",
|
||||
"cancel-share-mode": "Anulare",
|
||||
"theme-auto_title": "Adaptează tema la sistem",
|
||||
"install_title": "Instalează PairDrop",
|
||||
"theme-dark_title": "Utilizați mereu tema întunecoasă",
|
||||
@@ -69,13 +69,15 @@
|
||||
"language-selector_title": "Setează Limba",
|
||||
"about_title": "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": {
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -83,7 +85,11 @@
|
||||
"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-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": {
|
||||
"processing": "Procesarea…",
|
||||
@@ -95,7 +101,7 @@
|
||||
"transferring": "Transferul…"
|
||||
},
|
||||
"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.",
|
||||
"receive-text-title": "Mesaj primit",
|
||||
"edit-paired-devices-title": "Editați dispozitivele asociate",
|
||||
@@ -111,7 +117,7 @@
|
||||
"join": "Alătură-te",
|
||||
"title-image-plural": "Imagini",
|
||||
"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",
|
||||
"copy": "Copiază",
|
||||
"file-other-description-image": "și 1 altă imagine",
|
||||
@@ -125,7 +131,7 @@
|
||||
"title-image": "Imagine",
|
||||
"file-other-description-file-plural": "și {{count}} alte fișiere",
|
||||
"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",
|
||||
"pair": "Cuplu",
|
||||
"hr-or": "SAU",
|
||||
@@ -144,7 +150,16 @@
|
||||
"enter-room-id-from-another-device": "Introdu ID-ul camerei de pe un alt dispozitiv pentru a intra în cameră.",
|
||||
"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",
|
||||
"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": {
|
||||
"claim": "Cel mai simplu mod de a transfera fișiere între dispozitive",
|
||||
@@ -152,7 +167,11 @@
|
||||
"close-about_aria-label": "Închide Despre PairDrop",
|
||||
"buy-me-a-coffee_title": "Cumpără-mi o cafea!",
|
||||
"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": {
|
||||
"file-transfer-requested": "Transfer de fișiere cerut",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"header": {
|
||||
"about_title": "PairDrop Hakkında",
|
||||
"about_aria-label": "PairDrop Hakkında Aç",
|
||||
"about_aria-label": "PairDrop Hakkındayı Aç",
|
||||
"theme-auto_title": "Temayı sisteme uyarla",
|
||||
"theme-light_title": "Daima açık tema kullan",
|
||||
"theme-dark_title": "Daima koyu tema kullan",
|
||||
@@ -12,18 +12,19 @@
|
||||
"cancel-share-mode": "Bitti",
|
||||
"join-public-room_title": "Geçici olarak genel odaya katılın",
|
||||
"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": {
|
||||
"no-peers_data-drop-bg": "Alıcıyı seçmek için bırakın",
|
||||
"x-instructions_mobile": "Dosya göndermek için dokun veya mesaj göndermek için uzun dokun",
|
||||
"x-instructions-share-mode_desktop": "Göndermek için tıkla {{descriptor}}",
|
||||
"x-instructions-share-mode_desktop": "{{descriptor}} kişisine göndermek için tıkla",
|
||||
"activate-share-mode-and-other-files-plural": "ve {{count}} diğer dosya",
|
||||
"x-instructions-share-mode_mobile": "Göndermek için dokun {{descriptor}}",
|
||||
"x-instructions-share-mode_mobile": "{{descriptor}} kişisine göndermek için dokun",
|
||||
"activate-share-mode-base": "Göndermek için diğer cihazlarda PairDrop'u açın",
|
||||
"no-peers-subtitle": "Diğer ağlarda keşfedilebilir olmak için cihazları eşleştirin veya ortak bir odaya girin",
|
||||
"activate-share-mode-shared-text": "paylaşılan metin",
|
||||
"x-instructions_desktop": "Dosya göndermek için tıkla ya da mesaj göndermek için sağ tıkla",
|
||||
"x-instructions_desktop": "Dosya göndermek için tıkla veya mesaj göndermek için sağ tıkla",
|
||||
"no-peers-title": "Dosya göndermek için diğer cihazlarda PairDrop'u açın",
|
||||
"x-instructions_data-drop-peer": "Göndermek için serbest bırak",
|
||||
"x-instructions_data-drop-bg": "Alıcıyı seçmek için bırakın",
|
||||
@@ -131,11 +132,11 @@
|
||||
"public-room-left": "{{publicRoomId}} genel odasından ayrıldın",
|
||||
"copied-text": "Metin panoya kopyalandı",
|
||||
"display-name-random-again": "Mevcut adın tekrardan rastgele oluşturuldu",
|
||||
"display-name-changed-permanently": "Mevcut adın kalıcı olarak değiştirilir",
|
||||
"display-name-changed-permanently": "Mevcut adın kalıcı olarak değiştirildi",
|
||||
"copied-to-clipboard-error": "Kopyalama mümkün değil. Manuel olarak kopyalayın.",
|
||||
"pairing-success": "Cihazlar eşleştirildi",
|
||||
"clipboard-content-incorrect": "Pano içeriği yanlış",
|
||||
"display-name-changed-temporarily": "Mevcut adın yalnızca bu oturum için değiştirilir",
|
||||
"display-name-changed-temporarily": "Mevcut adın yalnızca bu oturum için değiştirildi",
|
||||
"copied-to-clipboard": "Panoya kopyalandı",
|
||||
"offline": "Çevrimdışısın",
|
||||
"pairing-tabs-error": "İki web tarayıcı sekmesini eşleştirmek mümkün değildir",
|
||||
@@ -149,7 +150,7 @@
|
||||
"room-url-copied-to-clipboard": "Genel oda bağlantı linki panoya kopyalandı",
|
||||
"copied-text-error": "Panoya kopyalanamadı. Lütfen manuel olarak kopyalayın!",
|
||||
"download-successful": "{{descriptor}} indirildi",
|
||||
"click-to-show": "Göstermek için tıkla"
|
||||
"click-to-show": "Görmek için tıkla"
|
||||
},
|
||||
"peer-ui": {
|
||||
"processing": "İşleniyor…",
|
||||
@@ -166,7 +167,11 @@
|
||||
"close-about_aria-label": "PairDrop Hakkında'yı Kapat",
|
||||
"buy-me-a-coffee_title": "Bana bir kahve al!",
|
||||
"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": {
|
||||
"file-transfer-requested": "Dosya Transferi Talep Edildi",
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"cancel-share-mode": "完成",
|
||||
"join-public-room_title": "暂时加入公共房间",
|
||||
"language-selector_title": "设置语言",
|
||||
"edit-share-mode": "编辑"
|
||||
"edit-share-mode": "编辑",
|
||||
"expand_title": "展开标题按钮行"
|
||||
},
|
||||
"instructions": {
|
||||
"x-instructions_data-drop-peer": "释放以发送到此设备",
|
||||
@@ -114,7 +115,11 @@
|
||||
"github_title": "PairDrop 在 GitHub 上开源",
|
||||
"claim": "最简单的跨设备传输方案",
|
||||
"buy-me-a-coffee_title": "帮我买杯咖啡!",
|
||||
"tweet_title": "关于 PairDrop 的推特"
|
||||
"tweet_title": "关于 PairDrop 的推特",
|
||||
"bluesky_title": "在 BlueSky 上关注",
|
||||
"privacypolicy_title": "打开隐私政策",
|
||||
"mastodon_title": "在 Maston 上推广 PairDrop",
|
||||
"custom_title": "关注我们"
|
||||
},
|
||||
"notifications": {
|
||||
"display-name-changed-permanently": "展示的名字已经永久变更",
|
||||
|
||||
@@ -1,40 +1,49 @@
|
||||
class Localization {
|
||||
constructor() {
|
||||
Localization.$htmlRoot = document.querySelector('html');
|
||||
|
||||
Localization.defaultLocale = "en";
|
||||
Localization.supportedLocales = ["ar", "de", "en", "es", "fr", "id", "it", "ja", "nb", "nl", "ro", "ru", "tr", "zh-CN","pt-BR"];
|
||||
Localization.supportedLocales = ["ar", "ca", "de", "en", "es", "fr", "id", "it", "ja", "kn", "nb", "nl", "pt-BR", "ro", "ru", "tr", "zh-CN"];
|
||||
Localization.supportedLocalesRtl = ["ar"];
|
||||
|
||||
Localization.translations = {};
|
||||
Localization.defaultTranslations = {};
|
||||
Localization.translationsDefaultLocale = {};
|
||||
|
||||
Localization.systemLocale = Localization.getSupportedOrDefault(navigator.languages);
|
||||
Localization.systemLocale = Localization.getSupportedOrDefaultLocales(navigator.languages);
|
||||
|
||||
let storedLanguageCode = localStorage.getItem('language_code');
|
||||
|
||||
Localization.initialLocale = storedLanguageCode && Localization.isSupported(storedLanguageCode)
|
||||
Localization.initialLocale = storedLanguageCode && Localization.localeIsSupported(storedLanguageCode)
|
||||
? storedLanguageCode
|
||||
: Localization.systemLocale;
|
||||
}
|
||||
|
||||
static isSupported(locale) {
|
||||
static localeIsSupported(locale) {
|
||||
return Localization.supportedLocales.indexOf(locale) > -1;
|
||||
}
|
||||
|
||||
static isRtlLanguage(locale) {
|
||||
static localeIsRtl(locale) {
|
||||
return Localization.supportedLocalesRtl.indexOf(locale) > -1;
|
||||
}
|
||||
|
||||
static isCurrentLocaleRtl() {
|
||||
return Localization.isRtlLanguage(Localization.locale);
|
||||
static currentLocaleIsRtl() {
|
||||
return Localization.localeIsRtl(Localization.locale);
|
||||
}
|
||||
|
||||
static getSupportedOrDefault(locales) {
|
||||
static currentLocaleIsDefault() {
|
||||
return Localization.locale === Localization.defaultLocale
|
||||
}
|
||||
|
||||
static getSupportedOrDefaultLocales(locales) {
|
||||
// get generic locales not included in locales
|
||||
// ["en-us", "de-CH", "fr"] --> ["en", "de"]
|
||||
let localesGeneric = locales
|
||||
.map(locale => locale.split("-")[0])
|
||||
.filter(locale => locales.indexOf(locale) === -1);
|
||||
|
||||
return locales.find(Localization.isSupported)
|
||||
|| localesGeneric.find(Localization.isSupported)
|
||||
// If there is no perfect match for browser locales, try generic locales first before resorting to the default locale
|
||||
return locales.find(Localization.localeIsSupported)
|
||||
|| localesGeneric.find(Localization.localeIsSupported)
|
||||
|| Localization.defaultLocale;
|
||||
}
|
||||
|
||||
@@ -48,16 +57,14 @@ class Localization {
|
||||
await Localization.setLocale(locale)
|
||||
await Localization.translatePage();
|
||||
|
||||
const htmlRootNode = document.querySelector('html');
|
||||
|
||||
if (Localization.isRtlLanguage(locale)) {
|
||||
htmlRootNode.setAttribute('dir', 'rtl');
|
||||
if (Localization.localeIsRtl(locale)) {
|
||||
Localization.$htmlRoot.setAttribute('dir', 'rtl');
|
||||
}
|
||||
else {
|
||||
htmlRootNode.removeAttribute('dir');
|
||||
Localization.$htmlRoot.removeAttribute('dir');
|
||||
}
|
||||
|
||||
htmlRootNode.setAttribute('lang', locale);
|
||||
Localization.$htmlRoot.setAttribute('lang', locale);
|
||||
|
||||
|
||||
console.log("Page successfully translated",
|
||||
@@ -111,75 +118,108 @@ class Localization {
|
||||
const key = element.getAttribute("data-i18n-key");
|
||||
const attrs = element.getAttribute("data-i18n-attrs").split(" ");
|
||||
|
||||
for (let i in attrs) {
|
||||
let attr = attrs[i];
|
||||
attrs.forEach(attr => {
|
||||
if (attr === "text") {
|
||||
element.innerText = Localization.getTranslation(key);
|
||||
}
|
||||
else {
|
||||
element.setAttribute(attr, Localization.getTranslation(key, attr));
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static getTranslation(key, attr = null, data = {}, useDefault = false) {
|
||||
const keys = key.split(".");
|
||||
|
||||
let translationCandidates = useDefault
|
||||
? Localization.defaultTranslations
|
||||
: Localization.translations;
|
||||
|
||||
static getTranslationFromTranslationsObj(translationObj, key, attr) {
|
||||
let translation;
|
||||
|
||||
try {
|
||||
const keys = key.split(".");
|
||||
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
translationCandidates = translationCandidates[keys[i]]
|
||||
// iterate into translation object until last layer
|
||||
translationObj = translationObj[keys[i]]
|
||||
}
|
||||
|
||||
let lastKey = keys[keys.length - 1];
|
||||
|
||||
if (attr) lastKey += "_" + attr;
|
||||
|
||||
translation = translationCandidates[lastKey];
|
||||
translation = translationObj[lastKey];
|
||||
|
||||
for (let j in data) {
|
||||
if (translation.includes(`{{${j}}}`)) {
|
||||
translation = translation.replace(`{{${j}}}`, data[j]);
|
||||
} else {
|
||||
console.warn(`Translation for your language ${Localization.locale.toUpperCase()} misses at least one data placeholder:`, key, attr, data);
|
||||
Localization.logHelpCallKey(key);
|
||||
Localization.logHelpCall();
|
||||
translation = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
translation = "";
|
||||
}
|
||||
|
||||
if (!translation) {
|
||||
if (!useDefault) {
|
||||
console.warn(`Missing translation entry for your language ${Localization.locale.toUpperCase()}. Using ${Localization.defaultLocale.toUpperCase()} instead.`, key, attr);
|
||||
Localization.logHelpCallKey(key);
|
||||
Localization.logHelpCall();
|
||||
translation = this.getTranslation(key, attr, data, true);
|
||||
throw new Error(`Translation misses entry. Key: ${key} Attribute: ${attr}`);
|
||||
}
|
||||
|
||||
return translation;
|
||||
}
|
||||
|
||||
static addDataToTranslation(translation, data) {
|
||||
for (let j in data) {
|
||||
if (!translation.includes(`{{${j}}}`)) {
|
||||
throw new Error(`Translation misses data placeholder: ${j}`);
|
||||
}
|
||||
// Add data to translation
|
||||
translation = translation.replace(`{{${j}}}`, data[j]);
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
|
||||
static getTranslation(key, attr = null, data = {}, useDefault = false) {
|
||||
let translationObj = useDefault
|
||||
? Localization.translationsDefaultLocale
|
||||
: Localization.translations;
|
||||
|
||||
let translation;
|
||||
|
||||
try {
|
||||
translation = Localization.getTranslationFromTranslationsObj(translationObj, key, attr);
|
||||
translation = Localization.addDataToTranslation(translation, data);
|
||||
}
|
||||
catch (e) {
|
||||
// Log warnings and help calls
|
||||
console.warn(e);
|
||||
Localization.logTranslationMissingOrBroken(key, attr, data, useDefault);
|
||||
Localization.logHelpCallKey(key, attr);
|
||||
Localization.logHelpCall();
|
||||
|
||||
if (useDefault || Localization.currentLocaleIsDefault()) {
|
||||
// Is default locale already
|
||||
// Use empty string as translation
|
||||
translation = ""
|
||||
}
|
||||
else {
|
||||
console.warn("Missing translation in default language:", key, attr);
|
||||
Localization.logHelpCall();
|
||||
// Is not default locale yet
|
||||
// Get translation for default language with same arguments
|
||||
console.log(`Using default language ${Localization.defaultLocale.toUpperCase()} instead.`);
|
||||
translation = this.getTranslation(key, attr, data, true);
|
||||
}
|
||||
}
|
||||
|
||||
return Localization.escapeHTML(translation);
|
||||
}
|
||||
|
||||
static logTranslationMissingOrBroken(key, attr, data, useDefault) {
|
||||
let usedLocale = useDefault
|
||||
? Localization.defaultLocale.toUpperCase()
|
||||
: Localization.locale.toUpperCase();
|
||||
|
||||
console.warn(`Missing or broken translation for language ${usedLocale}.\n`, 'key:', key, 'attr:', attr, 'data:', data);
|
||||
}
|
||||
|
||||
static logHelpCall() {
|
||||
console.log("Help translating PairDrop: https://hosted.weblate.org/engage/pairdrop/");
|
||||
}
|
||||
|
||||
static logHelpCallKey(key) {
|
||||
console.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${Localization.locale.toLowerCase()}/?q=${key}`);
|
||||
static logHelpCallKey(key, attr) {
|
||||
let locale = Localization.locale.toLowerCase();
|
||||
|
||||
let keyComplete = !attr || attr === "text"
|
||||
? key
|
||||
: `${key}_${attr}`;
|
||||
|
||||
console.warn(`Translate this string here: https://hosted.weblate.org/browse/pairdrop/pairdrop-spa/${locale}/?q=${keyComplete}`);
|
||||
}
|
||||
|
||||
static escapeHTML(unsafeText) {
|
||||
|
||||
@@ -7,7 +7,7 @@ class PairDrop {
|
||||
this.$headerInstallBtn = $('install');
|
||||
|
||||
this.deferredStyles = [
|
||||
"styles/deferred-styles.css"
|
||||
"styles/styles-deferred.css"
|
||||
];
|
||||
this.deferredScripts = [
|
||||
"scripts/browser-tabs-connector.js",
|
||||
@@ -56,13 +56,16 @@ class PairDrop {
|
||||
await this.backgroundCanvas.fadeIn();
|
||||
|
||||
// Load deferred assets
|
||||
console.log("Load deferred assets...");
|
||||
await this.loadDeferredAssets();
|
||||
console.log("Loading of deferred assets completed.");
|
||||
|
||||
console.log("Hydrate UI...");
|
||||
await this.hydrate();
|
||||
console.log("UI hydrated.");
|
||||
|
||||
// Evaluate url params as soon as ws is connected
|
||||
console.log("Evaluate URL params as soon as websocket connection is established.");
|
||||
Events.on('ws-connected', _ => this.evaluateUrlParams(), {once: true});
|
||||
}
|
||||
|
||||
@@ -102,36 +105,40 @@ class PairDrop {
|
||||
}
|
||||
}
|
||||
|
||||
async loadDeferredAssets() {
|
||||
console.log("Load deferred assets");
|
||||
for (const url of this.deferredStyles) {
|
||||
await this.loadAndApplyStylesheet(url);
|
||||
}
|
||||
for (const url of this.deferredScripts) {
|
||||
await this.loadAndApplyScript(url);
|
||||
}
|
||||
loadDeferredAssets() {
|
||||
const stylePromises = this.deferredStyles.map(url => this.loadAndApplyStylesheet(url));
|
||||
const scriptPromises = this.deferredScripts.map(url => this.loadAndApplyScript(url));
|
||||
|
||||
return Promise.all([...stylePromises, ...scriptPromises]);
|
||||
}
|
||||
|
||||
loadStyleSheet(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let stylesheet = document.createElement('link');
|
||||
stylesheet.rel = 'stylesheet';
|
||||
stylesheet.rel = 'preload';
|
||||
stylesheet.as = 'style';
|
||||
stylesheet.href = url;
|
||||
stylesheet.type = 'text/css';
|
||||
stylesheet.onload = resolve;
|
||||
stylesheet.onload = _ => {
|
||||
stylesheet.onload = null;
|
||||
stylesheet.rel = 'stylesheet';
|
||||
resolve();
|
||||
};
|
||||
stylesheet.onerror = reject;
|
||||
|
||||
document.head.appendChild(stylesheet);
|
||||
});
|
||||
}
|
||||
|
||||
async loadAndApplyStylesheet(url) {
|
||||
try {
|
||||
await this.loadStyleSheet(url);
|
||||
console.log(`Stylesheet loaded successfully: ${url}`);
|
||||
} catch (error) {
|
||||
console.error('Error loading stylesheet:', error);
|
||||
}
|
||||
loadAndApplyStylesheet(url) {
|
||||
return new Promise( async (resolve) => {
|
||||
try {
|
||||
await this.loadStyleSheet(url);
|
||||
console.log(`Stylesheet loaded successfully: ${url}`);
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error('Error loading stylesheet:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadScript(url) {
|
||||
@@ -145,16 +152,20 @@ class PairDrop {
|
||||
});
|
||||
}
|
||||
|
||||
async loadAndApplyScript(url) {
|
||||
try {
|
||||
await this.loadScript(url);
|
||||
console.log(`Script loaded successfully: ${url}`);
|
||||
} catch (error) {
|
||||
console.error('Error loading script:', error);
|
||||
}
|
||||
loadAndApplyScript(url) {
|
||||
return new Promise( async (resolve) => {
|
||||
try {
|
||||
await this.loadScript(url);
|
||||
console.log(`Script loaded successfully: ${url}`);
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error('Error loading script:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async hydrate() {
|
||||
this.aboutUI = new AboutUI();
|
||||
this.peersUI = new PeersUI();
|
||||
this.languageSelectDialog = new LanguageSelectDialog();
|
||||
this.receiveFileDialog = new ReceiveFileDialog();
|
||||
@@ -222,6 +233,8 @@ class PairDrop {
|
||||
// remove url params from url
|
||||
const urlWithoutParams = getUrlWithoutArguments();
|
||||
window.history.replaceState({}, "Rewrite URL", urlWithoutParams);
|
||||
|
||||
console.log("URL params evaluated.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ class HeaderUI {
|
||||
this.$header.classList.remove('overflow-expanded');
|
||||
|
||||
|
||||
const rtlLocale = Localization.isCurrentLocaleRtl();
|
||||
const rtlLocale = Localization.currentLocaleIsRtl();
|
||||
let icon;
|
||||
const $headerIconsShown = document.querySelectorAll('body > header:first-of-type > *:not([hidden])');
|
||||
|
||||
|
||||
@@ -172,31 +172,34 @@ class PeersUI {
|
||||
}
|
||||
|
||||
_onDrop(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.shareMode.active || Dialog.anyDialogShown()) return;
|
||||
|
||||
if (!$$('x-peer') || !$$('x-peer').contains(e.target)) {
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
Events.fire('activate-share-mode', {files: e.dataTransfer.files});
|
||||
} else {
|
||||
for (let i=0; i<e.dataTransfer.items.length; i++) {
|
||||
if (e.dataTransfer.items[i].type === "text/plain") {
|
||||
e.dataTransfer.items[i].getAsString(text => {
|
||||
Events.fire('activate-share-mode', {text: text});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
this._onDragEnd();
|
||||
|
||||
if ($$('x-peer') || !$$('x-peer').contains(e.target)) return; // dropped on peer
|
||||
|
||||
const files = e.dataTransfer.files;
|
||||
const text = e.dataTransfer.getData("text");
|
||||
|
||||
if (files.length > 0) {
|
||||
Events.fire('activate-share-mode', {
|
||||
files: files
|
||||
});
|
||||
}
|
||||
else if(text.length > 0) {
|
||||
Events.fire('activate-share-mode', {
|
||||
text: text
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_onDragOver(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.shareMode.active || Dialog.anyDialogShown()) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
this.$xInstructions.setAttribute('drop-bg', true);
|
||||
this.$xNoPeers.setAttribute('drop-bg', true);
|
||||
}
|
||||
@@ -590,6 +593,9 @@ class PeerUI {
|
||||
_onFilesSelected(e) {
|
||||
const $input = e.target;
|
||||
const files = $input.files;
|
||||
|
||||
if (files.length === 0) return;
|
||||
|
||||
Events.fire('files-selected', {
|
||||
files: files,
|
||||
to: this._peer.id
|
||||
@@ -630,29 +636,28 @@ class PeerUI {
|
||||
}
|
||||
|
||||
_onDrop(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (PeerUI._shareMode.active || Dialog.anyDialogShown()) return;
|
||||
|
||||
if (e.dataTransfer.files.length > 0) {
|
||||
Events.fire('files-selected', {
|
||||
files: e.dataTransfer.files,
|
||||
to: this._peer.id
|
||||
});
|
||||
} else {
|
||||
for (let i=0; i<e.dataTransfer.items.length; i++) {
|
||||
if (e.dataTransfer.items[i].type === "text/plain") {
|
||||
e.dataTransfer.items[i].getAsString(text => {
|
||||
Events.fire('send-text', {
|
||||
text: text,
|
||||
to: this._peer.id
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
this._onDragEnd();
|
||||
|
||||
const peerId = this._peer.id;
|
||||
const files = e.dataTransfer.files;
|
||||
const text = e.dataTransfer.getData("text");
|
||||
|
||||
if (files.length > 0) {
|
||||
Events.fire('files-selected', {
|
||||
files: files,
|
||||
to: peerId
|
||||
});
|
||||
}
|
||||
else if (text.length > 0) {
|
||||
Events.fire('send-text', {
|
||||
text: text,
|
||||
to: peerId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_onDragOver() {
|
||||
@@ -1896,6 +1901,8 @@ class SendTextDialog extends Dialog {
|
||||
this.$submit = this.$el.querySelector('button[type="submit"]');
|
||||
this.$form.addEventListener('submit', e => this._onSubmit(e));
|
||||
this.$text.addEventListener('input', _ => this._onInput());
|
||||
this.$text.addEventListener('paste', e => this._onPaste(e));
|
||||
this.$text.addEventListener('drop', e => this._onDrop(e));
|
||||
|
||||
Events.on('text-recipient', e => this._onRecipient(e.detail.peerId, e.detail.deviceName));
|
||||
Events.on('keydown', e => this._onKeyDown(e));
|
||||
@@ -1914,6 +1921,40 @@ class SendTextDialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
async _onDrop(e) {
|
||||
e.preventDefault()
|
||||
|
||||
const text = e.dataTransfer.getData("text");
|
||||
const selection = window.getSelection();
|
||||
|
||||
if (selection.rangeCount) {
|
||||
selection.deleteFromDocument();
|
||||
selection.getRangeAt(0).insertNode(document.createTextNode(text));
|
||||
}
|
||||
|
||||
this._onInput();
|
||||
}
|
||||
|
||||
async _onPaste(e) {
|
||||
e.preventDefault()
|
||||
|
||||
const text = (e.clipboardData || window.clipboardData).getData('text');
|
||||
const selection = window.getSelection();
|
||||
|
||||
if (selection.rangeCount) {
|
||||
selection.deleteFromDocument();
|
||||
const textNode = document.createTextNode(text);
|
||||
const range = document.createRange();
|
||||
range.setStart(textNode, textNode.length);
|
||||
range.collapse(true);
|
||||
selection.getRangeAt(0).insertNode(textNode);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
this._onInput();
|
||||
}
|
||||
|
||||
_textEmpty() {
|
||||
return !this.$text.innerText || this.$text.innerText === "\n";
|
||||
}
|
||||
@@ -1978,12 +2019,15 @@ class ReceiveTextDialog extends Dialog {
|
||||
this._receiveTextQueue = [];
|
||||
}
|
||||
|
||||
selectionEmpty() {
|
||||
return !window.getSelection().toString()
|
||||
}
|
||||
|
||||
async _onKeyDown(e) {
|
||||
if (!this.isShown()) return
|
||||
|
||||
if (e.code === "KeyC" && (e.ctrlKey || e.metaKey)) {
|
||||
if (e.code === "KeyC" && (e.ctrlKey || e.metaKey) && this.selectionEmpty()) {
|
||||
await this._onCopy()
|
||||
this.hide();
|
||||
}
|
||||
else if (e.code === "Escape") {
|
||||
this.hide();
|
||||
@@ -1994,12 +2038,22 @@ class ReceiveTextDialog extends Dialog {
|
||||
window.blop.play();
|
||||
this._receiveTextQueue.push({text: text, peerId: peerId});
|
||||
this._setDocumentTitleMessages();
|
||||
changeFavicon("images/favicon-96x96-notification.png");
|
||||
|
||||
if (this.isShown()) return;
|
||||
|
||||
this._dequeueRequests();
|
||||
}
|
||||
|
||||
_dequeueRequests() {
|
||||
if (!this._receiveTextQueue.length) return;
|
||||
if (!this._receiveTextQueue.length) {
|
||||
this.$text.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
this._setDocumentTitleMessages();
|
||||
changeFavicon("images/favicon-96x96-notification.png");
|
||||
|
||||
let {text, peerId} = this._receiveTextQueue.shift();
|
||||
this._showReceiveTextDialog(text, peerId);
|
||||
}
|
||||
@@ -2010,26 +2064,68 @@ class ReceiveTextDialog extends Dialog {
|
||||
this.$displayName.classList.add($(peerId).ui._badgeClassName());
|
||||
|
||||
this.$text.innerText = text;
|
||||
this.$text.classList.remove('text-center');
|
||||
|
||||
// Beautify text if text is short
|
||||
if (text.length < 2000) {
|
||||
// replace urls with actual links
|
||||
this.$text.innerHTML = this.$text.innerHTML.replace(/((https?:\/\/|www)[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\-._~:\/?#\[\]@!$&'()*+,;=]+)/g, url => {
|
||||
return `<a href="${url}" target="_blank">${url}</a>`;
|
||||
});
|
||||
// Beautify text if text is not too long
|
||||
if (this.$text.innerText.length <= 300000) {
|
||||
// Hacky workaround to replace URLs with link nodes in all cases
|
||||
// 1. Use text variable, find all valid URLs via regex and replace URLs with placeholder
|
||||
// 2. Use html variable, find placeholders with regex and replace them with link nodes
|
||||
|
||||
let $textShadow = document.createElement('div');
|
||||
$textShadow.innerText = text;
|
||||
|
||||
let linkNodes = {};
|
||||
let searchHTML = $textShadow.innerHTML;
|
||||
const p = "@";
|
||||
const pRgx = new RegExp(`${p}\\d+`, 'g');
|
||||
let occP = searchHTML.match(pRgx) || [];
|
||||
|
||||
let m = 0;
|
||||
|
||||
const allowedDomainChars = "a-zA-Z0-9áàäčçđéèêŋńñóòôöšŧüžæøåëìíîïðùúýþćěłřśţźǎǐǒǔǥǧǩǯəʒâûœÿãõāēīōūăąĉċďĕėęĝğġģĥħĩĭįıĵķĸĺļľņňŏőŕŗŝşťũŭůűųŵŷżאבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ";
|
||||
const urlRgx = new RegExp(`(^|\\n|\\s|["><\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.])(((https?:\\/\\/)?(?:[${allowedDomainChars}](?:[${allowedDomainChars}-]{0,61}[${allowedDomainChars}])?\\.)+[${allowedDomainChars}][${allowedDomainChars}-]{0,61}[${allowedDomainChars}])(:?\\d*)\\/?([${allowedDomainChars}_\\/\\-#.]*)(\\?([${allowedDomainChars}\\-_~:\\/?#\\[\\]@!$&'()*+,;=%.]*))?)`, 'g');
|
||||
|
||||
$textShadow.innerText = text.replace(urlRgx,
|
||||
(match, whitespaceOrSpecial, url, g3, scheme) => {
|
||||
let link = url;
|
||||
|
||||
// prefix www.example.com with http protocol to prevent it from being a relative link
|
||||
if (!scheme && link.startsWith('www')) {
|
||||
link = "http://" + link
|
||||
}
|
||||
|
||||
if (isUrlValid(link)) {
|
||||
// link is valid -> replace with link node placeholder
|
||||
|
||||
// find linkNodePlaceholder that is not yet present in text node
|
||||
m++;
|
||||
while (occP.includes(`${p}${m}`)) {
|
||||
m++;
|
||||
}
|
||||
let linkNodePlaceholder = `${p}${m}`;
|
||||
|
||||
// add linkNodePlaceholder to text node and save a reference to linkNodes object
|
||||
linkNodes[linkNodePlaceholder] = `<a href="${link}" target="_blank">${url}</a>`;
|
||||
return `${whitespaceOrSpecial}${linkNodePlaceholder}`;
|
||||
}
|
||||
// link is not valid -> do not replace
|
||||
return match;
|
||||
});
|
||||
|
||||
|
||||
this.$text.innerHTML = $textShadow.innerHTML.replace(pRgx,
|
||||
(m) => {
|
||||
let urlNode = linkNodes[m];
|
||||
return urlNode ? urlNode : m;
|
||||
});
|
||||
}
|
||||
|
||||
this._evaluateOverflowing(this.$text);
|
||||
|
||||
this._setDocumentTitleMessages();
|
||||
|
||||
changeFavicon("images/favicon-96x96-notification.png");
|
||||
this.show();
|
||||
}
|
||||
|
||||
_setDocumentTitleMessages() {
|
||||
document.title = !this._receiveTextQueue.length
|
||||
document.title = this._receiveTextQueue.length <= 1
|
||||
? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop`
|
||||
: `${ Localization.getTranslation("document-titles.message-received-plural", null, {count: this._receiveTextQueue.length + 1}) } - PairDrop`;
|
||||
}
|
||||
@@ -2049,7 +2145,10 @@ class ReceiveTextDialog extends Dialog {
|
||||
|
||||
hide() {
|
||||
super.hide();
|
||||
setTimeout(() => this._dequeueRequests(), 500);
|
||||
setTimeout(() => {
|
||||
this._dequeueRequests();
|
||||
this.$text.innerHTML = "";
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2275,6 +2374,53 @@ class Base64Dialog extends Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
class AboutUI {
|
||||
constructor() {
|
||||
this.$donationBtn = $('donation-btn');
|
||||
this.$twitterBtn = $('twitter-btn');
|
||||
this.$mastodonBtn = $('mastodon-btn');
|
||||
this.$blueskyBtn = $('bluesky-btn');
|
||||
this.$customBtn = $('custom-btn');
|
||||
this.$privacypolicyBtn = $('privacypolicy-btn');
|
||||
Events.on('config', e => this._onConfig(e.detail.buttons));
|
||||
}
|
||||
|
||||
async _onConfig(btnConfig) {
|
||||
await this._evaluateBtnConfig(this.$donationBtn, btnConfig.donation_button);
|
||||
await this._evaluateBtnConfig(this.$twitterBtn, btnConfig.twitter_button);
|
||||
await this._evaluateBtnConfig(this.$mastodonBtn, btnConfig.mastodon_button);
|
||||
await this._evaluateBtnConfig(this.$blueskyBtn, btnConfig.bluesky_button);
|
||||
await this._evaluateBtnConfig(this.$customBtn, btnConfig.custom_button);
|
||||
await this._evaluateBtnConfig(this.$privacypolicyBtn, btnConfig.privacypolicy_button);
|
||||
}
|
||||
|
||||
async _evaluateBtnConfig($btn, config) {
|
||||
// if config is not set leave everything as default
|
||||
if (!Object.keys(config).length) return;
|
||||
|
||||
if (config.active === "false") {
|
||||
$btn.setAttribute('hidden', true);
|
||||
} else {
|
||||
if (config.link) {
|
||||
$btn.setAttribute('href', config.link);
|
||||
}
|
||||
if (config.title) {
|
||||
$btn.setAttribute('title', config.title);
|
||||
// prevent overwriting of custom title when setting different language
|
||||
$btn.removeAttribute('data-i18n-key');
|
||||
$btn.removeAttribute('data-i18n-attrs');
|
||||
}
|
||||
if (config.icon) {
|
||||
$btn.setAttribute('title', config.title);
|
||||
// prevent overwriting of custom title when setting different language
|
||||
$btn.removeAttribute('data-i18n-key');
|
||||
$btn.removeAttribute('data-i18n-attrs');
|
||||
}
|
||||
$btn.removeAttribute('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Toast extends Dialog {
|
||||
constructor() {
|
||||
super('toast');
|
||||
@@ -2373,14 +2519,9 @@ class Notifications {
|
||||
|
||||
_downloadNotification(files) {
|
||||
if (document.visibilityState !== 'visible') {
|
||||
let imagesOnly = true;
|
||||
for(let i=0; i<files.length; i++) {
|
||||
if (files[i].type.split('/')[0] !== 'image') {
|
||||
imagesOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let imagesOnly = files.every(file => file.type.split('/')[0] === 'image');
|
||||
let title;
|
||||
|
||||
if (files.length === 1) {
|
||||
title = `${files[0].name}`;
|
||||
}
|
||||
@@ -2405,15 +2546,8 @@ class Notifications {
|
||||
|
||||
_requestNotification(request, peerId) {
|
||||
if (document.visibilityState !== 'visible') {
|
||||
let imagesOnly = true;
|
||||
for(let i=0; i<request.header.length; i++) {
|
||||
if (request.header[i].mime.split('/')[0] !== 'image') {
|
||||
imagesOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let displayName = $(peerId).querySelector('.name').textContent
|
||||
let imagesOnly = request.header.every(header => header.mime.split('/')[0] === 'image');
|
||||
let displayName = $(peerId).querySelector('.name').textContent;
|
||||
|
||||
let descriptor;
|
||||
if (request.header.length === 1) {
|
||||
|
||||
@@ -583,4 +583,14 @@ async function decodeBase64Text(base64) {
|
||||
if (!base64) throw new Error('Base64 is empty');
|
||||
|
||||
return decodeURIComponent(escape(window.atob(base64)))
|
||||
}
|
||||
|
||||
function isUrlValid(url) {
|
||||
try {
|
||||
let urlObj = new URL(url);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
const cacheVersion = 'v1.10.0';
|
||||
const cacheVersion = 'v1.10.7';
|
||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||
const forceFetch = false; // FOR DEVELOPMENT: Set to true to always update assets instead of using cached versions
|
||||
const relativePathsToCache = [
|
||||
@@ -6,7 +6,7 @@ const relativePathsToCache = [
|
||||
'index.html',
|
||||
'manifest.json',
|
||||
'styles/styles-main.css',
|
||||
'styles/deferred-styles.css',
|
||||
'styles/styles-deferred.css',
|
||||
'scripts/localization.js',
|
||||
'scripts/main.js',
|
||||
'scripts/network.js',
|
||||
@@ -27,6 +27,7 @@ const relativePathsToCache = [
|
||||
'images/android-chrome-512x512-maskable.png',
|
||||
'images/apple-touch-icon.png',
|
||||
'lang/ar.json',
|
||||
'lang/ca.json',
|
||||
'lang/de.json',
|
||||
'lang/en.json',
|
||||
'lang/es.json',
|
||||
@@ -34,11 +35,13 @@ const relativePathsToCache = [
|
||||
'lang/id.json',
|
||||
'lang/it.json',
|
||||
'lang/ja.json',
|
||||
'lang/kn.json',
|
||||
'lang/nb.json',
|
||||
'lang/nl.json',
|
||||
'lang/tr.json',
|
||||
'lang/pt-BR.json',
|
||||
'lang/ro.json',
|
||||
'lang/ru.json',
|
||||
'lang/tr.json',
|
||||
'lang/zh-CN.json'
|
||||
];
|
||||
const relativePathsNotToCache = [
|
||||
@@ -190,7 +193,7 @@ const evaluateRequestData = function (request) {
|
||||
|
||||
const objectStoreRequest = objectStore.add(fileObjects[i]);
|
||||
objectStoreRequest.onsuccess = _ => {
|
||||
if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share-target=files');
|
||||
if (i === fileObjects.length - 1) resolve(pairDropUrl + '?share_target=files');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,7 +202,7 @@ const evaluateRequestData = function (request) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
let urlArgument = '?share-target=text';
|
||||
let urlArgument = '?share_target=text';
|
||||
|
||||
if (title) urlArgument += `&title=${title}`;
|
||||
if (text) urlArgument += `&text=${text}`;
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
display: block;
|
||||
overflow: auto;
|
||||
resize: none;
|
||||
line-height: 16px;
|
||||
max-height: 350px;
|
||||
word-break: break-word;
|
||||
word-wrap: anywhere;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.textarea:before {
|
||||
@@ -335,6 +335,7 @@ x-dialog x-paper {
|
||||
display: flex;
|
||||
margin: auto;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
z-index: 3;
|
||||
border-radius: 30px;
|
||||
@@ -382,10 +383,6 @@ x-dialog:not([show]) x-paper {
|
||||
transform: scale(0.1);
|
||||
}
|
||||
|
||||
x-dialog a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* Pair Devices Dialog & Public Room Dialog */
|
||||
|
||||
.input-key-container {
|
||||
@@ -784,7 +781,7 @@ x-dialog x-paper {
|
||||
background-color: var(--bg-color-secondary) !important;
|
||||
}
|
||||
|
||||
.textarea * {
|
||||
.textarea *:not(a) {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
color: unset !important;
|
||||
@@ -797,6 +794,10 @@ x-dialog x-paper {
|
||||
font-weight: unset !important;
|
||||
}
|
||||
|
||||
x-dialog a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
/* Image/Video/Audio Preview */
|
||||
.file-preview {
|
||||
margin-bottom: 15px;
|
||||
@@ -252,6 +252,7 @@ html[dir="rtl"] #expand.flipped > .icon {
|
||||
@font-face {
|
||||
font-family: "Open Sans";
|
||||
src: url('../fonts/OpenSans/static/OpenSans-Medium.ttf') format('truetype');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -625,12 +626,15 @@ x-dialog:not([show]) x-background {
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
background-color: var(--accent-color);
|
||||
transition: opacity 300ms;
|
||||
}
|
||||
|
||||
.icon-button:before {
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.btn:not([disabled]):hover:before,
|
||||
.icon-button:hover:before {
|
||||
opacity: 0.3;
|
||||
|
||||
@@ -32,10 +32,14 @@ process.on('unhandledRejection', (reason, promise) => {
|
||||
|
||||
// Evaluate arguments for deployment with Docker and Node.js
|
||||
let conf = {};
|
||||
|
||||
conf.debugMode = process.env.DEBUG_MODE === "true";
|
||||
|
||||
conf.port = process.env.PORT || 3000;
|
||||
|
||||
conf.wsFallback = process.argv.includes('--include-ws-fallback') || process.env.WS_FALLBACK === "true";
|
||||
conf.rtcConfig = process.env.RTC_CONFIG
|
||||
|
||||
conf.rtcConfig = process.env.RTC_CONFIG && process.env.RTC_CONFIG !== "false"
|
||||
? JSON.parse(fs.readFileSync(process.env.RTC_CONFIG, 'utf8'))
|
||||
: {
|
||||
"sdpSemantics": "unified-plan",
|
||||
@@ -47,7 +51,10 @@ conf.rtcConfig = process.env.RTC_CONFIG
|
||||
};
|
||||
|
||||
|
||||
conf.signalingServer = process.env.SIGNALING_SERVER || false;
|
||||
conf.signalingServer = process.env.SIGNALING_SERVER && process.env.SIGNALING_SERVER !== "false"
|
||||
? process.env.SIGNALING_SERVER
|
||||
: false;
|
||||
|
||||
conf.ipv6Localize = parseInt(process.env.IPV6_LOCALIZE) || false;
|
||||
|
||||
let rateLimit = false;
|
||||
@@ -62,10 +69,45 @@ else {
|
||||
}
|
||||
conf.rateLimit = rateLimit;
|
||||
|
||||
conf.buttons = {
|
||||
"donation_button": {
|
||||
"active": process.env.DONATION_BUTTON_ACTIVE,
|
||||
"link": process.env.DONATION_BUTTON_LINK,
|
||||
"title": process.env.DONATION_BUTTON_TITLE
|
||||
},
|
||||
"twitter_button": {
|
||||
"active": process.env.TWITTER_BUTTON_ACTIVE,
|
||||
"link": process.env.TWITTER_BUTTON_LINK,
|
||||
"title": process.env.TWITTER_BUTTON_TITLE
|
||||
},
|
||||
"mastodon_button": {
|
||||
"active": process.env.MASTODON_BUTTON_ACTIVE,
|
||||
"link": process.env.MASTODON_BUTTON_LINK,
|
||||
"title": process.env.MASTODON_BUTTON_TITLE
|
||||
},
|
||||
"bluesky_button": {
|
||||
"active": process.env.BLUESKY_BUTTON_ACTIVE,
|
||||
"link": process.env.BLUESKY_BUTTON_LINK,
|
||||
"title": process.env.BLUESKY_BUTTON_TITLE
|
||||
},
|
||||
"custom_button": {
|
||||
"active": process.env.CUSTOM_BUTTON_ACTIVE,
|
||||
"link": process.env.CUSTOM_BUTTON_LINK,
|
||||
"title": process.env.CUSTOM_BUTTON_TITLE
|
||||
},
|
||||
"privacypolicy_button": {
|
||||
"active": process.env.PRIVACYPOLICY_BUTTON_ACTIVE,
|
||||
"link": process.env.PRIVACYPOLICY_BUTTON_LINK,
|
||||
"title": process.env.PRIVACYPOLICY_BUTTON_TITLE
|
||||
}
|
||||
};
|
||||
|
||||
// Evaluate arguments for deployment with Node.js only
|
||||
conf.autoStart = process.argv.includes('--auto-restart');
|
||||
|
||||
conf.localhostOnly = process.argv.includes('--localhost-only');
|
||||
|
||||
|
||||
// Validate configuration
|
||||
if (conf.ipv6Localize) {
|
||||
if (!(0 < conf.ipv6Localize && conf.ipv6Localize < 8)) {
|
||||
|
||||
@@ -49,7 +49,8 @@ export default class PairDropServer {
|
||||
// By using `WS_SERVER`, you can host an instance that uses another signaling server.
|
||||
app.get('/config', (req, res) => {
|
||||
res.send({
|
||||
signalingServer: conf.signalingServer
|
||||
signalingServer: conf.signalingServer,
|
||||
buttons: conf.buttons
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user