Merge pull request #206 from schlagmichdoch/fix-send-text-dialog-cut-off
Make style more airy; Dark mode real black; Recreate Icons
|
@ -85,7 +85,8 @@ Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop)
|
||||||
* Lots of stability fixes (Thanks [@MWY001](https://github.com/MWY001) [@skiby7](https://github.com/skiby7) and [@willstott101](https://github.com/willstott101))
|
* Lots of stability fixes (Thanks [@MWY001](https://github.com/MWY001) [@skiby7](https://github.com/skiby7) and [@willstott101](https://github.com/willstott101))
|
||||||
* To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558)
|
* To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558)
|
||||||
* When hosting PairDrop yourself you can [set your own STUN/TURN servers](/docs/host-your-own.md#specify-stunturn-servers)
|
* When hosting PairDrop yourself you can [set your own STUN/TURN servers](/docs/host-your-own.md#specify-stunturn-servers)
|
||||||
* Built-in translations
|
* Built-in translations via [Weblate](https://hosted.weblate.org/engage/pairdrop/)
|
||||||
|
* Airy design (Thanks [@Avieshek](https://linktr.ee/avieshek/))
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
93
public/fonts/OpenSans/OFL.txt
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
BIN
public/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf
Normal file
BIN
public/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf
Normal file
100
public/fonts/OpenSans/README.txt
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
Open Sans Variable Font
|
||||||
|
=======================
|
||||||
|
|
||||||
|
This download contains Open Sans as both variable fonts and static fonts.
|
||||||
|
|
||||||
|
Open Sans is a variable font with these axes:
|
||||||
|
wdth
|
||||||
|
wght
|
||||||
|
|
||||||
|
This means all the styles are contained in these files:
|
||||||
|
OpenSans-VariableFont_wdth,wght.ttf
|
||||||
|
OpenSans-Italic-VariableFont_wdth,wght.ttf
|
||||||
|
|
||||||
|
If your app fully supports variable fonts, you can now pick intermediate styles
|
||||||
|
that aren’t available as static fonts. Not all apps support variable fonts, and
|
||||||
|
in those cases you can use the static font files for Open Sans:
|
||||||
|
static/OpenSans_Condensed-Light.ttf
|
||||||
|
static/OpenSans_Condensed-Regular.ttf
|
||||||
|
static/OpenSans_Condensed-Medium.ttf
|
||||||
|
static/OpenSans_Condensed-SemiBold.ttf
|
||||||
|
static/OpenSans_Condensed-Bold.ttf
|
||||||
|
static/OpenSans_Condensed-ExtraBold.ttf
|
||||||
|
static/OpenSans_SemiCondensed-Light.ttf
|
||||||
|
static/OpenSans_SemiCondensed-Regular.ttf
|
||||||
|
static/OpenSans_SemiCondensed-Medium.ttf
|
||||||
|
static/OpenSans_SemiCondensed-SemiBold.ttf
|
||||||
|
static/OpenSans_SemiCondensed-Bold.ttf
|
||||||
|
static/OpenSans_SemiCondensed-ExtraBold.ttf
|
||||||
|
static/OpenSans-Light.ttf
|
||||||
|
static/OpenSans-Regular.ttf
|
||||||
|
static/OpenSans-Medium.ttf
|
||||||
|
static/OpenSans-SemiBold.ttf
|
||||||
|
static/OpenSans-Bold.ttf
|
||||||
|
static/OpenSans-ExtraBold.ttf
|
||||||
|
static/OpenSans_Condensed-LightItalic.ttf
|
||||||
|
static/OpenSans_Condensed-Italic.ttf
|
||||||
|
static/OpenSans_Condensed-MediumItalic.ttf
|
||||||
|
static/OpenSans_Condensed-SemiBoldItalic.ttf
|
||||||
|
static/OpenSans_Condensed-BoldItalic.ttf
|
||||||
|
static/OpenSans_Condensed-ExtraBoldItalic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-LightItalic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-Italic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-MediumItalic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-SemiBoldItalic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-BoldItalic.ttf
|
||||||
|
static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf
|
||||||
|
static/OpenSans-LightItalic.ttf
|
||||||
|
static/OpenSans-Italic.ttf
|
||||||
|
static/OpenSans-MediumItalic.ttf
|
||||||
|
static/OpenSans-SemiBoldItalic.ttf
|
||||||
|
static/OpenSans-BoldItalic.ttf
|
||||||
|
static/OpenSans-ExtraBoldItalic.ttf
|
||||||
|
|
||||||
|
Get started
|
||||||
|
-----------
|
||||||
|
|
||||||
|
1. Install the font files you want to use
|
||||||
|
|
||||||
|
2. Use your app's font picker to view the font family and all the
|
||||||
|
available styles
|
||||||
|
|
||||||
|
Learn more about variable fonts
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
||||||
|
https://variablefonts.typenetwork.com
|
||||||
|
https://medium.com/variable-fonts
|
||||||
|
|
||||||
|
In desktop apps
|
||||||
|
|
||||||
|
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
||||||
|
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
||||||
|
|
||||||
|
Online
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/getting_started
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
||||||
|
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
||||||
|
|
||||||
|
Installing fonts
|
||||||
|
|
||||||
|
MacOS: https://support.apple.com/en-us/HT201749
|
||||||
|
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
||||||
|
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
||||||
|
|
||||||
|
Android Apps
|
||||||
|
|
||||||
|
https://developers.google.com/fonts/docs/android
|
||||||
|
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Please read the full license text (OFL.txt) to understand the permissions,
|
||||||
|
restrictions and requirements for usage, redistribution, and modification.
|
||||||
|
|
||||||
|
You can use them in your products & projects – print or digital,
|
||||||
|
commercial or otherwise.
|
||||||
|
|
||||||
|
This isn't legal advice, please consider consulting a lawyer and see the full
|
||||||
|
license for all details.
|
BIN
public/fonts/OpenSans/static/OpenSans-Bold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-BoldItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-ExtraBold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-ExtraBoldItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-Italic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-Light.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-LightItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-Medium.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-MediumItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-Regular.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-SemiBold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans-SemiBoldItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-Bold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-BoldItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-Italic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-Light.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-LightItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-Medium.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-MediumItalic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-Regular.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_Condensed-SemiBold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-Bold.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-Italic.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-Light.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-Medium.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-Regular.ttf
Normal file
BIN
public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBold.ttf
Normal file
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 31 KiB |
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<!-- Web App Config -->
|
<!-- Web App Config -->
|
||||||
<title>PairDrop</title>
|
<title>PairDrop | Transfer Files Cross-Platform. No Setup, No Signup.</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="theme-color" content="#3367d6">
|
<meta name="theme-color" content="#3367d6">
|
||||||
<meta name="color-scheme" content="dark light">
|
<meta name="color-scheme" content="dark light">
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
<use xlink:href="#public-room-icon"></use>
|
<use xlink:href="#public-room-icon"></use>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div id="cancel-paste-mode" class="button" data-i18n-key="header.cancel-paste-mode" data-i18n-attrs="text" hidden></div>
|
<div id="cancel-paste-mode" class="btn" data-i18n-key="header.cancel-paste-mode" data-i18n-attrs="text" hidden></div>
|
||||||
</header>
|
</header>
|
||||||
<!-- Center -->
|
<!-- Center -->
|
||||||
<div id="center" class="opacity-0">
|
<div id="center" class="opacity-0">
|
||||||
|
@ -118,7 +118,13 @@
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<footer class="column opacity-0">
|
<footer class="column opacity-0">
|
||||||
<svg class="icon logo">
|
<svg class="icon logo">
|
||||||
<use xlink:href="#wifi-tethering"></use>
|
<defs>
|
||||||
|
<linearGradient id="primaryGradient" gradientTransform="rotate(90)">
|
||||||
|
<stop offset="0%" class="start-color" />
|
||||||
|
<stop offset="100%" class="stop-color" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<use xlink:href="#wifi-tethering" style="fill: url(#primaryGradient);"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="known-as-wrapper">
|
<div class="known-as-wrapper">
|
||||||
|
@ -133,9 +139,9 @@
|
||||||
<span data-i18n-key="footer.discovery" data-i18n-attrs="text"></span>
|
<span data-i18n-key="footer.discovery" data-i18n-attrs="text"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center">
|
||||||
<span class="badge badge-room-ip" data-i18n-key="footer.on-this-network" data-i18n-attrs="text title"></span>
|
<span class="badge badge-gradient badge-room-ip" data-i18n-key="footer.on-this-network" data-i18n-attrs="text title"></span>
|
||||||
<span class="badge badge-room-secret pointer" data-i18n-key="footer.paired-devices" data-i18n-attrs="text title" hidden></span>
|
<span class="badge badge-gradient badge-room-secret pointer" data-i18n-key="footer.paired-devices" data-i18n-attrs="text title" hidden></span>
|
||||||
<span class="badge badge-room-public-id pointer" data-i18n-key="footer.public-room-devices" data-i18n-attrs="title" hidden>in room IAIAI</span>
|
<span class="badge badge-gradient badge-room-public-id pointer" data-i18n-key="footer.public-room-devices" data-i18n-attrs="title" hidden>in room IAIAI</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -148,78 +154,78 @@
|
||||||
<h2 class="center" data-i18n-key="dialogs.language-selector-title" data-i18n-attrs="text"></h2>
|
<h2 class="center" data-i18n-key="dialogs.language-selector-title" data-i18n-attrs="text"></h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="language-buttons">
|
<div class="language-buttons">
|
||||||
<button class="button fw" data-i18n-key="dialogs.system-language" data-i18n-attrs="text"></button>
|
<button class="btn fw" data-i18n-key="dialogs.system-language" data-i18n-attrs="text"></button>
|
||||||
<button class="button fw" value="ar">
|
<button class="btn fw" value="ar">
|
||||||
<span>العربية</span>
|
<span>العربية</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Arabic)</span>
|
<span>(Arabic)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="de">
|
<button class="btn fw" value="de">
|
||||||
<span>Deutsch</span>
|
<span>Deutsch</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(German)</span>
|
<span>(German)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="en">
|
<button class="btn fw" value="en">
|
||||||
<span>English</span>
|
<span>English</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="es">
|
<button class="btn fw" value="es">
|
||||||
<span>Español</span>
|
<span>Español</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Spanish)</span>
|
<span>(Spanish)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="fr">
|
<button class="btn fw" value="fr">
|
||||||
<span>Français</span>
|
<span>Français</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(French)</span>
|
<span>(French)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="id">
|
<button class="btn fw" value="id">
|
||||||
<span>Bahasa Indonesia</span>
|
<span>Bahasa Indonesia</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Indonesian)</span>
|
<span>(Indonesian)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="it">
|
<button class="btn fw" value="it">
|
||||||
<span>Italiano</span>
|
<span>Italiano</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Italian)</span>
|
<span>(Italian)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="nl">
|
<button class="btn fw" value="nl">
|
||||||
<span>Nederlands</span>
|
<span>Nederlands</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Dutch)</span>
|
<span>(Dutch)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="nb">
|
<button class="btn fw" value="nb">
|
||||||
<span>Norsk</span>
|
<span>Norsk</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Norwegian)</span>
|
<span>(Norwegian)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="ro">
|
<button class="btn fw" value="ro">
|
||||||
<span>Română</span>
|
<span>Română</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Romanian)</span>
|
<span>(Romanian)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="ru">
|
<button class="btn fw" value="ru">
|
||||||
<span>Русский язык</span>
|
<span>Русский язык</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Russian)</span>
|
<span>(Russian)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="tr">
|
<button class="btn fw" value="tr">
|
||||||
<span>Türkçe</span>
|
<span>Türkçe</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Turkish)</span>
|
<span>(Turkish)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="zh-CN">
|
<button class="btn fw" value="zh-CN">
|
||||||
<span>中文</span>
|
<span>中文</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Chinese)</span>
|
<span>(Chinese)</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button fw" value="ja">
|
<button class="btn fw" value="ja">
|
||||||
<span>日本語</span>
|
<span>日本語</span>
|
||||||
<span>-</span>
|
<span>-</span>
|
||||||
<span>(Japanese)</span>
|
<span>(Japanese)</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="center row-reverse button-row">
|
<div class="center row-reverse button-row">
|
||||||
<button class="button" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -249,7 +255,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center">
|
||||||
<div class="column">
|
<div class="column fw">
|
||||||
<div class="input-key-container six-chars" dir="ltr">
|
<div class="input-key-container six-chars" dir="ltr">
|
||||||
<input type="tel" class="textarea center" aria-label="pair-key-char-1" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" autofocus contenteditable placeholder disabled>
|
<input type="tel" class="textarea center" aria-label="pair-key-char-1" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" autofocus contenteditable placeholder disabled>
|
||||||
<input type="tel" class="textarea center" aria-label="pair-key-char-2" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" contenteditable placeholder disabled>
|
<input type="tel" class="textarea center" aria-label="pair-key-char-2" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" contenteditable placeholder disabled>
|
||||||
|
@ -262,8 +268,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-row row-reverse">
|
<div class="button-row row-reverse">
|
||||||
<button class="button" type="submit" data-i18n-key="dialogs.pair" data-i18n-attrs="text" disabled></button>
|
<button class="btn btn-rounded btn-grey" type="submit" data-i18n-key="dialogs.pair" data-i18n-attrs="text" disabled></button>
|
||||||
<button class="button" type="button" data-i18n-key="dialogs.cancel" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" type="button" data-i18n-key="dialogs.cancel" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -286,7 +292,7 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="center row-reverse button-row">
|
<div class="center row-reverse button-row">
|
||||||
<button class="button" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -319,7 +325,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center">
|
||||||
<div class="column">
|
<div class="column fw">
|
||||||
<div class="input-key-container" dir="ltr">
|
<div class="input-key-container" dir="ltr">
|
||||||
<input type="text" class="textarea center" aria-label="room-id-char-1" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" autofocus contenteditable placeholder disabled>
|
<input type="text" class="textarea center" aria-label="room-id-char-1" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" autofocus contenteditable placeholder disabled>
|
||||||
<input type="text" class="textarea center" aria-label="room-id-char-2" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" contenteditable placeholder disabled>
|
<input type="text" class="textarea center" aria-label="room-id-char-2" maxlength="1" autocorrect="off" autocomplete="off" autocapitalize="none" spellcheck="false" contenteditable placeholder disabled>
|
||||||
|
@ -331,9 +337,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="center row-reverse button-row">
|
<div class="center row-reverse button-row">
|
||||||
<button class="button" type="submit" data-i18n-key="dialogs.join" data-i18n-attrs="text" disabled></button>
|
<button class="btn btn-rounded btn-grey" type="submit" data-i18n-key="dialogs.join" data-i18n-attrs="text" disabled></button>
|
||||||
<button class="button" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" type="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
||||||
<button class="button leave-room" type="button" data-i18n-key="dialogs.leave" data-i18n-attrs="text"></button>
|
<button class="btn btn-rounded btn-grey leave-room" type="button" data-i18n-key="dialogs.leave" data-i18n-attrs="text"></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -348,10 +354,10 @@
|
||||||
<h2 class="center"></h2>
|
<h2 class="center"></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center p1">
|
||||||
<div class="column center file-description">
|
<div class="column center file-description">
|
||||||
<div>
|
<div>
|
||||||
<span class="display-name badge"></span>
|
<span class="display-name badge badge-gradient"></span>
|
||||||
<span data-i18n-key="dialogs.would-like-to-share" data-i18n-attrs="text"></span>
|
<span data-i18n-key="dialogs.would-like-to-share" data-i18n-attrs="text"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row file-name">
|
<div class="row file-name">
|
||||||
|
@ -365,8 +371,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="center file-preview"></div>
|
<div class="center file-preview"></div>
|
||||||
<div class="row-reverse center button-row">
|
<div class="row-reverse center button-row">
|
||||||
<button id="accept-request" class="button" title="ENTER" data-i18n-key="dialogs.accept" data-i18n-attrs="text" autofocus></button>
|
<button id="accept-request" class="btn btn-rounded btn-grey" title="ENTER" data-i18n-key="dialogs.accept" data-i18n-attrs="text" autofocus></button>
|
||||||
<button id="decline-request" class="button" title="ESCAPE" data-i18n-key="dialogs.decline" data-i18n-attrs="text"></button>
|
<button id="decline-request" class="btn btn-rounded btn-grey" title="ESCAPE" data-i18n-key="dialogs.decline" data-i18n-attrs="text"></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -380,10 +386,10 @@
|
||||||
<h2 class="center"></h2>
|
<h2 class="center"></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center p1">
|
||||||
<div class="column center file-description">
|
<div class="column center file-description">
|
||||||
<div>
|
<div>
|
||||||
<span class="display-name badge"></span>
|
<span class="display-name badge badge-gradient"></span>
|
||||||
<span data-i18n-key="dialogs.has-sent" data-i18n-attrs="text"></span>
|
<span data-i18n-key="dialogs.has-sent" data-i18n-attrs="text"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row file-name">
|
<div class="row file-name">
|
||||||
|
@ -397,9 +403,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="center file-preview"></div>
|
<div class="center file-preview"></div>
|
||||||
<div class="row-reverse center button-row">
|
<div class="row-reverse center button-row">
|
||||||
<button id="share-btn" class="button" data-i18n-key="dialogs.share" data-i18n-attrs="text" hidden></button>
|
<button id="share-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.share" data-i18n-attrs="text" hidden></button>
|
||||||
<button id="download-btn" class="button" data-i18n-key="dialogs.download" data-i18n-attrs="text" autofocus></button>
|
<button id="download-btn" class="btn btn-rounded btn-grey" data-i18n-key="dialogs.download" data-i18n-attrs="text" autofocus></button>
|
||||||
<button class="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -414,22 +420,22 @@
|
||||||
<h2 class="center" data-i18n-key="dialogs.send-message-title" data-i18n-attrs="text"></h2>
|
<h2 class="center" data-i18n-key="dialogs.send-message-title" data-i18n-attrs="text"></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center display-name-wrapper">
|
<div class="row center p1 display-name-wrapper">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<span data-i18n-key="dialogs.send-message-to" data-i18n-attrs="text"></span>
|
<span data-i18n-key="dialogs.send-message-to" data-i18n-attrs="text"></span>
|
||||||
<span class="display-name badge"></span>
|
<span class="display-name badge badge-gradient"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row p1">
|
||||||
<div class="column fw">
|
<div class="column fw">
|
||||||
<div id="text-input" class="textarea" role="textbox" data-i18n-key="dialogs.message" data-i18n-attrs="title" autocapitalize="none" spellcheck="false" autofocus contenteditable></div>
|
<div id="text-input" class="fw textarea" role="textbox" data-i18n-key="dialogs.message" data-i18n-attrs="title placeholder" autofocus contenteditable></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-row row-reverse">
|
<div class="button-row row-reverse">
|
||||||
<button class="button" type="submit" title="CTRL/⌘ + ENTER" data-i18n-key="dialogs.send" data-i18n-attrs="text" disabled></button>
|
<button class="btn btn-rounded btn-grey" type="submit" title="CTRL/⌘ + ENTER" data-i18n-key="dialogs.send" data-i18n-attrs="text" disabled></button>
|
||||||
<button class="button" type="button" title="ESCAPE" data-i18n-key="dialogs.cancel" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" type="button" title="ESCAPE" data-i18n-key="dialogs.cancel" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -442,20 +448,20 @@
|
||||||
<div class="row center">
|
<div class="row center">
|
||||||
<h2 class="text-center" data-i18n-key="dialogs.receive-text-title" data-i18n-attrs="text"></h2>
|
<h2 class="text-center" data-i18n-key="dialogs.receive-text-title" data-i18n-attrs="text"></h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center p1 display-name-wrapper">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<span class="display-name badge"></span>
|
<span class="display-name badge badge-gradient"></span>
|
||||||
<span data-i18n-key="dialogs.has-sent" data-i18n-attrs="text"></span>
|
<span data-i18n-key="dialogs.has-sent" data-i18n-attrs="text"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row center">
|
<div class="row center p1">
|
||||||
<div class="column fw">
|
<div class="column fw">
|
||||||
<div id="text" class="textarea fw"></div>
|
<div id="text" class="textarea"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-reverse center button-row">
|
<div class="row-reverse center button-row">
|
||||||
<button id="copy" class="button" title="CTRL/⌘ + C" data-i18n-key="dialogs.copy" data-i18n-attrs="text"></button>
|
<button id="copy" class="btn btn-rounded btn-grey" title="CTRL/⌘ + C" data-i18n-key="dialogs.copy" data-i18n-attrs="text"></button>
|
||||||
<button id="close" class="button" title="ESCAPE" data-i18n-key="dialogs.close" data-i18n-attrs="text"></button>
|
<button id="close" class="btn btn-rounded btn-grey" title="ESCAPE" data-i18n-key="dialogs.close" data-i18n-attrs="text"></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
@ -464,10 +470,10 @@
|
||||||
<x-dialog id="base64-paste-dialog">
|
<x-dialog id="base64-paste-dialog">
|
||||||
<x-background class="full center">
|
<x-background class="full center">
|
||||||
<x-paper shadow="2">
|
<x-paper shadow="2">
|
||||||
<button class="button center" id="base64-paste-btn" title="Paste"></button>
|
<button class="btn btn-rounded btn-grey center" id="base64-paste-btn" title="Paste"></button>
|
||||||
<div class="textarea" placeholder="Paste here to send files" title="CMD/⌘ + V" contenteditable hidden></div>
|
<div class="textarea" placeholder="Paste here to send files" title="CMD/⌘ + V" contenteditable hidden></div>
|
||||||
<div class="row-reverse center button-row">
|
<div class="row-reverse center button-row">
|
||||||
<button class="button" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
<button class="btn btn-rounded btn-grey" data-i18n-key="dialogs.close" data-i18n-attrs="text" close></button>
|
||||||
</div>
|
</div>
|
||||||
</x-paper>
|
</x-paper>
|
||||||
</x-background>
|
</x-background>
|
||||||
|
|
|
@ -70,8 +70,9 @@
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"send-message-title": "Send Message",
|
"send-message-title": "Send Message",
|
||||||
"send-message-to": "Send a Message to",
|
"send-message-to": "To:",
|
||||||
"message_title": "Insert message to send",
|
"message_title": "Insert message to send",
|
||||||
|
"message_placeholder": "Text",
|
||||||
"send": "Send",
|
"send": "Send",
|
||||||
"receive-text-title": "Message Received",
|
"receive-text-title": "Message Received",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
{
|
{
|
||||||
"name": "PairDrop",
|
"name": "PairDrop",
|
||||||
"short_name": "PairDrop",
|
"short_name": "PairDrop",
|
||||||
"icons": [{
|
"icons": [
|
||||||
|
{
|
||||||
"src": "images/android-chrome-192x192.png",
|
"src": "images/android-chrome-192x192.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"src": "images/android-chrome-512x512.png",
|
"src": "images/android-chrome-512x512.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png"
|
"type": "image/png"
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"src": "images/android-chrome-192x192-maskable.png",
|
"src": "images/android-chrome-192x192-maskable.png",
|
||||||
"sizes": "192x192",
|
"sizes": "192x192",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},{
|
},
|
||||||
|
{
|
||||||
"src": "images/android-chrome-512x512-maskable.png",
|
"src": "images/android-chrome-512x512-maskable.png",
|
||||||
"sizes": "512x512",
|
"sizes": "512x512",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"purpose": "maskable"
|
"purpose": "maskable"
|
||||||
},{
|
}
|
||||||
"src": "images/favicon-96x96.png",
|
],
|
||||||
"sizes": "96x96",
|
|
||||||
"type": "image/png"
|
|
||||||
}],
|
|
||||||
"background_color": "#efefef",
|
"background_color": "#efefef",
|
||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
"scope": "/",
|
"scope": "/",
|
||||||
|
|
60
public/scripts/browser-tabs-connector.js
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
class BrowserTabsConnector {
|
||||||
|
constructor() {
|
||||||
|
this.bc = new BroadcastChannel('pairdrop');
|
||||||
|
this.bc.addEventListener('message', e => this._onMessage(e));
|
||||||
|
Events.on('broadcast-send', e => this._broadcastSend(e.detail));
|
||||||
|
}
|
||||||
|
|
||||||
|
_broadcastSend(message) {
|
||||||
|
this.bc.postMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onMessage(e) {
|
||||||
|
console.log('Broadcast:', e.data)
|
||||||
|
switch (e.data.type) {
|
||||||
|
case 'self-display-name-changed':
|
||||||
|
Events.fire('self-display-name-changed', e.data.detail);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static peerIsSameBrowser(peerId) {
|
||||||
|
let peerIdsBrowser = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
||||||
|
return peerIdsBrowser
|
||||||
|
? peerIdsBrowser.indexOf(peerId) !== -1
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async addPeerIdToLocalStorage() {
|
||||||
|
const peerId = sessionStorage.getItem("peer_id");
|
||||||
|
if (!peerId) return false;
|
||||||
|
|
||||||
|
let peerIdsBrowser = [];
|
||||||
|
let peerIdsBrowserOld = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
||||||
|
|
||||||
|
if (peerIdsBrowserOld) peerIdsBrowser.push(...peerIdsBrowserOld);
|
||||||
|
peerIdsBrowser.push(peerId);
|
||||||
|
peerIdsBrowser = peerIdsBrowser.filter(onlyUnique);
|
||||||
|
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
||||||
|
|
||||||
|
return peerIdsBrowser;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async removePeerIdFromLocalStorage(peerId) {
|
||||||
|
let peerIdsBrowser = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
||||||
|
const index = peerIdsBrowser.indexOf(peerId);
|
||||||
|
peerIdsBrowser.splice(index, 1);
|
||||||
|
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
||||||
|
return peerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static async removeOtherPeerIdsFromLocalStorage() {
|
||||||
|
const peerId = sessionStorage.getItem("peer_id");
|
||||||
|
if (!peerId) return false;
|
||||||
|
|
||||||
|
let peerIdsBrowser = [peerId];
|
||||||
|
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
||||||
|
return peerIdsBrowser;
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ class PairDrop {
|
||||||
registerServiceWorker() {
|
registerServiceWorker() {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker
|
navigator.serviceWorker
|
||||||
.register('/service-worker.js')
|
.register('service-worker.js')
|
||||||
.then(serviceWorker => {
|
.then(serviceWorker => {
|
||||||
console.log('Service Worker registered');
|
console.log('Service Worker registered');
|
||||||
window.serviceWorker = serviceWorker
|
window.serviceWorker = serviceWorker
|
||||||
|
@ -99,6 +99,7 @@ class PairDrop {
|
||||||
"styles/deferred-styles.css"
|
"styles/deferred-styles.css"
|
||||||
];
|
];
|
||||||
this.deferredScripts = [
|
this.deferredScripts = [
|
||||||
|
"scripts/browser-tabs-connector.js",
|
||||||
"scripts/util.js",
|
"scripts/util.js",
|
||||||
"scripts/network.js",
|
"scripts/network.js",
|
||||||
"scripts/ui.js",
|
"scripts/ui.js",
|
||||||
|
|
|
@ -271,8 +271,8 @@ class BackgroundCanvas {
|
||||||
drawCircle(ctx, radius) {
|
drawCircle(ctx, radius) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
let opacity = Math.max(0, 0.3 * (1 - 1 * radius / Math.max(this.w, this.h)));
|
let opacity = Math.max(0, 0.3 * (1 - 1.2 * radius / Math.max(this.w, this.h)));
|
||||||
ctx.strokeStyle = `rgba(128, 128, 128, ${opacity})`;
|
ctx.strokeStyle = `rgba(165, 165, 165, ${opacity})`;
|
||||||
ctx.arc(this.x0, this.y0, radius, 0, 2 * Math.PI);
|
ctx.arc(this.x0, this.y0, radius, 0, 2 * Math.PI);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,6 +280,8 @@ class PeersUI {
|
||||||
|
|
||||||
class PeerUI {
|
class PeerUI {
|
||||||
|
|
||||||
|
static _badgeClassNames = ["badge-room-ip", "badge-room-secret", "badge-room-public-id"];
|
||||||
|
|
||||||
constructor(peer, connectionHash) {
|
constructor(peer, connectionHash) {
|
||||||
this.$xInstructions = $$('x-instructions');
|
this.$xInstructions = $$('x-instructions');
|
||||||
this.$xPeers = $$('x-peers');
|
this.$xPeers = $$('x-peers');
|
||||||
|
@ -330,14 +332,12 @@ class PeerUI {
|
||||||
<div class="name font-subheading"></div>
|
<div class="name font-subheading"></div>
|
||||||
<div class="device-name font-body2"></div>
|
<div class="device-name font-body2"></div>
|
||||||
<div class="status font-body2"></div>
|
<div class="status font-body2"></div>
|
||||||
<span class="connection-hash font-body2" dir="ltr" title="${ Localization.getTranslation("peer-ui.connection-hash") }"></span>
|
|
||||||
</div>
|
</div>
|
||||||
</label>`;
|
</label>`;
|
||||||
|
|
||||||
this.$el.querySelector('svg use').setAttribute('xlink:href', this._icon());
|
this.$el.querySelector('svg use').setAttribute('xlink:href', this._icon());
|
||||||
this.$el.querySelector('.name').textContent = this._displayName();
|
this.$el.querySelector('.name').textContent = this._displayName();
|
||||||
this.$el.querySelector('.device-name').textContent = this._deviceName();
|
this.$el.querySelector('.device-name').textContent = this._deviceName();
|
||||||
this.$el.querySelector('.connection-hash').textContent = this._connectionHash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addTypesToClassList() {
|
addTypesToClassList() {
|
||||||
|
@ -569,7 +569,7 @@ class Dialog {
|
||||||
document.activeElement.blur();
|
document.activeElement.blur();
|
||||||
window.blur();
|
window.blur();
|
||||||
}
|
}
|
||||||
document.title = 'PairDrop';
|
document.title = 'PairDrop | Transfer Files Cross-Platform. No Setup, No Signup.';
|
||||||
changeFavicon("images/favicon-96x96.png");
|
changeFavicon("images/favicon-96x96.png");
|
||||||
this.correspondingPeerId = undefined;
|
this.correspondingPeerId = undefined;
|
||||||
}
|
}
|
||||||
|
@ -1187,8 +1187,8 @@ class PairDeviceDialog extends Dialog {
|
||||||
// Display the QR code for the url
|
// Display the QR code for the url
|
||||||
const qr = new QRCode({
|
const qr = new QRCode({
|
||||||
content: this._getPairUrl(),
|
content: this._getPairUrl(),
|
||||||
width: 150,
|
width: 130,
|
||||||
height: 150,
|
height: 130,
|
||||||
padding: 1,
|
padding: 1,
|
||||||
background: 'rgb(250,250,250)',
|
background: 'rgb(250,250,250)',
|
||||||
color: 'rgb(18, 18, 18)',
|
color: 'rgb(18, 18, 18)',
|
||||||
|
@ -1392,7 +1392,7 @@ class EditPairedDevicesDialog extends Dialog {
|
||||||
<label class="auto-accept pointer">${autoAcceptString}
|
<label class="auto-accept pointer">${autoAcceptString}
|
||||||
<input type="checkbox" ${roomSecretsEntry.auto_accept ? "checked" : ""}>
|
<input type="checkbox" ${roomSecretsEntry.auto_accept ? "checked" : ""}>
|
||||||
</label>
|
</label>
|
||||||
<button class="button" type="button">${unpairString}</button>
|
<button class="btn" type="button">${unpairString}</button>
|
||||||
</div>`
|
</div>`
|
||||||
|
|
||||||
$pairedDevice
|
$pairedDevice
|
||||||
|
@ -1433,7 +1433,19 @@ class EditPairedDevicesDialog extends Dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onEditPairedDevices() {
|
_onEditPairedDevices() {
|
||||||
this._initDOM().then(_ => this.show());
|
this._initDOM()
|
||||||
|
.then(_ => {
|
||||||
|
this._evaluateOverflowing();
|
||||||
|
this.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_evaluateOverflowing() {
|
||||||
|
if (this.$pairedDevicesWrapper.clientHeight < this.$pairedDevicesWrapper.scrollHeight) {
|
||||||
|
this.$pairedDevicesWrapper.classList.add('overflowing');
|
||||||
|
} else {
|
||||||
|
this.$pairedDevicesWrapper.classList.remove('overflowing');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearRoomSecrets() {
|
_clearRoomSecrets() {
|
||||||
|
@ -1556,8 +1568,8 @@ class PublicRoomDialog extends Dialog {
|
||||||
// Display the QR code for the url
|
// Display the QR code for the url
|
||||||
const qr = new QRCode({
|
const qr = new QRCode({
|
||||||
content: this._getShareRoomUrl(),
|
content: this._getShareRoomUrl(),
|
||||||
width: 150,
|
width: 130,
|
||||||
height: 150,
|
height: 130,
|
||||||
padding: 1,
|
padding: 1,
|
||||||
background: 'rgb(250,250,250)',
|
background: 'rgb(250,250,250)',
|
||||||
color: 'rgb(18, 18, 18)',
|
color: 'rgb(18, 18, 18)',
|
||||||
|
@ -1736,16 +1748,27 @@ class SendTextDialog extends Dialog {
|
||||||
_onChange() {
|
_onChange() {
|
||||||
if (this._textInputEmpty()) {
|
if (this._textInputEmpty()) {
|
||||||
this.$submit.setAttribute('disabled', true);
|
this.$submit.setAttribute('disabled', true);
|
||||||
|
// remove remaining whitespace on Firefox on text deletion
|
||||||
|
this.$text.innerText = "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.$submit.removeAttribute('disabled');
|
this.$submit.removeAttribute('disabled');
|
||||||
}
|
}
|
||||||
|
this._evaluateOverflowing();
|
||||||
|
}
|
||||||
|
|
||||||
|
_evaluateOverflowing() {
|
||||||
|
if (this.$text.clientHeight < this.$text.scrollHeight) {
|
||||||
|
this.$text.classList.add('overflowing');
|
||||||
|
} else {
|
||||||
|
this.$text.classList.remove('overflowing');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRecipient(peerId, deviceName) {
|
_onRecipient(peerId, deviceName) {
|
||||||
this.correspondingPeerId = peerId;
|
this.correspondingPeerId = peerId;
|
||||||
this.$peerDisplayName.innerText = deviceName;
|
this.$peerDisplayName.innerText = deviceName;
|
||||||
this.$peerDisplayName.classList.remove("badge-room-ip", "badge-room-secret", "badge-room-public-id");
|
this.$peerDisplayName.classList.remove(...PeerUI._badgeClassNames);
|
||||||
this.$peerDisplayName.classList.add($(peerId).ui._badgeClassName());
|
this.$peerDisplayName.classList.add($(peerId).ui._badgeClassName());
|
||||||
|
|
||||||
this.show();
|
this.show();
|
||||||
|
@ -1768,8 +1791,8 @@ class SendTextDialog extends Dialog {
|
||||||
to: this.correspondingPeerId,
|
to: this.correspondingPeerId,
|
||||||
text: this.$text.innerText
|
text: this.$text.innerText
|
||||||
});
|
});
|
||||||
this.$text.innerText = "";
|
|
||||||
this.hide();
|
this.hide();
|
||||||
|
setTimeout(() => this.$text.innerText = "", 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1818,7 +1841,7 @@ class ReceiveTextDialog extends Dialog {
|
||||||
|
|
||||||
_showReceiveTextDialog(text, peerId) {
|
_showReceiveTextDialog(text, peerId) {
|
||||||
this.$displayName.innerText = $(peerId).ui._displayName();
|
this.$displayName.innerText = $(peerId).ui._displayName();
|
||||||
this.$displayName.classList.remove("badge-room-ip", "badge-room-secret", "badge-room-public-id");
|
this.$displayName.classList.remove(...PeerUI._badgeClassNames);
|
||||||
this.$displayName.classList.add($(peerId).ui._badgeClassName());
|
this.$displayName.classList.add($(peerId).ui._badgeClassName());
|
||||||
|
|
||||||
this.$text.innerText = text;
|
this.$text.innerText = text;
|
||||||
|
@ -1832,12 +1855,22 @@ class ReceiveTextDialog extends Dialog {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._evaluateOverflowing();
|
||||||
|
|
||||||
this._setDocumentTitleMessages();
|
this._setDocumentTitleMessages();
|
||||||
|
|
||||||
changeFavicon("images/favicon-96x96-notification.png");
|
changeFavicon("images/favicon-96x96-notification.png");
|
||||||
this.show();
|
this.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_evaluateOverflowing() {
|
||||||
|
if (this.$text.clientHeight < this.$text.scrollHeight) {
|
||||||
|
this.$text.classList.add('overflowing');
|
||||||
|
} else {
|
||||||
|
this.$text.classList.remove('overflowing');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_setDocumentTitleMessages() {
|
_setDocumentTitleMessages() {
|
||||||
document.title = !this._receiveTextQueue.length
|
document.title = !this._receiveTextQueue.length
|
||||||
? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop`
|
? `${ Localization.getTranslation("document-titles.message-received") } - PairDrop`
|
||||||
|
@ -2326,64 +2359,3 @@ class NoSleepUI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BrowserTabsConnector {
|
|
||||||
constructor() {
|
|
||||||
this.bc = new BroadcastChannel('pairdrop');
|
|
||||||
this.bc.addEventListener('message', e => this._onMessage(e));
|
|
||||||
Events.on('broadcast-send', e => this._broadcastSend(e.detail));
|
|
||||||
}
|
|
||||||
|
|
||||||
_broadcastSend(message) {
|
|
||||||
this.bc.postMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onMessage(e) {
|
|
||||||
console.log('Broadcast:', e.data)
|
|
||||||
switch (e.data.type) {
|
|
||||||
case 'self-display-name-changed':
|
|
||||||
Events.fire('self-display-name-changed', e.data.detail);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static peerIsSameBrowser(peerId) {
|
|
||||||
let peerIdsBrowser = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
|
||||||
return peerIdsBrowser
|
|
||||||
? peerIdsBrowser.indexOf(peerId) !== -1
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async addPeerIdToLocalStorage() {
|
|
||||||
const peerId = sessionStorage.getItem("peer_id");
|
|
||||||
if (!peerId) return false;
|
|
||||||
|
|
||||||
let peerIdsBrowser = [];
|
|
||||||
let peerIdsBrowserOld = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
|
||||||
|
|
||||||
if (peerIdsBrowserOld) peerIdsBrowser.push(...peerIdsBrowserOld);
|
|
||||||
peerIdsBrowser.push(peerId);
|
|
||||||
peerIdsBrowser = peerIdsBrowser.filter(onlyUnique);
|
|
||||||
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
|
||||||
|
|
||||||
return peerIdsBrowser;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async removePeerIdFromLocalStorage(peerId) {
|
|
||||||
let peerIdsBrowser = JSON.parse(localStorage.getItem("peer_ids_browser"));
|
|
||||||
const index = peerIdsBrowser.indexOf(peerId);
|
|
||||||
peerIdsBrowser.splice(index, 1);
|
|
||||||
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
|
||||||
return peerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static async removeOtherPeerIdsFromLocalStorage() {
|
|
||||||
const peerId = sessionStorage.getItem("peer_id");
|
|
||||||
if (!peerId) return false;
|
|
||||||
|
|
||||||
let peerIdsBrowser = [peerId];
|
|
||||||
localStorage.setItem("peer_ids_browser", JSON.stringify(peerIdsBrowser));
|
|
||||||
return peerIdsBrowser;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +1,46 @@
|
||||||
/* All styles in this sheet are not needed on page load and deferred */
|
/* All styles in this sheet are not needed on page load and deferred */
|
||||||
|
|
||||||
/* Peers */
|
/* Paste mode */
|
||||||
|
#cancel-paste-mode {
|
||||||
x-peers.overflowing {
|
z-index: 21;
|
||||||
background: /* Shadow covers */ linear-gradient(rgb(var(--bg-color)) 30%, rgba(var(--bg-color), 0)),
|
margin: 0;
|
||||||
linear-gradient(rgba(var(--bg-color), 0), rgb(var(--bg-color)) 70%) 0 100%,
|
padding: 0;
|
||||||
/* Shadows */ radial-gradient(farthest-side at 50% 0, rgba(var(--text-color), .2), rgba(var(--text-color), 0)),
|
position: absolute;
|
||||||
radial-gradient(farthest-side at 50% 100%, rgba(var(--text-color), .2), rgba(var(--text-color), 0)) 0 100%;
|
top: 0;
|
||||||
|
right: 0;
|
||||||
background-repeat: no-repeat;
|
left: 0;
|
||||||
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
|
width: 100vw;
|
||||||
|
height: 56px;
|
||||||
/* Opera doesn't support this in the shorthand */
|
background-color: var(--primary-color);
|
||||||
background-attachment: local, local, scroll, scroll;
|
color: rgb(238, 238, 238);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Text Input */
|
||||||
|
.textarea {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
padding: 16px 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
display: block;
|
||||||
|
overflow: auto;
|
||||||
|
resize: none;
|
||||||
|
line-height: 16px;
|
||||||
|
max-height: 300px;
|
||||||
|
word-break: break-word;
|
||||||
|
word-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Peers */
|
||||||
|
|
||||||
x-peers:has(> x-peer) {
|
x-peers:has(> x-peer) {
|
||||||
--peers-per-row: 10;
|
--peers-per-row: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* peers-per-row if height is too small for 2 rows */
|
@media screen and (min-height: 505px) and (max-height: 649px) and (max-width: 426px),
|
||||||
@media screen and (min-height: 538px) and (max-height: 683px) and (max-width: 402px),
|
screen and (min-height: 486px) and (max-height: 631px) and (min-width: 426px) {
|
||||||
screen and (min-height: 517px) and (max-height: 664px) and (min-width: 426px) {
|
|
||||||
x-peers:has(> x-peer) {
|
x-peers:has(> x-peer) {
|
||||||
--peers-per-row: 3;
|
--peers-per-row: 3;
|
||||||
}
|
}
|
||||||
|
@ -55,9 +74,8 @@ screen and (min-height: 517px) and (max-height: 664px) and (min-width: 426px) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* peers-per-row if height is too small for 3 rows */
|
@media screen and (min-height: 649px) and (max-width: 425px),
|
||||||
@media screen and (min-height: 683px) and (max-width: 402px),
|
screen and (min-height: 631px) and (min-width: 426px) {
|
||||||
screen and (min-height: 664px) and (min-width: 426px) {
|
|
||||||
x-peers:has(> x-peer) {
|
x-peers:has(> x-peer) {
|
||||||
--peers-per-row: 3;
|
--peers-per-row: 3;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +117,11 @@ x-peer {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x-peer input[type="file"] {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
x-peer label {
|
x-peer label {
|
||||||
width: var(--peer-width);
|
width: var(--peer-width);
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
|
@ -119,48 +142,60 @@ x-peer .icon-wrapper {
|
||||||
width: var(--icon-size);
|
width: var(--icon-size);
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--primary-color);
|
background: var(--accent-color);
|
||||||
|
background-image: linear-gradient(45deg, var(--accent-color) 40%, color-mix(in srgb, var(--accent-color) 70%, white) 100%);
|
||||||
color: white;
|
color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer.type-secret .icon-wrapper {
|
x-peer.type-secret .icon-wrapper {
|
||||||
background: var(--paired-device-color);
|
--accent-color: var(--paired-device-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer:not(.type-ip):not(.type-secret).type-public-id .icon-wrapper {
|
x-peer:not(.type-ip):not(.type-secret).type-public-id .icon-wrapper {
|
||||||
background: var(--public-room-color);
|
--accent-color: var(--public-room-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer x-icon > .highlight-wrapper {
|
.highlight-wrapper {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 7px auto 0;
|
margin: 7px auto 0;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer x-icon > .highlight-wrapper > .highlight {
|
.highlight {
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 6px;
|
height: 6px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
|
--highlight-color: var(--badge-color);
|
||||||
|
background-color: var(--highlight-color);
|
||||||
|
background-image: linear-gradient(180deg, var(--highlight-color) 0%, color-mix(in srgb, var(--highlight-color) 90%, black));
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-room-ip {
|
||||||
|
--highlight-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-room-secret {
|
||||||
|
--highlight-color: var(--paired-device-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-room-public-id {
|
||||||
|
--highlight-color: var(--public-room-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
x-peer:not(.type-ip) .highlight-room-ip {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer.type-ip x-icon > .highlight-wrapper > .highlight.highlight-room-ip {
|
x-peer:not(.type-secret) .highlight-room-secret {
|
||||||
background-color: var(--primary-color);
|
display: none;
|
||||||
display: inline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer.type-secret x-icon > .highlight-wrapper > .highlight.highlight-room-secret {
|
x-peer:not(.type-public-id) .highlight-room-public-id {
|
||||||
background-color: var(--paired-device-color);
|
display: none;
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
x-peer.type-public-id x-icon > .highlight-wrapper > .highlight.highlight-room-public-id {
|
|
||||||
background-color: var(--public-room-color);
|
|
||||||
display: inline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x-peer:not([status]):hover x-icon,
|
x-peer:not([status]):hover x-icon,
|
||||||
|
@ -174,7 +209,6 @@ x-peer[status] x-icon {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
x-peer.ws-peer {
|
x-peer.ws-peer {
|
||||||
margin-top: -1.5px;
|
margin-top: -1.5px;
|
||||||
}
|
}
|
||||||
|
@ -213,18 +247,8 @@ x-peer.ws-peer .highlight-wrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
.status,
|
.status,
|
||||||
.device-name,
|
|
||||||
.connection-hash {
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.device-name {
|
.device-name {
|
||||||
font-size: 14px;
|
opacity: 0.7;
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connection-hash {
|
|
||||||
font-size: 12px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,14 +280,13 @@ x-peer[drop] x-icon {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Dialog
|
/* Dialog */
|
||||||
|
|
||||||
x-dialog x-background {
|
x-dialog x-background {
|
||||||
background: rgba(0, 0, 0, 0.61);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
z-index: 10;
|
z-index: 30;
|
||||||
transition: opacity 300ms;
|
transition: opacity 300ms;
|
||||||
will-change: opacity;
|
will-change: opacity;
|
||||||
padding: 15px;
|
|
||||||
overflow: overlay;
|
overflow: overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,8 +295,7 @@ x-dialog x-paper {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: calc(100vw - 10px);
|
width: calc(100vw - 10px);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
background: white;
|
border-radius: 30px;
|
||||||
border-radius: 8px;
|
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -292,8 +314,8 @@ x-dialog x-paper {
|
||||||
|
|
||||||
x-paper > .row:first-of-type {
|
x-paper > .row:first-of-type {
|
||||||
background-color: var(--accent-color);
|
background-color: var(--accent-color);
|
||||||
border-bottom: solid 4px var(--border-color);
|
padding: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-paper > .row:first-of-type h2 {
|
x-paper > .row:first-of-type h2 {
|
||||||
|
@ -339,7 +361,6 @@ x-dialog a {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-key-container > input {
|
.input-key-container > input {
|
||||||
|
@ -372,20 +393,22 @@ x-dialog a {
|
||||||
-moz-user-select: text;
|
-moz-user-select: text;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 50px;
|
font-size: 45px;
|
||||||
letter-spacing: min(calc((100vw - 80px - 99px) / 100 * 7), 20px);
|
letter-spacing: min(calc((100vw - 80px - 99px) / 100 * 7), 20px);
|
||||||
text-indent: calc(0.5 * (11px + min(calc((100vw - 80px - 99px) / 100 * 6), 28px)));
|
text-indent: calc(0.5 * (11px + min(calc((100vw - 80px - 99px) / 100 * 6), 28px)));
|
||||||
margin: 25px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.key-qr-code {
|
.key-qr-code {
|
||||||
margin: 16px;
|
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.key-instructions {
|
.key-instructions {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-dialog h2 {
|
x-dialog h2 {
|
||||||
|
@ -394,19 +417,19 @@ x-dialog h2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
x-dialog hr {
|
x-dialog hr {
|
||||||
height: 3px;
|
height: 1px;
|
||||||
border: none;
|
border: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--border-color);
|
background-color: var(--border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.hr-note {
|
.hr-note {
|
||||||
margin-top: 10px;
|
margin-top: 23px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 31px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hr-note hr {
|
.hr-note hr {
|
||||||
margin-bottom: -2px;
|
margin-bottom: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hr-note > div {
|
.hr-note > div {
|
||||||
|
@ -417,9 +440,9 @@ x-dialog hr {
|
||||||
|
|
||||||
.hr-note > div > span {
|
.hr-note > div > span {
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
border-radius: 10px;
|
border-radius: 20px;
|
||||||
color: rgb(var(--text-color));
|
color: rgb(var(--text-color));
|
||||||
background-color: rgb(var(--bg-color));
|
background-color: var(--dialog-bg-color);
|
||||||
border: var(--border-color) solid 3px;
|
border: var(--border-color) solid 3px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
@ -438,20 +461,10 @@ x-dialog hr {
|
||||||
}
|
}
|
||||||
|
|
||||||
.paired-devices-wrapper {
|
.paired-devices-wrapper {
|
||||||
border-top: solid 4px var(--paired-device-color);
|
margin-top: -5px;
|
||||||
border-bottom: solid 4px var(--paired-device-color);
|
border-bottom: solid 4px var(--paired-device-color);
|
||||||
max-height: 65vh;
|
max-height: 65vh;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
background: /* Shadow covers */ linear-gradient(rgb(var(--bg-color)) 30%, rgba(var(--bg-color), 0)),
|
|
||||||
linear-gradient(rgba(var(--bg-color), 0), rgb(var(--bg-color)) 70%) 0 100%,
|
|
||||||
/* Shadows */ radial-gradient(farthest-side at 50% 0, rgba(var(--text-color), .3), rgba(var(--text-color), 0)),
|
|
||||||
radial-gradient(farthest-side at 50% 100%, rgba(var(--text-color), .3), rgba(var(--text-color), 0)) 0 100%;
|
|
||||||
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100% 80px, 100% 80px, 100% 24px, 100% 24px;
|
|
||||||
|
|
||||||
/* Opera doesn't support this in the shorthand */
|
|
||||||
background-attachment: local, local, scroll, scroll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.paired-device {
|
.paired-device {
|
||||||
|
@ -515,44 +528,41 @@ x-dialog hr {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive Dialog */
|
|
||||||
|
|
||||||
x-paper > .row {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* button row*/
|
/* button row*/
|
||||||
x-paper > .button-row {
|
x-paper > .button-row {
|
||||||
border-top: solid 3px var(--border-color);
|
|
||||||
height: 50px;
|
height: 50px;
|
||||||
margin-top: 10px;
|
margin: 5px 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
x-paper > .button-row > .button {
|
x-paper > .button-row > .btn {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not([dir="rtl"]) x-paper > .button-row > .button:not(:first-child) {
|
html:not([dir="rtl"]) x-paper > .button-row > .btn:not(:first-child) {
|
||||||
border-right: solid 1.5px var(--border-color);
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not([dir="rtl"]) x-paper > .button-row > .button:not(:last-child) {
|
html:not([dir="rtl"]) x-paper > .button-row > .btn:not(:last-child) {
|
||||||
border-left: solid 1.5px var(--border-color);
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[dir="rtl"] x-paper > .button-row > .button:not(:first-child) {
|
html[dir="rtl"] x-paper > .button-row > .btn:not(:first-child) {
|
||||||
border-left: solid 1.5px var(--border-color);
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[dir="rtl"] x-paper > .button-row > .button:not(:last-child) {
|
html[dir="rtl"] x-paper > .button-row > .btn:not(:last-child) {
|
||||||
border-right: solid 1.5px var(--border-color);
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-buttons > button > span {
|
.language-buttons > button > span {
|
||||||
margin: 0 0.3em;
|
margin: 0 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-buttons > button {
|
||||||
|
min-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
.file-description {
|
.file-description {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -581,31 +591,37 @@ x-dialog .dialog-subheader {
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#send-text-dialog .display-name-wrapper {
|
.display-name-wrapper {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#text-input {
|
#send-text-dialog,
|
||||||
min-height: 200px;
|
#receive-text-dialog {
|
||||||
width: 100%;
|
font-size: 16px; /* prevents auto-zoom on edit */
|
||||||
|
--shadow-color-rgb: var(--shadow-color-secondary-rgb);
|
||||||
|
--shadow-color-cover-rgb: var(--shadow-color-secondary-cover-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#edit-paired-devices-dialog {
|
||||||
|
--shadow-color-rgb: var(--shadow-color-dialog-rgb);
|
||||||
|
--shadow-color-cover-rgb: var(--shadow-color-dialog-cover-rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
#text-input:before {
|
||||||
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive Text Dialog */
|
/* Receive Text Dialog */
|
||||||
|
|
||||||
#receive-text-dialog #text {
|
#receive-text-dialog #text {
|
||||||
width: 100%;
|
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
max-height: calc(100vh - 393px);
|
max-height: 400px;
|
||||||
|
padding: 10px;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: scroll;
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
-moz-user-select: text;
|
-moz-user-select: text;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
#receive-text-dialog #text a {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#receive-text-dialog #text a:hover {
|
#receive-text-dialog #text a:hover {
|
||||||
|
@ -618,17 +634,11 @@ x-dialog .dialog-subheader {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row-separator {
|
|
||||||
border-bottom: solid 2.5px var(--border-color);
|
|
||||||
margin: auto -24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#base64-paste-btn,
|
#base64-paste-btn,
|
||||||
#base64-paste-dialog .textarea {
|
#base64-paste-dialog .textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40vh;
|
height: 40vh;
|
||||||
border: solid 12px #438cff;
|
border: solid 12px #438cff;
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#base64-paste-dialog .textarea {
|
#base64-paste-dialog .textarea {
|
||||||
|
@ -639,7 +649,7 @@ x-dialog .dialog-subheader {
|
||||||
}
|
}
|
||||||
|
|
||||||
#base64-paste-dialog .textarea::before {
|
#base64-paste-dialog .textarea::before {
|
||||||
font-size: 15px;
|
font-size: 14px;
|
||||||
letter-spacing: 0.12em;
|
letter-spacing: 0.12em;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
@ -647,7 +657,6 @@ x-dialog .dialog-subheader {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Peer loading Indicator */
|
/* Peer loading Indicator */
|
||||||
|
|
||||||
.progress {
|
.progress {
|
||||||
|
@ -679,7 +688,6 @@ x-dialog .dialog-subheader {
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Color Themes
|
Color Themes
|
||||||
*/
|
*/
|
||||||
|
@ -687,7 +695,7 @@ x-dialog .dialog-subheader {
|
||||||
/* Colored Elements */
|
/* Colored Elements */
|
||||||
|
|
||||||
x-dialog x-paper {
|
x-dialog x-paper {
|
||||||
background-color: rgb(var(--bg-color));
|
background-color: var(--dialog-bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.textarea {
|
.textarea {
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
/* All styles in this sheet are needed on page load */
|
/* All styles in this sheet are needed on page load */
|
||||||
|
|
||||||
/* Constants */
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--icon-size: 24px;
|
|
||||||
--primary-color: #4285f4;
|
|
||||||
--paired-device-color: #00a69c;
|
|
||||||
--public-room-color: #db8500;
|
|
||||||
--accent-color: var(--primary-color);
|
|
||||||
--peer-width: 120px;
|
|
||||||
--ws-peer-color: #ff6b6b;
|
|
||||||
color-scheme: light dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
|
|
||||||
html,
|
html,
|
||||||
|
@ -43,6 +30,10 @@ html {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p1 {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.row-reverse {
|
.row-reverse {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
|
@ -90,7 +81,7 @@ header {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
z-index: 2;
|
z-index: 20;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
@ -163,10 +154,18 @@ header > div:hover .icon-button.selected::before {
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
src: url('../fonts/OpenSans/static/OpenSans-Medium.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
font-family: "Open Sans", -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
font-variant-ligatures: common-ligatures;
|
||||||
|
font-kerning: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
@ -174,7 +173,7 @@ h1 {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
letter-spacing: -.01em;
|
letter-spacing: -.01em;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
margin: 8px 0 0;
|
margin: 0 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
@ -260,7 +259,19 @@ x-noscript {
|
||||||
0 2px 4px -1px rgba(0, 0, 0, 0.4);
|
0 2px 4px -1px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overflowing {
|
||||||
|
background:
|
||||||
|
/* Shadow covers */
|
||||||
|
linear-gradient(rgb(var(--shadow-color-cover-rgb)) 30%, rgba(var(--shadow-color-cover-rgb), 0)),
|
||||||
|
linear-gradient(rgba(var(--shadow-color-cover-rgb), 0), rgb(var(--shadow-color-cover-rgb)) 70%) 0 100%,
|
||||||
|
/* Shadows */
|
||||||
|
radial-gradient(farthest-side at 50% 0, rgba(var(--shadow-color-rgb), .2), rgba(var(--shadow-color-rgb), 0)),
|
||||||
|
radial-gradient(farthest-side at 50% 100%, rgba(var(--shadow-color-rgb), .2), rgba(var(--shadow-color-rgb), 0))
|
||||||
|
0 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 60px, 100% 60px, 100% 24px, 100% 24px;
|
||||||
|
background-attachment: local, local, scroll, scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
|
@ -295,6 +306,28 @@ x-noscript {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x-peers {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
align-items: start !important;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
z-index: 2;
|
||||||
|
transition: background-color 0.5s ease;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overscroll-behavior-x: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
|
--peers-per-row: 6; /* default if browser does not support :has selector */
|
||||||
|
--x-peers-width: min(100vw, calc(var(--peers-per-row) * (var(--peer-width) + 25px) - 16px));
|
||||||
|
width: var(--x-peers-width);
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Empty Peers List */
|
/* Empty Peers List */
|
||||||
|
|
||||||
x-no-peers {
|
x-no-peers {
|
||||||
|
@ -331,34 +364,6 @@ x-no-peers[drop-bg] * {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
input[type="file"] {
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
x-peers {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
flex-grow: 1;
|
|
||||||
align-items: start !important;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
z-index: 2;
|
|
||||||
transition: --bg-color 0.5s ease;
|
|
||||||
overflow-y: scroll;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overscroll-behavior-x: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
|
|
||||||
--peers-per-row: 6; /* default if browser does not support :has selector */
|
|
||||||
--x-peers-width: min(100vw, calc(var(--peers-per-row) * (var(--peer-width) + 25px) - 16px));
|
|
||||||
width: var(--x-peers-width);
|
|
||||||
margin-right: 20px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
|
@ -378,16 +383,23 @@ footer .logo {
|
||||||
}
|
}
|
||||||
|
|
||||||
.discovery-wrapper {
|
.discovery-wrapper {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
margin: 10px auto auto;
|
margin: 15px auto auto;
|
||||||
border: 3px solid var(--border-color);
|
border: 2px solid var(--border-color);
|
||||||
border-radius: 0.5rem;
|
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
background-color: rgb(var(--bg-color));
|
background-color: rgb(var(--bg-color));
|
||||||
transition: background-color 0.5s ease;
|
transition: background-color 0.5s ease;
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.discovery-wrapper.column {
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.discovery-wrapper.row {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
/*You can be discovered wrapper*/
|
/*You can be discovered wrapper*/
|
||||||
.discovery-wrapper > div:first-of-type {
|
.discovery-wrapper > div:first-of-type {
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
@ -401,28 +413,32 @@ footer .logo {
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
border-radius: 0.3rem/0.3rem;
|
border-radius: 0.4rem;
|
||||||
padding-right: 0.3rem;
|
padding-right: 0.3rem;
|
||||||
padding-left: 0.3em;
|
padding-left: 0.3em;
|
||||||
background-color: var(--badge-color);
|
background-color: var(--badge-color);
|
||||||
color: white;
|
color: white;
|
||||||
transition: background-color 0.5s ease;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge-gradient {
|
||||||
|
background-image: linear-gradient(180deg, color-mix(in srgb, var(--badge-color) 80%, white) 0%, var(--badge-color) 50%);
|
||||||
|
}
|
||||||
|
|
||||||
.badge-room-ip {
|
.badge-room-ip {
|
||||||
background-color: var(--primary-color);
|
--badge-color: var(--primary-color);
|
||||||
border-color: var(--primary-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-room-secret {
|
.badge-room-secret {
|
||||||
background-color: var(--paired-device-color);
|
--badge-color: var(--paired-device-color);
|
||||||
border-color: var(--paired-device-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-room-public-id {
|
.badge-room-public-id {
|
||||||
background-color: var(--public-room-color);
|
--badge-color: var(--public-room-color);
|
||||||
border-color: var(--public-room-color);
|
}
|
||||||
|
|
||||||
|
.known-as-wrapper {
|
||||||
|
font-size: 16px; /* prevents auto-zoom on edit */
|
||||||
}
|
}
|
||||||
|
|
||||||
#display-name {
|
#display-name {
|
||||||
|
@ -470,13 +486,12 @@ x-dialog:not([show]) x-background {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Button */
|
/* Button */
|
||||||
|
|
||||||
.button {
|
.btn {
|
||||||
|
font-family: "Open Sans", -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
padding: 2px 16px 0;
|
padding: 2px 16px 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-height: 36px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
@ -490,13 +505,13 @@ x-dialog:not([show]) x-background {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button[disabled] {
|
.btn[disabled] {
|
||||||
color: #5B5B66;
|
color: var(--btn-disabled-color);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.button,
|
.btn,
|
||||||
.icon-button {
|
.icon-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -508,7 +523,7 @@ x-dialog:not([show]) x-background {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:before,
|
.btn:before,
|
||||||
.icon-button:before {
|
.icon-button:before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -516,41 +531,33 @@ x-dialog:not([show]) x-background {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: currentColor;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
background-color: var(--accent-color);
|
||||||
transition: opacity 300ms;
|
transition: opacity 300ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:not([disabled]):hover:before,
|
.btn:not([disabled]):hover:before,
|
||||||
.icon-button:hover:before {
|
.icon-button:hover:before {
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button[selected],
|
.btn[selected],
|
||||||
.icon-button[selected] {
|
.icon-button[selected] {
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#cancel-paste-mode {
|
.btn:focus:before,
|
||||||
z-index: 2;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 56px;
|
|
||||||
background-color: var(--primary-color);
|
|
||||||
color: rgb(238, 238, 238);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:focus:before,
|
|
||||||
.icon-button:focus:before {
|
.icon-button:focus:before {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn-rounded {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-grey {
|
||||||
|
background-color: var(--bg-color-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
button::-moz-focus-inner {
|
button::-moz-focus-inner {
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -567,30 +574,12 @@ button::-moz-focus-inner {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text Input */
|
|
||||||
.textarea {
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
padding: 16px 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-family: inherit;
|
|
||||||
background: #f1f3f4;
|
|
||||||
display: block;
|
|
||||||
overflow: auto;
|
|
||||||
resize: none;
|
|
||||||
line-height: 16px;
|
|
||||||
max-height: calc(100vh - 254px);
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Info Animation */
|
/* Info Animation */
|
||||||
|
|
||||||
#about {
|
#about {
|
||||||
color: white;
|
color: white;
|
||||||
z-index: 11;
|
z-index: 32;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -631,7 +620,7 @@ button::-moz-focus-inner {
|
||||||
}
|
}
|
||||||
|
|
||||||
#about .title-wrapper > div {
|
#about .title-wrapper > div {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#about x-background {
|
#about x-background {
|
||||||
|
@ -641,10 +630,11 @@ button::-moz-focus-inner {
|
||||||
top: calc(28px - var(--size-half));
|
top: calc(28px - var(--size-half));
|
||||||
width: var(--size);
|
width: var(--size);
|
||||||
height: var(--size);
|
height: var(--size);
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--primary-color);
|
|
||||||
transform: scale(0);
|
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
background: var(--primary-color);
|
||||||
|
background-image: radial-gradient(circle at calc(50% - 36px), var(--accent-color) 0%, color-mix(in srgb, var(--accent-color) 40%, black) 80%);
|
||||||
|
--crop-size: 0px;
|
||||||
|
clip-path: circle(var(--crop-size));
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not([dir="rtl"]) #about x-background {
|
html:not([dir="rtl"]) #about x-background {
|
||||||
|
@ -658,12 +648,12 @@ html[dir="rtl"] #about x-background {
|
||||||
|
|
||||||
/* Hack such that initial scale(0) isn't animated */
|
/* Hack such that initial scale(0) isn't animated */
|
||||||
#about x-background {
|
#about x-background {
|
||||||
will-change: transform;
|
will-change: clip-path;
|
||||||
transition: transform 800ms cubic-bezier(0.77, 0, 0.175, 1);
|
transition: clip-path 800ms cubic-bezier(0.77, 0, 0.175, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#about:target x-background {
|
#about:target x-background {
|
||||||
transform: scale(1);
|
--crop-size: var(--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#about .row a {
|
#about .row a {
|
||||||
|
@ -687,6 +677,38 @@ canvas.circles {
|
||||||
content: attr(placeholder);
|
content: attr(placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Toast */
|
||||||
|
|
||||||
|
.toast-container {
|
||||||
|
padding: 0 8px 24px;
|
||||||
|
overflow: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
x-toast {
|
||||||
|
position: absolute;
|
||||||
|
min-height: 48px;
|
||||||
|
top: 50px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 344px;
|
||||||
|
background-color: rgb(var(--text-color));
|
||||||
|
color: var(--dialog-bg-color);
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 8px 24px;
|
||||||
|
z-index: 40;
|
||||||
|
transition: opacity 200ms, transform 300ms ease-out;
|
||||||
|
cursor: default;
|
||||||
|
line-height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
x-toast:not([show]):not(:hover) {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-100px);
|
||||||
|
}
|
||||||
|
|
||||||
/* Instructions */
|
/* Instructions */
|
||||||
|
|
||||||
x-instructions {
|
x-instructions {
|
||||||
|
@ -757,36 +779,12 @@ x-peers:empty~x-instructions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toast */
|
/* Constants */
|
||||||
|
|
||||||
.toast-container {
|
:root {
|
||||||
padding: 0 8px 24px;
|
--icon-size: 24px;
|
||||||
overflow: hidden;
|
--peer-width: 120px;
|
||||||
pointer-events: none;
|
color-scheme: light dark;
|
||||||
}
|
|
||||||
|
|
||||||
x-toast {
|
|
||||||
position: absolute;
|
|
||||||
min-height: 48px;
|
|
||||||
top: 50px;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 344px;
|
|
||||||
background-color: rgb(var(--text-color));
|
|
||||||
color: rgb(var(--bg-color));
|
|
||||||
align-items: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 8px 24px;
|
|
||||||
z-index: 20;
|
|
||||||
transition: opacity 200ms, transform 300ms ease-out;
|
|
||||||
cursor: default;
|
|
||||||
line-height: 24px;
|
|
||||||
border-radius: 8px;
|
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
|
|
||||||
x-toast:not([show]):not(:hover) {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-100px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -794,22 +792,82 @@ x-toast:not([show]):not(:hover) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Default colors */
|
/* Default colors */
|
||||||
|
body {
|
||||||
|
/* Constant colors */
|
||||||
|
--primary-color: #4285f4;
|
||||||
|
--paired-device-color: #00a69c;
|
||||||
|
--public-room-color: #db8500;
|
||||||
|
--accent-color: var(--primary-color);
|
||||||
|
--ws-peer-color: #ff6b6b;
|
||||||
|
--btn-disabled-color: #5B5B66;
|
||||||
|
/* shadows */
|
||||||
|
--shadow-color-rgb: var(--text-color);
|
||||||
|
--shadow-color-cover-rgb: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light theme colors */
|
||||||
body {
|
body {
|
||||||
--text-color: 51,51,51;
|
--text-color: 51,51,51;
|
||||||
--bg-color: 250,250,250; /*rgb code*/
|
--dialog-bg-color: #fff;
|
||||||
--bg-color-test: 18,18,18;
|
--bg-color: 255,255,255;
|
||||||
--bg-color-secondary: #e4e4e4;
|
--bg-color-secondary: #f2f2f2;
|
||||||
--border-color: rgb(169, 169, 169);
|
--border-color: rgb(169, 169, 169);
|
||||||
--badge-color: #a5a5a5;
|
--badge-color: #a5a5a5;
|
||||||
|
|
||||||
|
--shadow-color-secondary-rgb: 0,0,0;
|
||||||
|
--shadow-color-secondary-cover-rgb: 242,242,242;
|
||||||
|
--shadow-color-dialog-rgb: 0,0,0;
|
||||||
|
--shadow-color-dialog-cover-rgb: 242,242,242;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark theme colors */
|
/* Dark theme colors */
|
||||||
body.dark-theme {
|
body.dark-theme {
|
||||||
--text-color: 238,238,238;
|
--text-color: 238,238,238;
|
||||||
--bg-color: 18,18,18; /*rgb code*/
|
--dialog-bg-color: #121212;
|
||||||
--bg-color-secondary: #333;
|
--bg-color: 0,0,0;
|
||||||
--border-color: rgb(238,238,238);
|
--bg-color-secondary: #262628;
|
||||||
|
--border-color: rgb(91, 91, 91);
|
||||||
--badge-color: #717171;
|
--badge-color: #717171;
|
||||||
|
|
||||||
|
--shadow-color-secondary-rgb: 255,255,255;
|
||||||
|
--shadow-color-secondary-cover-rgb: 38,38,38;
|
||||||
|
--shadow-color-dialog-rgb: 255,255,255;
|
||||||
|
--shadow-color-dialog-cover-rgb: 38,38,38;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles for users who prefer dark mode at the OS level */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
/* defaults to dark theme */
|
||||||
|
body {
|
||||||
|
--text-color: 238,238,238;
|
||||||
|
--dialog-bg-color: #121212;
|
||||||
|
--bg-color-secondary: #262628;
|
||||||
|
--bg-color: 0,0,0;
|
||||||
|
--border-color: rgb(91, 91, 91);
|
||||||
|
--badge-color: #717171;
|
||||||
|
|
||||||
|
--shadow-color-secondary-rgb: 255,255,255;
|
||||||
|
--shadow-color-secondary-cover-rgb: 38,38,38;
|
||||||
|
--shadow-color-dialog-rgb: 255,255,255;
|
||||||
|
--shadow-color-dialog-cover-rgb: 38,38,38;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Override dark mode with light mode styles if the user decides to swap */
|
||||||
|
body.light-theme {
|
||||||
|
--text-color: 51,51,51;
|
||||||
|
--dialog-bg-color: #fff;
|
||||||
|
--bg-color: 255,255,255;
|
||||||
|
--bg-color-secondary: #f2f2f2;
|
||||||
|
--border-color: rgb(169, 169, 169);
|
||||||
|
--badge-color: #a5a5a5;
|
||||||
|
|
||||||
|
--shadow-color-secondary-rgb: 0,0,0;
|
||||||
|
--shadow-color-secondary-cover-rgb: 242,242,242;
|
||||||
|
--shadow-color-dialog-rgb: 0,0,0;
|
||||||
|
--shadow-color-dialog-cover-rgb: 242,242,242;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Colored Elements */
|
/* Colored Elements */
|
||||||
|
@ -819,26 +877,41 @@ body {
|
||||||
transition: background-color 0.5s ease;
|
transition: background-color 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for users who prefer dark mode at the OS level */
|
x-dialog x-paper {
|
||||||
@media (prefers-color-scheme: dark) {
|
background-color: var(--dialog-bg-color);
|
||||||
|
|
||||||
/* defaults to dark theme */
|
|
||||||
body {
|
|
||||||
--text-color: 238,238,238;
|
|
||||||
--bg-color: 18,18,18; /*rgb code*/
|
|
||||||
--bg-color-secondary: #333;
|
|
||||||
--border-color: rgb(238,238,238);
|
|
||||||
--badge-color: #717171;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override dark mode with light mode styles if the user decides to swap */
|
.textarea {
|
||||||
body.light-theme {
|
color: rgb(var(--text-color)) !important;
|
||||||
--text-color: 51,51,51;
|
background-color: var(--bg-color-secondary) !important;
|
||||||
--bg-color: 250,250,250; /*rgb code*/
|
|
||||||
--bg-color-secondary: #e4e4e4;
|
|
||||||
--border-color: rgb(169, 169, 169);
|
|
||||||
--badge-color: #a5a5a5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.textarea * {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
color: unset !important;
|
||||||
|
background: unset !important;
|
||||||
|
border: unset !important;
|
||||||
|
opacity: unset !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-style: unset !important;
|
||||||
|
font-weight: unset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gradient for wifi-tether icon */
|
||||||
|
#primaryGradient .start-color {
|
||||||
|
stop-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (stop-color: color-mix(in srgb, blue 50%, black)) {
|
||||||
|
#primaryGradient .start-color {
|
||||||
|
stop-color: color-mix(in srgb, var(--primary-color) 80%, white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#primaryGradient .stop-color {
|
||||||
|
stop-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -894,3 +967,4 @@ See note here: https://developer.mozilla.org/en-US/docs/Web/CSS/user-select */
|
||||||
-webkit-user-select: text;
|
-webkit-user-select: text;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|