Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
31ec776fb3 | |
![]() |
4862ba3067 | |
![]() |
7639aca84c | |
![]() |
8b8e5b7433 | |
![]() |
f6f3db2df9 | |
![]() |
abd3a0c47c | |
![]() |
89734e6954 | |
![]() |
59bd9265bc | |
![]() |
dbd6321fec | |
![]() |
d18e290ad4 | |
![]() |
d7b68e214e | |
![]() |
148eb79ef0 | |
![]() |
80615c533c | |
![]() |
b0b091c4f7 | |
![]() |
c7b7badb3d | |
![]() |
13e75f525d | |
![]() |
b7c1893ac0 | |
![]() |
341fa7fdf0 | |
![]() |
aa09da3076 | |
![]() |
547038c9bc | |
![]() |
a39d8cdc84 |
|
@ -36,7 +36,7 @@ If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Bug occurs on official PairDrop instance https://pairdrop.net/**
|
**Bug occurs on official PairDrop instance https://pairdrop.net/**
|
||||||
No | Yes
|
No | Yes
|
||||||
Version: v1.11.0
|
Version: v1.11.2
|
||||||
|
|
||||||
**Bug occurs on self-hosted PairDrop instance**
|
**Bug occurs on self-hosted PairDrop instance**
|
||||||
No | Yes
|
No | Yes
|
||||||
|
@ -44,7 +44,7 @@ No | Yes
|
||||||
**Self-Hosted Setup**
|
**Self-Hosted Setup**
|
||||||
Proxy: Nginx | Apache2
|
Proxy: Nginx | Apache2
|
||||||
Deployment: docker run | docker compose | npm run start:prod
|
Deployment: docker run | docker compose | npm run start:prod
|
||||||
Version: v1.11.0
|
Version: v1.11.2
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
|
|
@ -45,11 +45,11 @@ This pairdrop-cli version was released alongside v1.10.4
|
||||||
#### Linux / Mac
|
#### Linux / Mac
|
||||||
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases)
|
1. Download the latest _pairdrop-cli.zip_ from the [releases page](https://github.com/schlagmichdoch/PairDrop/releases)
|
||||||
```shell
|
```shell
|
||||||
wget "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.11.0/pairdrop-cli.zip"
|
wget "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.11.2/pairdrop-cli.zip"
|
||||||
```
|
```
|
||||||
or
|
or
|
||||||
```shell
|
```shell
|
||||||
curl -LO "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.11.0/pairdrop-cli.zip"
|
curl -LO "https://github.com/schlagmichdoch/PairDrop/releases/download/v1.11.2/pairdrop-cli.zip"
|
||||||
```
|
```
|
||||||
2. Unzip the archive to a folder of your choice e.g. `/usr/share/pairdrop-cli/`
|
2. Unzip the archive to a folder of your choice e.g. `/usr/share/pairdrop-cli/`
|
||||||
```shell
|
```shell
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "pairdrop",
|
"name": "pairdrop",
|
||||||
"version": "1.11.0",
|
"version": "1.11.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "pairdrop",
|
"name": "pairdrop",
|
||||||
"version": "1.11.0",
|
"version": "1.11.2",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
@ -318,16 +318,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.2.7",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bind-apply-helpers": "^1.0.1",
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
"es-define-property": "^1.0.1",
|
"es-define-property": "^1.0.1",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"es-object-atoms": "^1.0.0",
|
"es-object-atoms": "^1.1.1",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"get-proto": "^1.0.0",
|
"get-proto": "^1.0.1",
|
||||||
"gopd": "^1.2.0",
|
"gopd": "^1.2.0",
|
||||||
"has-symbols": "^1.1.0",
|
"has-symbols": "^1.1.0",
|
||||||
"hasown": "^2.0.2",
|
"hasown": "^2.0.2",
|
||||||
|
@ -815,9 +815,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.18.0",
|
"version": "8.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
|
||||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
"integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pairdrop",
|
"name": "pairdrop",
|
||||||
"version": "1.11.0",
|
"version": "1.11.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "server/index.js",
|
"main": "server/index.js",
|
||||||
|
|
|
@ -668,7 +668,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
<div class="title-wrapper" dir="ltr">
|
<div class="title-wrapper" dir="ltr">
|
||||||
<h1>PairDrop</h1>
|
<h1>PairDrop</h1>
|
||||||
<div class="font-subheading">v1.11.0</div>
|
<div class="font-subheading">v1.11.2</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
|
<div class="font-subheading" data-i18n-key="about.claim" data-i18n-attrs="text"></div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -811,9 +811,9 @@
|
||||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
<!--!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>
|
<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>
|
||||||
<symbol id="bluesky" viewBox="0 0 448 512">
|
<symbol id="bluesky" 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.-->
|
<!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 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>
|
<path d="M111.8 62.2C170.2 105.9 233 194.7 256 242.4c23-47.6 85.8-136.4 144.2-180.2c42.1-31.6 110.3-56 110.3 21.8c0 15.5-8.9 130.5-14.1 149.2C478.2 298 412 314.6 353.1 304.5c102.9 17.5 129.1 75.5 72.5 133.5c-107.4 110.2-154.3-27.6-166.3-62.9l0 0c-1.7-4.9-2.6-7.8-3.3-7.8s-1.6 3-3.3 7.8l0 0c-12 35.3-59 173.1-166.3 62.9c-56.5-58-30.4-116 72.5-133.5C100 314.6 33.8 298 15.7 233.1C10.4 214.4 1.5 99.4 1.5 83.9c0-77.8 68.2-53.4 110.3-21.8z"/>
|
||||||
</symbol>
|
</symbol>
|
||||||
<symbol id="custom" viewBox="0 0 512 512">
|
<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.-->
|
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.-->
|
||||||
|
|
|
@ -1,6 +1,35 @@
|
||||||
{
|
{
|
||||||
"header": {
|
"header": {
|
||||||
"about_title": "পেয়ার ড্রপ সম্পর্কে",
|
"about_title": "পেয়ার ড্রপ সম্পর্কে",
|
||||||
"install_title": "পেয়ার ড্রপ ইন্সটল করুন"
|
"install_title": "পেয়ার ড্রপ ইন্সটল করুন",
|
||||||
|
"pair-device_title": "ডিভাইস স্থায়ী ভাবে যুক্ত করুন",
|
||||||
|
"cancel-share-mode": "বাতিল",
|
||||||
|
"theme-light_title": "সবসময় সাদা থিম ব্যাবহার",
|
||||||
|
"language-selector_title": "ভাষা সেট করুন",
|
||||||
|
"about_aria-label": "পেয়ারড্রপ সম্পর্কে",
|
||||||
|
"theme-auto_title": "থিমের ধরন ডিভাইস অনুযায়ী",
|
||||||
|
"theme-dark_title": "সবসময় কালো থিব ব্যাবহার",
|
||||||
|
"notification_title": "নোটিফিকেশন চালু করুন",
|
||||||
|
"edit-paired-devices_title": "যুক্ত ডিভাইস সম্পাদনা করুন",
|
||||||
|
"join-public-room_title": "সাময়িক ভাবে পাবলিক রুমে জয়েন করুন",
|
||||||
|
"edit-share-mode": "সম্পাদনা",
|
||||||
|
"expand_title": "হেডার বোতামের সারিটি বড় করুন"
|
||||||
|
},
|
||||||
|
"instructions": {
|
||||||
|
"activate-share-mode-and-other-file": "আর একটি ফাইল যোগ করুন",
|
||||||
|
"activate-share-mode-shared-file": "পাঠানো ফাইল",
|
||||||
|
"no-peers-subtitle": "ডিভাইস প্রদর্শিত হতে নতুন ডিভাইস যুক্ত করুন অথবা পাবলিক রুমে জয়েন দিন",
|
||||||
|
"no-peers-title": "ফাইল পাঠানোর জন্য অন্যান্য ডিভাইসে পেয়ারড্রপ খুলুন",
|
||||||
|
"x-instructions_data-drop-bg": "প্রাপক নির্বাচন করতে ছেড়ে দিন",
|
||||||
|
"no-peers_data-drop-bg": "প্রাপক নির্বাচন ছেড়ে দিন",
|
||||||
|
"x-instructions_desktop": "ফাইল পাঠাতে ক্লিক করুন অথবা মেসেজ পাঠাতে ডানে চাপুন",
|
||||||
|
"x-instructions_mobile": "ফাইল পাঠাতে ক্লিক করুন অথবা বেশি চেপে মেসেজ পাঠান",
|
||||||
|
"x-instructions_data-drop-peer": "পিয়ারকে পাঠানোর জন্য রিলিজ করুন",
|
||||||
|
"x-instructions-share-mode_desktop": "পাঠাতে ক্লিক করুন",
|
||||||
|
"x-instructions-share-mode_mobile": "পাঠাতে ক্লিক করুন",
|
||||||
|
"activate-share-mode-base": "অন্য ডিভাইসে পাঠাতে পেয়ারড্রপ খুলুন",
|
||||||
|
"activate-share-mode-and-other-files-plural": "অন্য ফাইল যোগ করুন",
|
||||||
|
"activate-share-mode-shared-text": "পাঠানো টেক্সট",
|
||||||
|
"activate-share-mode-shared-files-plural": "পাঠানো ফাইল গুলো"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{
|
{
|
||||||
"footer": {
|
"footer": {
|
||||||
"webrtc": "(WebRTCが無効なため)",
|
"webrtc": "(WebRTCが無効なため)",
|
||||||
"public-room-devices_title": "公開ルーム内のデバイスは、接続中のネットワークと関係なくアクセスできます。",
|
"public-room-devices_title": "公開ルーム内のデバイスは、別のネットワークからもアクセスできます。",
|
||||||
"display-name_data-placeholder": "読み込み中…",
|
"display-name_data-placeholder": "読み込み中…",
|
||||||
"display-name_title": "デバイス名を変更する",
|
"display-name_title": "デバイス名を変更する",
|
||||||
"traffic": "この通信は",
|
"traffic": "この通信は",
|
||||||
"paired-devices_title": "ペアリング済みデバイスであれば、接続中のネットワークに関わらずアクセスできます。",
|
"paired-devices_title": "ペアリング済みデバイスは、別のネットワークからもアクセスできます。",
|
||||||
"public-room-devices": "ルーム{{roomId}}",
|
"public-room-devices": "ルーム{{roomId}}",
|
||||||
"paired-devices": "ペアリング済みデバイス",
|
"paired-devices": "ペアリング済みデバイス",
|
||||||
"on-this-network": "このネットワーク上",
|
"on-this-network": "このネットワーク内",
|
||||||
"routed": "サーバーを経由します",
|
"routed": "サーバーを経由します",
|
||||||
"discovery": "このデバイスを検出可能なネットワーク:",
|
"discovery": "このデバイスを検出可能なネットワーク:",
|
||||||
"on-this-network_title": "このネットワーク上のすべてのデバイスからアクセスできます。",
|
"on-this-network_title": "このネットワーク内のすべてのデバイスからアクセスできます。",
|
||||||
"known-as": "他のデバイスに表示される名前:"
|
"known-as": "このデバイスの名前:"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"request-title": "{{name}}は{{count}}個の{{descriptor}}を共有しようとしています",
|
"request-title": "{{name}}は{{count}}個の{{descriptor}}を共有しようとしています",
|
||||||
|
@ -20,12 +20,12 @@
|
||||||
"message-received": "{{name}}から受信したメッセージ(クリックしてコピー)",
|
"message-received": "{{name}}から受信したメッセージ(クリックしてコピー)",
|
||||||
"rate-limit-join-key": "レート制限に到達しました。10秒待ってから再度お試しください。",
|
"rate-limit-join-key": "レート制限に到達しました。10秒待ってから再度お試しください。",
|
||||||
"connecting": "接続中…",
|
"connecting": "接続中…",
|
||||||
"pairing-key-invalidated": "コード{{key}}が失効しました",
|
"pairing-key-invalidated": "コード{{key}}は無効になりました",
|
||||||
"pairing-key-invalid": "無効なコード",
|
"pairing-key-invalid": "無効なコード",
|
||||||
"connected": "接続しました",
|
"connected": "接続済み",
|
||||||
"pairing-not-persistent": "このデバイスとのペアリングは解除される可能性があります",
|
"pairing-not-persistent": "このデバイスとのペアリングは解除される可能性があります",
|
||||||
"text-content-incorrect": "無効なテキスト内容です",
|
"text-content-incorrect": "無効なテキスト内容です",
|
||||||
"message-transfer-completed": "メッセージの送信が完了しました",
|
"message-transfer-completed": "メッセージを送信しました",
|
||||||
"file-transfer-completed": "ファイル転送が完了しました",
|
"file-transfer-completed": "ファイル転送が完了しました",
|
||||||
"file-content-incorrect": "無効なファイル内容です",
|
"file-content-incorrect": "無効なファイル内容です",
|
||||||
"files-incorrect": "ファイルが間違っています",
|
"files-incorrect": "ファイルが間違っています",
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
"copied-to-clipboard-error": "コピーできませんでした。手動でコピーしてください。",
|
"copied-to-clipboard-error": "コピーできませんでした。手動でコピーしてください。",
|
||||||
"pairing-success": "ペアリングしました",
|
"pairing-success": "ペアリングしました",
|
||||||
"clipboard-content-incorrect": "無効なクリップボード内容です",
|
"clipboard-content-incorrect": "無効なクリップボード内容です",
|
||||||
"display-name-changed-temporarily": "この接続のみデバイス名が変更されました",
|
"display-name-changed-temporarily": "この接続でのみデバイス名が変更されました",
|
||||||
"copied-to-clipboard": "クリップボードにコピーしました",
|
"copied-to-clipboard": "クリップボードにコピーしました",
|
||||||
"offline": "オフラインです",
|
"offline": "オフラインです",
|
||||||
"pairing-tabs-error": "同じWebブラウザーで開いたタブ同士でペアリングすることはできません",
|
"pairing-tabs-error": "同じWebブラウザーで開いたタブ同士でペアリングすることはできません",
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"cancel-share-mode": "キャンセル",
|
"cancel-share-mode": "キャンセル",
|
||||||
"theme-auto_title": "システムテーマに合わせる",
|
"theme-auto_title": "システムのテーマに合わせる",
|
||||||
"install_title": "PairDropをインストール",
|
"install_title": "PairDropをインストール",
|
||||||
"theme-dark_title": "常にダークテーマを使用する",
|
"theme-dark_title": "常にダークテーマを使用する",
|
||||||
"pair-device_title": "他のデバイスとペアリングする",
|
"pair-device_title": "他のデバイスとペアリングする",
|
||||||
|
@ -74,15 +74,15 @@
|
||||||
"expand_title": "ヘッダーボタン列を拡大する"
|
"expand_title": "ヘッダーボタン列を拡大する"
|
||||||
},
|
},
|
||||||
"instructions": {
|
"instructions": {
|
||||||
"x-instructions_mobile": "タップでファイルを送信、長押しでメッセージを送信します",
|
"x-instructions_mobile": "タップでファイル送信、長押しでメッセージ送信",
|
||||||
"x-instructions-share-mode_desktop": "クリックして{{descriptor}}を送信",
|
"x-instructions-share-mode_desktop": "クリックして{{descriptor}}を送信",
|
||||||
"activate-share-mode-and-other-files-plural": "とその他{{count}}個のファイル",
|
"activate-share-mode-and-other-files-plural": "とその他{{count}}個のファイル",
|
||||||
"x-instructions-share-mode_mobile": "タップして{{descriptor}}を送信",
|
"x-instructions-share-mode_mobile": "タップして{{descriptor}}を送信",
|
||||||
"activate-share-mode-base": "他のデバイスでPairDropを開いて送信します",
|
"activate-share-mode-base": "他のデバイスでPairDropを開いて送信します",
|
||||||
"no-peers-subtitle": "ペアリングや公開ルームを使用すると、他のネットワーク上のデバイスと共有できます",
|
"no-peers-subtitle": "ペアリングや公開ルームを使うと、別のネットワークにあるデバイスと共有できます",
|
||||||
"activate-share-mode-shared-text": "共有されたテキスト",
|
"activate-share-mode-shared-text": "共有されたテキスト",
|
||||||
"x-instructions_desktop": "左クリックでファイルを送信、右クリックでメッセージを送信します",
|
"x-instructions_desktop": "左クリックでファイル送信、右クリックでメッセージ送信",
|
||||||
"no-peers-title": "ファイルを共有するには他のデバイスでPairDropを開いてください",
|
"no-peers-title": "ファイル共有するには他のデバイスでPairDropを開きます",
|
||||||
"x-instructions_data-drop-peer": "ドロップするとこのデバイスに送信します",
|
"x-instructions_data-drop-peer": "ドロップするとこのデバイスに送信します",
|
||||||
"x-instructions_data-drop-bg": "送信したいデバイスの上でドロップしてください",
|
"x-instructions_data-drop-bg": "送信したいデバイスの上でドロップしてください",
|
||||||
"no-peers_data-drop-bg": "送信したいデバイスの上でドロップしてください",
|
"no-peers_data-drop-bg": "送信したいデバイスの上でドロップしてください",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"peer-ui": {
|
"peer-ui": {
|
||||||
"processing": "処理中…",
|
"processing": "処理中…",
|
||||||
"click-to-send-share-mode": "クリックして{{descriptor}}を送信",
|
"click-to-send-share-mode": "クリックして{{descriptor}}を送信",
|
||||||
"click-to-send": "左クリックでファイルを送信、右クリックでメッセージを送信します",
|
"click-to-send": "左クリックでファイル送信、右クリックでメッセージ送信",
|
||||||
"waiting": "待機中…",
|
"waiting": "待機中…",
|
||||||
"connection-hash": "エンドツーエンド暗号化のセキュリティを確認するには、両方のデバイスのセキュリティナンバーを確認してください",
|
"connection-hash": "エンドツーエンド暗号化のセキュリティを確認するには、両方のデバイスのセキュリティナンバーを確認してください",
|
||||||
"preparing": "準備中…",
|
"preparing": "準備中…",
|
||||||
|
@ -102,8 +102,8 @@
|
||||||
},
|
},
|
||||||
"dialogs": {
|
"dialogs": {
|
||||||
"base64-paste-to-send": "ここをタップして{{type}}を送信",
|
"base64-paste-to-send": "ここをタップして{{type}}を送信",
|
||||||
"auto-accept-instructions-2": "」を有効にすると、そのデバイスから送信されたすべてのファイルを自動的に受け入れます。",
|
"auto-accept-instructions-2": "」が有効なら、そのデバイスが送信したすべてのファイルを自動で受け入れます。",
|
||||||
"receive-text-title": "メッセージを受信しました",
|
"receive-text-title": "メッセージを受信",
|
||||||
"edit-paired-devices-title": "ペアリング設定",
|
"edit-paired-devices-title": "ペアリング設定",
|
||||||
"cancel": "キャンセル",
|
"cancel": "キャンセル",
|
||||||
"auto-accept-instructions-1": "「",
|
"auto-accept-instructions-1": "「",
|
||||||
|
@ -123,19 +123,19 @@
|
||||||
"file-other-description-image": "とその他1個の画像",
|
"file-other-description-image": "とその他1個の画像",
|
||||||
"temporary-public-room-title": "公開ルーム",
|
"temporary-public-room-title": "公開ルーム",
|
||||||
"base64-files": "ファイル",
|
"base64-files": "ファイル",
|
||||||
"has-sent": "が送信しました:",
|
"has-sent": "が送信:",
|
||||||
"file-other-description-file": "とその他1個のファイル",
|
"file-other-description-file": "とその他1個のファイル",
|
||||||
"close": "閉じる",
|
"close": "閉じる",
|
||||||
"system-language": "システム言語",
|
"system-language": "システムの言語",
|
||||||
"unpair": "ペアリング解除",
|
"unpair": "ペアリング解除",
|
||||||
"title-image": "画像",
|
"title-image": "画像",
|
||||||
"file-other-description-file-plural": "とその他{{count}}個のファイル",
|
"file-other-description-file-plural": "とその他{{count}}個のファイル",
|
||||||
"would-like-to-share": "が以下のファイルを共有しようとしています",
|
"would-like-to-share": "がこれを共有しています",
|
||||||
"send-message-to": "このデバイスにメッセージを送信:",
|
"send-message-to": "このデバイスにメッセージを送信:",
|
||||||
"language-selector-title": "言語設定",
|
"language-selector-title": "言語設定",
|
||||||
"pair": "ペアリング",
|
"pair": "ペアリング",
|
||||||
"hr-or": "または",
|
"hr-or": "または",
|
||||||
"scan-qr-code": "もしくはQRコードをスキャンしてください。",
|
"scan-qr-code": "QRコードをスキャンしてください。",
|
||||||
"input-key-on-this-device": "このコードを他のデバイスに入力するか",
|
"input-key-on-this-device": "このコードを他のデバイスに入力するか",
|
||||||
"download-again": "もう一度ダウンロードする",
|
"download-again": "もう一度ダウンロードする",
|
||||||
"accept": "承諾",
|
"accept": "承諾",
|
||||||
|
@ -162,20 +162,20 @@
|
||||||
"share-text-title": "テキストメッセージを共有します"
|
"share-text-title": "テキストメッセージを共有します"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"claim": "デバイス間のファイル共有を手軽に実現します",
|
"claim": "デバイス間でかんたんファイル共有",
|
||||||
"tweet_title": "PairDropのことをポストする",
|
"tweet_title": "PairDropについてポスト",
|
||||||
"close-about_aria-label": "PairDropについてを閉じる",
|
"close-about_aria-label": "PairDropについてを閉じる",
|
||||||
"buy-me-a-coffee_title": "コーヒーを一杯おごってください!",
|
"buy-me-a-coffee_title": "コーヒーを一杯おごってください!",
|
||||||
"github_title": "PairDrop on GitHub",
|
"github_title": "GitHub上のPairDropプロジェクト",
|
||||||
"faq_title": "FAQ",
|
"faq_title": "FAQ",
|
||||||
"mastodon_title": "MastodonにPairDropのことをトゥートする",
|
"mastodon_title": "MastodonでPairDropについてトゥート",
|
||||||
"bluesky_title": "BlueSkyでフォロー",
|
"bluesky_title": "BlueSkyでフォロー",
|
||||||
"custom_title": "フォロー",
|
"custom_title": "フォロー",
|
||||||
"privacypolicy_title": "プライバシーポリシーを開く"
|
"privacypolicy_title": "プライバシーポリシーを開く"
|
||||||
},
|
},
|
||||||
"document-titles": {
|
"document-titles": {
|
||||||
"file-transfer-requested": "ファイルの転送がリクエストされました",
|
"file-transfer-requested": "ファイル転送の要求があります",
|
||||||
"image-transfer-requested": "画像の転送がリクエストされました",
|
"image-transfer-requested": "画像の転送の要求があります",
|
||||||
"message-received-plural": "{{count}}個のメッセージを受信しました",
|
"message-received-plural": "{{count}}個のメッセージを受信しました",
|
||||||
"message-received": "メッセージを受信しました",
|
"message-received": "メッセージを受信しました",
|
||||||
"file-received": "ファイルを受信しました",
|
"file-received": "ファイルを受信しました",
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"background_color": "#efefef",
|
"background_color": "#efefef",
|
||||||
|
"start_url": "./",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"theme_color": "#3367d6",
|
"theme_color": "#3367d6",
|
||||||
"screenshots" : [
|
"screenshots" : [
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Localization {
|
||||||
Localization.defaultLocale = "en";
|
Localization.defaultLocale = "en";
|
||||||
Localization.supportedLocales = [
|
Localization.supportedLocales = [
|
||||||
"ar", "be", "bg", "ca", "cs", "da", "de", "en", "es", "et", "eu", "fa", "fr", "he", "hu", "id", "it", "ja",
|
"ar", "be", "bg", "ca", "cs", "da", "de", "en", "es", "et", "eu", "fa", "fr", "he", "hu", "id", "it", "ja",
|
||||||
"kn", "ko", "nb", "nn", "nl", "pl", "pt-BR", "ro", "ru", "sk", "ta", "tr", "uk", "zh-CN", "zh-HK", "zh-TW"
|
"kn", "ko", "nb", "nl", "nn", "pl", "pt-BR", "ro", "ru", "sk", "ta", "tr", "uk", "zh-CN", "zh-HK", "zh-TW"
|
||||||
];
|
];
|
||||||
Localization.supportedLocalesRtl = ["ar", "he"];
|
Localization.supportedLocalesRtl = ["ar", "he"];
|
||||||
|
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ class PeersManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onFilesSelected(message) {
|
async _onFilesSelected(message) {
|
||||||
let files = mime.addMissingMimeTypesToFiles(message.files);
|
let files = mime.addMissingMimeTypesToFiles([...message.files]);
|
||||||
await this.peers[message.to].requestFileTransfer(files);
|
await this.peers[message.to].requestFileTransfer(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,9 +1306,8 @@ class FileDigester {
|
||||||
const blob = new Blob(this._buffer)
|
const blob = new Blob(this._buffer)
|
||||||
this._buffer = null;
|
this._buffer = null;
|
||||||
this._callback(new File([blob], this._name, {
|
this._callback(new File([blob], this._name, {
|
||||||
type: this._mime,
|
type: this._mime || "application/octet-stream",
|
||||||
lastModified: new Date().getTime()
|
lastModified: new Date().getTime()
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -873,7 +873,9 @@ class ReceiveDialog extends Dialog {
|
||||||
|
|
||||||
const fileName = files[0].name;
|
const fileName = files[0].name;
|
||||||
const fileNameSplit = fileName.split('.');
|
const fileNameSplit = fileName.split('.');
|
||||||
const fileExtension = '.' + fileNameSplit[fileNameSplit.length - 1];
|
const fileExtension = fileNameSplit.length > 1
|
||||||
|
? '.' + fileNameSplit[fileNameSplit.length - 1]
|
||||||
|
: '';
|
||||||
this.$fileStem.innerText = fileName.substring(0, fileName.length - fileExtension.length);
|
this.$fileStem.innerText = fileName.substring(0, fileName.length - fileExtension.length);
|
||||||
this.$fileExtension.innerText = fileExtension;
|
this.$fileExtension.innerText = fileExtension;
|
||||||
this.$fileSize.innerText = this._formatFileSize(totalSize);
|
this.$fileSize.innerText = this._formatFileSize(totalSize);
|
||||||
|
@ -2402,7 +2404,7 @@ class Base64Dialog extends Dialog {
|
||||||
class AboutUI {
|
class AboutUI {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.$donationBtn = $('donation-btn');
|
this.$donationBtn = $('donation-btn');
|
||||||
this.$twitterBtn = $('twitter-btn');
|
this.$twitterBtn = $('x-twitter-btn');
|
||||||
this.$mastodonBtn = $('mastodon-btn');
|
this.$mastodonBtn = $('mastodon-btn');
|
||||||
this.$blueskyBtn = $('bluesky-btn');
|
this.$blueskyBtn = $('bluesky-btn');
|
||||||
this.$customBtn = $('custom-btn');
|
this.$customBtn = $('custom-btn');
|
||||||
|
|
|
@ -392,7 +392,8 @@ const mime = (() => {
|
||||||
"vob": "video/x-ms-vob",
|
"vob": "video/x-ms-vob",
|
||||||
"wmv": "video/x-ms-wmv",
|
"wmv": "video/x-ms-wmv",
|
||||||
"avi": "video/x-msvideo",
|
"avi": "video/x-msvideo",
|
||||||
"*": "video/x-sgi-movie"
|
"*": "video/x-sgi-movie",
|
||||||
|
"kdbx": "application/x-keepass2"
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -409,7 +410,7 @@ const mime = (() => {
|
||||||
// if filetype is empty guess via suffix otherwise leave unchanged
|
// if filetype is empty guess via suffix otherwise leave unchanged
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
if (!files[i].type) {
|
if (!files[i].type) {
|
||||||
files[i] = new File([files[i]], files[i].name, {type: mime.guessMimeByFilename(files[i].name) || ""});
|
files[i] = new File([files[i]], files[i].name, {type: mime.guessMimeByFilename(files[i].name) || "application/octet-stream"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files;
|
return files;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
const cacheVersion = 'v1.11.0';
|
const cacheVersion = 'v1.11.2';
|
||||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||||
const forceFetch = false; // FOR DEVELOPMENT: Set to true to always update assets instead of using cached versions
|
|
||||||
const relativePathsToCache = [
|
const relativePathsToCache = [
|
||||||
'./',
|
'./',
|
||||||
'index.html',
|
'index.html',
|
||||||
'manifest.json',
|
'manifest.json',
|
||||||
'styles/styles-main.css',
|
'styles/styles-main.css',
|
||||||
'styles/styles-deferred.css',
|
'styles/styles-deferred.css',
|
||||||
|
'scripts/browser-tabs-connector.js',
|
||||||
'scripts/localization.js',
|
'scripts/localization.js',
|
||||||
'scripts/main.js',
|
'scripts/main.js',
|
||||||
'scripts/network.js',
|
'scripts/network.js',
|
||||||
|
@ -28,14 +28,19 @@ const relativePathsToCache = [
|
||||||
'images/android-chrome-512x512.png',
|
'images/android-chrome-512x512.png',
|
||||||
'images/android-chrome-512x512-maskable.png',
|
'images/android-chrome-512x512-maskable.png',
|
||||||
'images/apple-touch-icon.png',
|
'images/apple-touch-icon.png',
|
||||||
|
'fonts/OpenSans/static/OpenSans-Medium.ttf',
|
||||||
'lang/ar.json',
|
'lang/ar.json',
|
||||||
'lang/be.json',
|
'lang/be.json',
|
||||||
|
'lang/bg.json',
|
||||||
'lang/ca.json',
|
'lang/ca.json',
|
||||||
'lang/cs.json',
|
'lang/cs.json',
|
||||||
'lang/da.json',
|
'lang/da.json',
|
||||||
'lang/de.json',
|
'lang/de.json',
|
||||||
'lang/en.json',
|
'lang/en.json',
|
||||||
'lang/es.json',
|
'lang/es.json',
|
||||||
|
'lang/et.json',
|
||||||
|
'lang/eu.json',
|
||||||
|
'lang/fa.json',
|
||||||
'lang/fr.json',
|
'lang/fr.json',
|
||||||
'lang/he.json',
|
'lang/he.json',
|
||||||
'lang/hu.json',
|
'lang/hu.json',
|
||||||
|
@ -43,15 +48,20 @@ const relativePathsToCache = [
|
||||||
'lang/it.json',
|
'lang/it.json',
|
||||||
'lang/ja.json',
|
'lang/ja.json',
|
||||||
'lang/kn.json',
|
'lang/kn.json',
|
||||||
|
'lang/ko.json',
|
||||||
'lang/nb.json',
|
'lang/nb.json',
|
||||||
'lang/nl.json',
|
'lang/nl.json',
|
||||||
|
'lang/nn.json',
|
||||||
'lang/pl.json',
|
'lang/pl.json',
|
||||||
'lang/pt-BR.json',
|
'lang/pt-BR.json',
|
||||||
'lang/ro.json',
|
'lang/ro.json',
|
||||||
'lang/ru.json',
|
'lang/ru.json',
|
||||||
|
'lang/sk.json',
|
||||||
|
'lang/ta.json',
|
||||||
'lang/tr.json',
|
'lang/tr.json',
|
||||||
'lang/uk.json',
|
'lang/uk.json',
|
||||||
'lang/zh-CN.json',
|
'lang/zh-CN.json',
|
||||||
|
'lang/zh-HK.json',
|
||||||
'lang/zh-TW.json'
|
'lang/zh-TW.json'
|
||||||
];
|
];
|
||||||
const relativePathsNotToCache = [
|
const relativePathsNotToCache = [
|
||||||
|
@ -59,14 +69,16 @@ const relativePathsNotToCache = [
|
||||||
]
|
]
|
||||||
|
|
||||||
self.addEventListener('install', function(event) {
|
self.addEventListener('install', function(event) {
|
||||||
// Perform install steps
|
// Perform install steps
|
||||||
|
console.log("Cache files for sw:", cacheVersion);
|
||||||
event.waitUntil(
|
event.waitUntil(
|
||||||
caches.open(cacheTitle)
|
caches.open(cacheTitle)
|
||||||
.then(function(cache) {
|
.then(function(cache) {
|
||||||
return cache
|
return cache
|
||||||
.addAll(relativePathsToCache)
|
.addAll(relativePathsToCache)
|
||||||
.then(_ => {
|
.then(_ => {
|
||||||
console.log('All files cached.');
|
console.log('All files cached for sw:', cacheVersion);
|
||||||
|
self.skipWaiting();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -76,20 +88,25 @@ self.addEventListener('install', function(event) {
|
||||||
const fromNetwork = (request, timeout) =>
|
const fromNetwork = (request, timeout) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
const timeoutId = setTimeout(reject, timeout);
|
const timeoutId = setTimeout(reject, timeout);
|
||||||
fetch(request)
|
fetch(request, {cache: "no-store"})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
if (response.redirected) {
|
||||||
|
throw new Error("Fetch is redirect. Abort usage and cache!");
|
||||||
|
}
|
||||||
|
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
resolve(response);
|
resolve(response);
|
||||||
|
|
||||||
|
// Prevent requests that are in relativePathsNotToCache from being cached
|
||||||
if (doNotCacheRequest(request)) return;
|
if (doNotCacheRequest(request)) return;
|
||||||
|
|
||||||
update(request)
|
updateCache(request)
|
||||||
.then(() => console.log("Cache successfully updated for", request.url))
|
.then(() => console.log("Cache successfully updated for", request.url))
|
||||||
.catch(reason => console.log("Cache could not be updated for", request.url, "Reason:", reason));
|
.catch(err => console.log("Cache could not be updated for", request.url, err));
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// Handle any errors that occurred during the fetch
|
// Handle any errors that occurred during the fetch
|
||||||
console.error(`Could not fetch ${request.url}. Are you online?`);
|
console.error(`Could not fetch ${request.url}.`);
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -111,16 +128,16 @@ const doNotCacheRequest = request => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// cache the current page to make it available for offline
|
// cache the current page to make it available for offline
|
||||||
const update = request => new Promise((resolve, reject) => {
|
const updateCache = request => new Promise((resolve, reject) => {
|
||||||
if (doNotCacheRequest(request)) {
|
|
||||||
reject("Url is specifically prevented from being cached in the serviceworker.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
caches
|
caches
|
||||||
.open(cacheTitle)
|
.open(cacheTitle)
|
||||||
.then(cache =>
|
.then(cache =>
|
||||||
fetch(request, {cache: "no-store"})
|
fetch(request, {cache: "no-store"})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
if (response.redirected) {
|
||||||
|
throw new Error("Fetch is redirect. Abort usage and cache!");
|
||||||
|
}
|
||||||
|
|
||||||
cache
|
cache
|
||||||
.put(request, response)
|
.put(request, response)
|
||||||
.then(() => resolve());
|
.then(() => resolve());
|
||||||
|
@ -129,11 +146,19 @@ const update = request => new Promise((resolve, reject) => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// general strategy when making a request (eg if online try to fetch it
|
// general strategy when making a request:
|
||||||
// from cache, if something fails fetch from network. Update cache everytime files are fetched.
|
// 1. Try to retrieve file from cache
|
||||||
// This way files should only be fetched if cacheVersion is changed
|
// 2. If cache is not available: Fetch from network and update cache.
|
||||||
|
// This way, cached files are only updated if the cacheVersion is changed
|
||||||
self.addEventListener('fetch', function(event) {
|
self.addEventListener('fetch', function(event) {
|
||||||
if (event.request.method === "POST") {
|
const swOrigin = new URL(self.location.href).origin;
|
||||||
|
const requestOrigin = new URL(event.request.url).origin;
|
||||||
|
|
||||||
|
if (swOrigin !== requestOrigin) {
|
||||||
|
// Do not handle requests from other origin
|
||||||
|
event.respondWith(fetch(event.request));
|
||||||
|
}
|
||||||
|
else if (event.request.method === "POST") {
|
||||||
// Requests related to Web Share Target.
|
// Requests related to Web Share Target.
|
||||||
event.respondWith((async () => {
|
event.respondWith((async () => {
|
||||||
const share_url = await evaluateRequestData(event.request);
|
const share_url = await evaluateRequestData(event.request);
|
||||||
|
@ -141,39 +166,48 @@ self.addEventListener('fetch', function(event) {
|
||||||
})());
|
})());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Regular requests not related to Web Share Target.
|
// Regular requests not related to Web Share Target:
|
||||||
if (forceFetch) {
|
// If request is excluded from cache -> respondWith fromNetwork
|
||||||
event.respondWith(fromNetwork(event.request, 10000));
|
// else -> try fromCache first
|
||||||
}
|
event.respondWith(
|
||||||
else {
|
doNotCacheRequest(event.request)
|
||||||
event.respondWith(
|
? fromNetwork(event.request, 10000)
|
||||||
fromCache(event.request)
|
: fromCache(event.request)
|
||||||
.then(rsp => {
|
.then(rsp => {
|
||||||
// if fromCache resolves to undefined fetch from network instead
|
// if fromCache resolves to undefined fetch from network instead
|
||||||
return rsp || fromNetwork(event.request, 10000);
|
if (!rsp) {
|
||||||
|
throw new Error("No match found.");
|
||||||
|
}
|
||||||
|
return rsp;
|
||||||
})
|
})
|
||||||
);
|
.catch(error => {
|
||||||
}
|
console.error("Could not retrieve request from cache:", event.request.url, error);
|
||||||
|
return fromNetwork(event.request, 10000);
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// on activation, we clean up the previously registered service workers
|
// on activation, we clean up the previously registered service workers
|
||||||
self.addEventListener('activate', evt => {
|
self.addEventListener('activate', evt => {
|
||||||
return evt.waitUntil(
|
console.log("Activate sw:", cacheVersion);
|
||||||
caches.keys()
|
evt.waitUntil(clients.claim());
|
||||||
.then(cacheNames => {
|
return evt.waitUntil(
|
||||||
return Promise.all(
|
caches
|
||||||
cacheNames.map(cacheName => {
|
.keys()
|
||||||
if (cacheName !== cacheTitle) {
|
.then(cacheNames => {
|
||||||
return caches.delete(cacheName);
|
return Promise.all(
|
||||||
}
|
cacheNames.map(cacheName => {
|
||||||
})
|
if (cacheName !== cacheTitle) {
|
||||||
);
|
console.log("Delete cache:", cacheName);
|
||||||
})
|
return caches.delete(cacheName);
|
||||||
)
|
}
|
||||||
}
|
})
|
||||||
);
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
const evaluateRequestData = function (request) {
|
const evaluateRequestData = function (request) {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
|
|
Loading…
Reference in New Issue