diff --git a/README.md b/README.md index fc8ce2f..b339a2b 100644 --- a/README.md +++ b/README.md @@ -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)) * To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558) * When hosting PairDrop yourself you can [set your own STUN/TURN servers](/docs/host-your-own.md#specify-stunturn-servers) -* Built-in translations +* Built-in translations via [Weblate](https://hosted.weblate.org/engage/pairdrop/) +* Airy design (Thanks [@Avieshek](https://linktr.ee/avieshek/)) diff --git a/public/fonts/OpenSans/OFL.txt b/public/fonts/OpenSans/OFL.txt new file mode 100644 index 0000000..9b448d4 --- /dev/null +++ b/public/fonts/OpenSans/OFL.txt @@ -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. diff --git a/public/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf b/public/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf new file mode 100644 index 0000000..5bda9cc Binary files /dev/null and b/public/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf differ diff --git a/public/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf b/public/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf new file mode 100644 index 0000000..e4142bf Binary files /dev/null and b/public/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf differ diff --git a/public/fonts/OpenSans/README.txt b/public/fonts/OpenSans/README.txt new file mode 100644 index 0000000..2548322 --- /dev/null +++ b/public/fonts/OpenSans/README.txt @@ -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. diff --git a/public/fonts/OpenSans/static/OpenSans-Bold.ttf b/public/fonts/OpenSans/static/OpenSans-Bold.ttf new file mode 100644 index 0000000..4a5bc39 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-Bold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-BoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans-BoldItalic.ttf new file mode 100644 index 0000000..8878a3e Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-BoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-ExtraBold.ttf b/public/fonts/OpenSans/static/OpenSans-ExtraBold.ttf new file mode 100644 index 0000000..5dfb66c Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-ExtraBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-ExtraBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans-ExtraBoldItalic.ttf new file mode 100644 index 0000000..d266998 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-ExtraBoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-Italic.ttf b/public/fonts/OpenSans/static/OpenSans-Italic.ttf new file mode 100644 index 0000000..e84f9ee Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-Italic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-Light.ttf b/public/fonts/OpenSans/static/OpenSans-Light.ttf new file mode 100644 index 0000000..cf8e0c7 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-Light.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-LightItalic.ttf b/public/fonts/OpenSans/static/OpenSans-LightItalic.ttf new file mode 100644 index 0000000..d913f35 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-LightItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-Medium.ttf b/public/fonts/OpenSans/static/OpenSans-Medium.ttf new file mode 100644 index 0000000..a76d4ce Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-Medium.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-MediumItalic.ttf b/public/fonts/OpenSans/static/OpenSans-MediumItalic.ttf new file mode 100644 index 0000000..5599691 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-MediumItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-Regular.ttf b/public/fonts/OpenSans/static/OpenSans-Regular.ttf new file mode 100644 index 0000000..29e9e60 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-Regular.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-SemiBold.ttf b/public/fonts/OpenSans/static/OpenSans-SemiBold.ttf new file mode 100644 index 0000000..a571167 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-SemiBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans-SemiBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans-SemiBoldItalic.ttf new file mode 100644 index 0000000..a7d2323 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans-SemiBoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-Bold.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-Bold.ttf new file mode 100644 index 0000000..90d25e5 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-Bold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-BoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-BoldItalic.ttf new file mode 100644 index 0000000..9fefa96 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-BoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBold.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBold.ttf new file mode 100644 index 0000000..ec9e308 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBoldItalic.ttf new file mode 100644 index 0000000..f4a2648 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-ExtraBoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-Italic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-Italic.ttf new file mode 100644 index 0000000..451059e Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-Italic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-Light.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-Light.ttf new file mode 100644 index 0000000..9823525 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-Light.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-LightItalic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-LightItalic.ttf new file mode 100644 index 0000000..d1f9808 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-LightItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-Medium.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-Medium.ttf new file mode 100644 index 0000000..50a9f70 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-Medium.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-MediumItalic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-MediumItalic.ttf new file mode 100644 index 0000000..e24fdca Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-MediumItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-Regular.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-Regular.ttf new file mode 100644 index 0000000..3aa5d46 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-Regular.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBold.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBold.ttf new file mode 100644 index 0000000..1b98bc4 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBoldItalic.ttf new file mode 100644 index 0000000..318828d Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_Condensed-SemiBoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Bold.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Bold.ttf new file mode 100644 index 0000000..dc2168f Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Bold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-BoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-BoldItalic.ttf new file mode 100644 index 0000000..36818ec Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-BoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBold.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBold.ttf new file mode 100644 index 0000000..64b8c41 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf new file mode 100644 index 0000000..09f3851 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Italic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Italic.ttf new file mode 100644 index 0000000..690ce39 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Italic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Light.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Light.ttf new file mode 100644 index 0000000..443bc12 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Light.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-LightItalic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-LightItalic.ttf new file mode 100644 index 0000000..b804514 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-LightItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Medium.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Medium.ttf new file mode 100644 index 0000000..8c143cd Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Medium.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-MediumItalic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-MediumItalic.ttf new file mode 100644 index 0000000..d4564c9 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-MediumItalic.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Regular.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Regular.ttf new file mode 100644 index 0000000..8130446 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-Regular.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBold.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBold.ttf new file mode 100644 index 0000000..99b6069 Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBold.ttf differ diff --git a/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf new file mode 100644 index 0000000..c89a1cf Binary files /dev/null and b/public/fonts/OpenSans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf differ diff --git a/public/images/android-chrome-192x192-maskable.png b/public/images/android-chrome-192x192-maskable.png index f0e9245..de6b81b 100644 Binary files a/public/images/android-chrome-192x192-maskable.png and b/public/images/android-chrome-192x192-maskable.png differ diff --git a/public/images/android-chrome-192x192.png b/public/images/android-chrome-192x192.png index 0bdca51..ea419d4 100644 Binary files a/public/images/android-chrome-192x192.png and b/public/images/android-chrome-192x192.png differ diff --git a/public/images/android-chrome-512x512-maskable.png b/public/images/android-chrome-512x512-maskable.png index cdda606..f2253c7 100644 Binary files a/public/images/android-chrome-512x512-maskable.png and b/public/images/android-chrome-512x512-maskable.png differ diff --git a/public/images/android-chrome-512x512.png b/public/images/android-chrome-512x512.png index b01e679..da6f1c8 100644 Binary files a/public/images/android-chrome-512x512.png and b/public/images/android-chrome-512x512.png differ diff --git a/public/images/apple-touch-icon.png b/public/images/apple-touch-icon.png index 0a32878..6a96c53 100644 Binary files a/public/images/apple-touch-icon.png and b/public/images/apple-touch-icon.png differ diff --git a/public/images/favicon-96x96-notification.png b/public/images/favicon-96x96-notification.png index d3407c3..3b1d846 100644 Binary files a/public/images/favicon-96x96-notification.png and b/public/images/favicon-96x96-notification.png differ diff --git a/public/images/favicon-96x96.png b/public/images/favicon-96x96.png index b8a5746..c884154 100644 Binary files a/public/images/favicon-96x96.png and b/public/images/favicon-96x96.png differ diff --git a/public/images/logo_blue_512x512.png b/public/images/logo_blue_512x512.png index 41d13fc..f2253c7 100644 Binary files a/public/images/logo_blue_512x512.png and b/public/images/logo_blue_512x512.png differ diff --git a/public/images/logo_transparent_128x128.png b/public/images/logo_transparent_128x128.png deleted file mode 100644 index c276efe..0000000 Binary files a/public/images/logo_transparent_128x128.png and /dev/null differ diff --git a/public/images/logo_transparent_512x512.png b/public/images/logo_transparent_512x512.png deleted file mode 100644 index 367e24f..0000000 Binary files a/public/images/logo_transparent_512x512.png and /dev/null differ diff --git a/public/images/logo_white_512x512.png b/public/images/logo_white_512x512.png deleted file mode 100644 index d7750d9..0000000 Binary files a/public/images/logo_white_512x512.png and /dev/null differ diff --git a/public/index.html b/public/index.html index 2d51d8d..c8afe83 100644 --- a/public/index.html +++ b/public/index.html @@ -5,7 +5,7 @@ - PairDrop + PairDrop | Transfer Files Cross-Platform. No Setup, No Signup. @@ -95,7 +95,7 @@ - +
@@ -118,7 +118,13 @@
@@ -148,78 +154,78 @@

- - + - - - - - - - - - - - - -
- +
@@ -249,7 +255,7 @@
-
+
@@ -262,8 +268,8 @@
- - + +
@@ -286,7 +292,7 @@

- +
@@ -319,7 +325,7 @@
-
+
@@ -331,9 +337,9 @@
- - - + + +
@@ -348,10 +354,10 @@

-
+
- +
@@ -365,8 +371,8 @@
- - + +
@@ -380,10 +386,10 @@

-
+
- +
@@ -397,9 +403,9 @@
- - - + + +
@@ -414,22 +420,22 @@

-
+
- +
-
+
-
+
- - + +
@@ -442,20 +448,20 @@

-
+
- +
-
+
-
+
- - + +
@@ -464,10 +470,10 @@ - +
- +
diff --git a/public/lang/en.json b/public/lang/en.json index 4b79d1c..6c3a214 100644 --- a/public/lang/en.json +++ b/public/lang/en.json @@ -70,8 +70,9 @@ "share": "Share", "download": "Download", "send-message-title": "Send Message", - "send-message-to": "Send a Message to", + "send-message-to": "To:", "message_title": "Insert message to send", + "message_placeholder": "Text", "send": "Send", "receive-text-title": "Message Received", "copy": "Copy", diff --git a/public/manifest.json b/public/manifest.json index 7ac7e66..2414c47 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,29 +1,30 @@ { "name": "PairDrop", "short_name": "PairDrop", - "icons": [{ + "icons": [ + { "src": "images/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" - },{ + }, + { "src": "images/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" - },{ + }, + { "src": "images/android-chrome-192x192-maskable.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" - },{ + }, + { "src": "images/android-chrome-512x512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" - },{ - "src": "images/favicon-96x96.png", - "sizes": "96x96", - "type": "image/png" - }], + } + ], "background_color": "#efefef", "start_url": "/", "scope": "/", diff --git a/public/scripts/browser-tabs-connector.js b/public/scripts/browser-tabs-connector.js new file mode 100644 index 0000000..92cc89a --- /dev/null +++ b/public/scripts/browser-tabs-connector.js @@ -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; + } +} \ No newline at end of file diff --git a/public/scripts/main.js b/public/scripts/main.js index 51eaa41..d0ec8a1 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -39,7 +39,7 @@ class PairDrop { registerServiceWorker() { if ('serviceWorker' in navigator) { navigator.serviceWorker - .register('/service-worker.js') + .register('service-worker.js') .then(serviceWorker => { console.log('Service Worker registered'); window.serviceWorker = serviceWorker @@ -99,6 +99,7 @@ class PairDrop { "styles/deferred-styles.css" ]; this.deferredScripts = [ + "scripts/browser-tabs-connector.js", "scripts/util.js", "scripts/network.js", "scripts/ui.js", diff --git a/public/scripts/ui-main.js b/public/scripts/ui-main.js index 0ff5810..6d787ef 100644 --- a/public/scripts/ui-main.js +++ b/public/scripts/ui-main.js @@ -271,8 +271,8 @@ class BackgroundCanvas { drawCircle(ctx, radius) { ctx.beginPath(); ctx.lineWidth = 2; - let opacity = Math.max(0, 0.3 * (1 - 1 * radius / Math.max(this.w, this.h))); - ctx.strokeStyle = `rgba(128, 128, 128, ${opacity})`; + let opacity = Math.max(0, 0.3 * (1 - 1.2 * radius / Math.max(this.w, this.h))); + ctx.strokeStyle = `rgba(165, 165, 165, ${opacity})`; ctx.arc(this.x0, this.y0, radius, 0, 2 * Math.PI); ctx.stroke(); } diff --git a/public/scripts/ui.js b/public/scripts/ui.js index 3f4fc97..7899c9f 100644 --- a/public/scripts/ui.js +++ b/public/scripts/ui.js @@ -280,6 +280,8 @@ class PeersUI { class PeerUI { + static _badgeClassNames = ["badge-room-ip", "badge-room-secret", "badge-room-public-id"]; + constructor(peer, connectionHash) { this.$xInstructions = $$('x-instructions'); this.$xPeers = $$('x-peers'); @@ -330,14 +332,12 @@ class PeerUI {
-
`; this.$el.querySelector('svg use').setAttribute('xlink:href', this._icon()); this.$el.querySelector('.name').textContent = this._displayName(); this.$el.querySelector('.device-name').textContent = this._deviceName(); - this.$el.querySelector('.connection-hash').textContent = this._connectionHash; } addTypesToClassList() { @@ -569,7 +569,7 @@ class Dialog { document.activeElement.blur(); window.blur(); } - document.title = 'PairDrop'; + document.title = 'PairDrop | Transfer Files Cross-Platform. No Setup, No Signup.'; changeFavicon("images/favicon-96x96.png"); this.correspondingPeerId = undefined; } @@ -1187,8 +1187,8 @@ class PairDeviceDialog extends Dialog { // Display the QR code for the url const qr = new QRCode({ content: this._getPairUrl(), - width: 150, - height: 150, + width: 130, + height: 130, padding: 1, background: 'rgb(250,250,250)', color: 'rgb(18, 18, 18)', @@ -1392,7 +1392,7 @@ class EditPairedDevicesDialog extends Dialog { - +
` $pairedDevice @@ -1433,7 +1433,19 @@ class EditPairedDevicesDialog extends Dialog { } _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() { @@ -1556,8 +1568,8 @@ class PublicRoomDialog extends Dialog { // Display the QR code for the url const qr = new QRCode({ content: this._getShareRoomUrl(), - width: 150, - height: 150, + width: 130, + height: 130, padding: 1, background: 'rgb(250,250,250)', color: 'rgb(18, 18, 18)', @@ -1736,16 +1748,27 @@ class SendTextDialog extends Dialog { _onChange() { if (this._textInputEmpty()) { this.$submit.setAttribute('disabled', true); + // remove remaining whitespace on Firefox on text deletion + this.$text.innerText = ""; } else { 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) { this.correspondingPeerId = peerId; 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.show(); @@ -1768,8 +1791,8 @@ class SendTextDialog extends Dialog { to: this.correspondingPeerId, text: this.$text.innerText }); - this.$text.innerText = ""; this.hide(); + setTimeout(() => this.$text.innerText = "", 300); } } @@ -1818,7 +1841,7 @@ class ReceiveTextDialog extends Dialog { _showReceiveTextDialog(text, peerId) { 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.$text.innerText = text; @@ -1832,12 +1855,22 @@ class ReceiveTextDialog extends Dialog { }); } + this._evaluateOverflowing(); + this._setDocumentTitleMessages(); changeFavicon("images/favicon-96x96-notification.png"); this.show(); } + _evaluateOverflowing() { + if (this.$text.clientHeight < this.$text.scrollHeight) { + this.$text.classList.add('overflowing'); + } else { + this.$text.classList.remove('overflowing'); + } + } + _setDocumentTitleMessages() { document.title = !this._receiveTextQueue.length ? `${ 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; - } -} \ No newline at end of file diff --git a/public/styles/deferred-styles.css b/public/styles/deferred-styles.css index 8fe43eb..bef550c 100644 --- a/public/styles/deferred-styles.css +++ b/public/styles/deferred-styles.css @@ -1,27 +1,46 @@ /* All styles in this sheet are not needed on page load and deferred */ -/* Peers */ - -x-peers.overflowing { - 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), .2), rgba(var(--text-color), 0)), - radial-gradient(farthest-side at 50% 100%, rgba(var(--text-color), .2), rgba(var(--text-color), 0)) 0 100%; - - background-repeat: no-repeat; - background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px; - - /* Opera doesn't support this in the shorthand */ - background-attachment: local, local, scroll, scroll; +/* Paste mode */ +#cancel-paste-mode { + z-index: 21; + 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); } +/* 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) { --peers-per-row: 10; } -/* peers-per-row if height is too small for 2 rows */ -@media screen and (min-height: 538px) and (max-height: 683px) and (max-width: 402px), -screen and (min-height: 517px) and (max-height: 664px) and (min-width: 426px) { +@media screen and (min-height: 505px) and (max-height: 649px) and (max-width: 426px), +screen and (min-height: 486px) and (max-height: 631px) and (min-width: 426px) { x-peers:has(> x-peer) { --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: 683px) and (max-width: 402px), -screen and (min-height: 664px) and (min-width: 426px) { +@media screen and (min-height: 649px) and (max-width: 425px), +screen and (min-height: 631px) and (min-width: 426px) { x-peers:has(> x-peer) { --peers-per-row: 3; } @@ -99,6 +117,11 @@ x-peer { flex-wrap: wrap; } +x-peer input[type="file"] { + visibility: hidden; + position: absolute; +} + x-peer label { width: var(--peer-width); touch-action: manipulation; @@ -119,48 +142,60 @@ x-peer .icon-wrapper { width: var(--icon-size); padding: 12px; 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; display: flex; } 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 { - background: var(--public-room-color); + --accent-color: var(--public-room-color); } -x-peer x-icon > .highlight-wrapper { +.highlight-wrapper { align-self: center; align-items: center; margin: 7px auto 0; height: 6px; } -x-peer x-icon > .highlight-wrapper > .highlight { +.highlight { width: 15px; height: 6px; border-radius: 4px; margin-left: 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; } -x-peer.type-ip x-icon > .highlight-wrapper > .highlight.highlight-room-ip { - background-color: var(--primary-color); - display: inline; +x-peer:not(.type-secret) .highlight-room-secret { + display: none; } -x-peer.type-secret x-icon > .highlight-wrapper > .highlight.highlight-room-secret { - background-color: var(--paired-device-color); - 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(.type-public-id) .highlight-room-public-id { + display: none; } x-peer:not([status]):hover x-icon, @@ -174,7 +209,6 @@ x-peer[status] x-icon { transform: scale(1); } - x-peer.ws-peer { margin-top: -1.5px; } @@ -213,18 +247,8 @@ x-peer.ws-peer .highlight-wrapper { } .status, -.device-name, -.connection-hash { - opacity: 0.7; -} - .device-name { - font-size: 14px; - white-space: nowrap; -} - -.connection-hash { - font-size: 12px; + opacity: 0.7; white-space: nowrap; } @@ -256,14 +280,13 @@ x-peer[drop] x-icon { } - Dialog +/* Dialog */ x-dialog x-background { - background: rgba(0, 0, 0, 0.61); - z-index: 10; + background: rgba(0, 0, 0, 0.8); + z-index: 30; transition: opacity 300ms; will-change: opacity; - padding: 15px; overflow: overlay; } @@ -272,8 +295,7 @@ x-dialog x-paper { flex-direction: column; width: calc(100vw - 10px); z-index: 3; - background: white; - border-radius: 8px; + border-radius: 30px; max-width: 400px; overflow: hidden; box-sizing: border-box; @@ -292,8 +314,8 @@ x-dialog x-paper { x-paper > .row:first-of-type { background-color: var(--accent-color); - border-bottom: solid 4px var(--border-color); - margin-bottom: 10px; + padding: 10px; + margin-bottom: 5px; } x-paper > .row:first-of-type h2 { @@ -339,7 +361,6 @@ x-dialog a { width: 100%; display: flex; justify-content: center; - margin-top: 10px; } .input-key-container > input { @@ -372,20 +393,22 @@ x-dialog a { -moz-user-select: text; user-select: text; display: inline-block; - font-size: 50px; + font-size: 45px; letter-spacing: min(calc((100vw - 80px - 99px) / 100 * 7), 20px); text-indent: calc(0.5 * (11px + min(calc((100vw - 80px - 99px) / 100 * 6), 28px))); - margin: 25px 0; + margin: 10px 0; } .key-qr-code { - margin: 16px; width: fit-content; align-self: center; + margin-top: 15px; + margin-bottom: 10px; } .key-instructions { flex-direction: column; + margin: 0; } x-dialog h2 { @@ -394,19 +417,19 @@ x-dialog h2 { } x-dialog hr { - height: 3px; + height: 1px; border: none; width: 100%; background-color: var(--border-color); } .hr-note { - margin-top: 10px; - margin-bottom: 20px; + margin-top: 23px; + margin-bottom: 31px; } .hr-note hr { - margin-bottom: -2px; + margin-bottom: -1px; } .hr-note > div { @@ -417,9 +440,9 @@ x-dialog hr { .hr-note > div > span { padding: 3px 10px; - border-radius: 10px; + border-radius: 20px; color: rgb(var(--text-color)); - background-color: rgb(var(--bg-color)); + background-color: var(--dialog-bg-color); border: var(--border-color) solid 3px; text-transform: uppercase; } @@ -438,20 +461,10 @@ x-dialog hr { } .paired-devices-wrapper { - border-top: solid 4px var(--paired-device-color); + margin-top: -5px; border-bottom: solid 4px var(--paired-device-color); max-height: 65vh; 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 { @@ -515,44 +528,41 @@ x-dialog hr { text-overflow: ellipsis; } -/* Receive Dialog */ - -x-paper > .row { - padding: 10px; -} - /* button row*/ x-paper > .button-row { - border-top: solid 3px var(--border-color); height: 50px; - margin-top: 10px; + margin: 5px 10px 10px; } -x-paper > .button-row > .button { +x-paper > .button-row > .btn { height: 100%; width: 100%; } -html:not([dir="rtl"]) x-paper > .button-row > .button:not(:first-child) { - border-right: solid 1.5px var(--border-color); +html:not([dir="rtl"]) x-paper > .button-row > .btn:not(:first-child) { + margin-right: 5px; } -html:not([dir="rtl"]) x-paper > .button-row > .button:not(:last-child) { - border-left: solid 1.5px var(--border-color); +html:not([dir="rtl"]) x-paper > .button-row > .btn:not(:last-child) { + margin-left: 5px; } -html[dir="rtl"] x-paper > .button-row > .button:not(:first-child) { - border-left: solid 1.5px var(--border-color); +html[dir="rtl"] x-paper > .button-row > .btn:not(:first-child) { + margin-right: 5px; } -html[dir="rtl"] x-paper > .button-row > .button:not(:last-child) { - border-right: solid 1.5px var(--border-color); +html[dir="rtl"] x-paper > .button-row > .btn:not(:last-child) { + margin-left: 5px; } .language-buttons > button > span { margin: 0 0.3em; } +.language-buttons > button { + min-height: 36px; +} + .file-description { max-width: 100%; } @@ -581,31 +591,37 @@ x-dialog .dialog-subheader { padding-bottom: 16px; } -#send-text-dialog .display-name-wrapper { +.display-name-wrapper { padding-bottom: 0; } -#text-input { - min-height: 200px; - width: 100%; +#send-text-dialog, +#receive-text-dialog { + 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 #text { - width: 100%; word-break: break-all; - max-height: calc(100vh - 393px); + max-height: 400px; + padding: 10px; overflow-x: hidden; - overflow-y: auto; + overflow-y: scroll; -webkit-user-select: text; -moz-user-select: text; user-select: text; - white-space: pre-wrap; -} - -#receive-text-dialog #text a { - cursor: pointer; } #receive-text-dialog #text a:hover { @@ -618,17 +634,11 @@ x-dialog .dialog-subheader { pointer-events: none; } -.row-separator { - border-bottom: solid 2.5px var(--border-color); - margin: auto -24px; -} - #base64-paste-btn, #base64-paste-dialog .textarea { width: 100%; height: 40vh; border: solid 12px #438cff; - border-radius: 8px; } #base64-paste-dialog .textarea { @@ -639,7 +649,7 @@ x-dialog .dialog-subheader { } #base64-paste-dialog .textarea::before { - font-size: 15px; + font-size: 14px; letter-spacing: 0.12em; color: var(--primary-color); font-weight: 700; @@ -647,7 +657,6 @@ x-dialog .dialog-subheader { white-space: pre-wrap; } - /* Peer loading Indicator */ .progress { @@ -679,7 +688,6 @@ x-dialog .dialog-subheader { transform: rotate(180deg); } - /* Color Themes */ @@ -687,7 +695,7 @@ x-dialog .dialog-subheader { /* Colored Elements */ x-dialog x-paper { - background-color: rgb(var(--bg-color)); + background-color: var(--dialog-bg-color); } .textarea { diff --git a/public/styles/styles-main.css b/public/styles/styles-main.css index ac28b04..8c74194 100644 --- a/public/styles/styles-main.css +++ b/public/styles/styles-main.css @@ -1,18 +1,5 @@ /* 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 */ html, @@ -43,6 +30,10 @@ html { width: 100%; } +.p1 { + padding: 10px; +} + .row-reverse { display: flex; flex-direction: row-reverse; @@ -90,7 +81,7 @@ header { padding: 8px 12px; box-sizing: border-box; width: 100vw; - z-index: 2; + z-index: 20; top: 0; right: 0; } @@ -163,10 +154,18 @@ header > div:hover .icon-button.selected::before { /* Typography */ +@font-face { + font-family: "Open Sans"; + src: url('../fonts/OpenSans/static/OpenSans-Medium.ttf') format('truetype'); +} + 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; -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; + font-variant-ligatures: common-ligatures; + font-kerning: normal; } h1 { @@ -174,7 +173,7 @@ h1 { font-weight: 400; letter-spacing: -.01em; line-height: 40px; - margin: 8px 0 0; + margin: 0 0 4px; } h2 { @@ -260,7 +259,19 @@ x-noscript { 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 */ @@ -295,6 +306,28 @@ x-noscript { 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 */ x-no-peers { @@ -331,34 +364,6 @@ x-no-peers[drop-bg] * { 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 { @@ -378,16 +383,23 @@ footer .logo { } .discovery-wrapper { - font-size: 12px; - margin: 10px auto auto; - border: 3px solid var(--border-color); - border-radius: 0.5rem; + font-size: 14px; + margin: 15px auto auto; + border: 2px solid var(--border-color); padding: 2px; background-color: rgb(var(--bg-color)); transition: background-color 0.5s ease; min-height: 24px; } +.discovery-wrapper.column { + border-radius: 16px; +} + +.discovery-wrapper.row { + border-radius: 12px; +} + /*You can be discovered wrapper*/ .discovery-wrapper > div:first-of-type { padding-left: 4px; @@ -401,28 +413,32 @@ footer .logo { } .badge { - border-radius: 0.3rem/0.3rem; + border-radius: 0.4rem; padding-right: 0.3rem; padding-left: 0.3em; background-color: var(--badge-color); color: white; - transition: background-color 0.5s ease; 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 { - background-color: var(--primary-color); - border-color: var(--primary-color); + --badge-color: var(--primary-color); } .badge-room-secret { - background-color: var(--paired-device-color); - border-color: var(--paired-device-color); + --badge-color: var(--paired-device-color); } .badge-room-public-id { - background-color: var(--public-room-color); - border-color: var(--public-room-color); + --badge-color: var(--public-room-color); +} + +.known-as-wrapper { + font-size: 16px; /* prevents auto-zoom on edit */ } #display-name { @@ -470,13 +486,12 @@ x-dialog:not([show]) x-background { opacity: 0; } - /* Button */ -.button { +.btn { + font-family: "Open Sans", -apple-system, BlinkMacSystemFont, sans-serif; padding: 2px 16px 0; box-sizing: border-box; - min-height: 36px; font-size: 14px; line-height: 24px; font-weight: 700; @@ -490,13 +505,13 @@ x-dialog:not([show]) x-background { overflow: hidden; } -.button[disabled] { - color: #5B5B66; +.btn[disabled] { + color: var(--btn-disabled-color); cursor: not-allowed; } -.button, +.btn, .icon-button { position: relative; display: flex; @@ -508,7 +523,7 @@ x-dialog:not([show]) x-background { outline: none; } -.button:before, +.btn:before, .icon-button:before { content: ''; position: absolute; @@ -516,41 +531,33 @@ x-dialog:not([show]) x-background { left: 0; right: 0; bottom: 0; - background: currentColor; opacity: 0; + background-color: var(--accent-color); transition: opacity 300ms; } -.button:not([disabled]):hover:before, +.btn:not([disabled]):hover:before, .icon-button:hover:before { opacity: 0.1; } -.button[selected], +.btn[selected], .icon-button[selected] { opacity: 0.1; } -#cancel-paste-mode { - 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, +.btn:focus:before, .icon-button:focus:before { opacity: 0.2; } +.btn-rounded { + border-radius: 12px; +} +.btn-grey { + background-color: var(--bg-color-secondary); +} button::-moz-focus-inner { border: 0; @@ -567,30 +574,12 @@ button::-moz-focus-inner { 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 */ #about { color: white; - z-index: 11; + z-index: 32; overflow: hidden; pointer-events: none; text-align: center; @@ -631,7 +620,7 @@ button::-moz-focus-inner { } #about .title-wrapper > div { - margin-left: 0.5em; + margin-left: 0.4em; } #about x-background { @@ -641,10 +630,11 @@ button::-moz-focus-inner { top: calc(28px - var(--size-half)); width: var(--size); height: var(--size); - border-radius: 50%; - background: var(--primary-color); - transform: scale(0); 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 { @@ -658,12 +648,12 @@ html[dir="rtl"] #about x-background { /* Hack such that initial scale(0) isn't animated */ #about x-background { - will-change: transform; - transition: transform 800ms cubic-bezier(0.77, 0, 0.175, 1); + will-change: clip-path; + transition: clip-path 800ms cubic-bezier(0.77, 0, 0.175, 1); } #about:target x-background { - transform: scale(1); + --crop-size: var(--size); } #about .row a { @@ -687,6 +677,38 @@ canvas.circles { 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 */ x-instructions { @@ -757,36 +779,12 @@ x-peers:empty~x-instructions { } } -/* Toast */ +/* Constants */ -.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: 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); +:root { + --icon-size: 24px; + --peer-width: 120px; + color-scheme: light dark; } /* @@ -794,22 +792,82 @@ x-toast:not([show]):not(:hover) { */ /* 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 { --text-color: 51,51,51; - --bg-color: 250,250,250; /*rgb code*/ - --bg-color-test: 18,18,18; - --bg-color-secondary: #e4e4e4; + --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; } /* Dark theme colors */ body.dark-theme { --text-color: 238,238,238; - --bg-color: 18,18,18; /*rgb code*/ - --bg-color-secondary: #333; - --border-color: rgb(238,238,238); + --dialog-bg-color: #121212; + --bg-color: 0,0,0; + --bg-color-secondary: #262628; + --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; +} + +/* 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 */ @@ -819,26 +877,41 @@ body { transition: background-color 0.5s ease; } -/* Styles for users who prefer dark mode at the OS level */ -@media (prefers-color-scheme: dark) { +x-dialog x-paper { + 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; +.textarea { + color: rgb(var(--text-color)) !important; + background-color: var(--bg-color-secondary) !important; +} + +.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); } +} - /* Override dark mode with light mode styles if the user decides to swap */ - body.light-theme { - --text-color: 51,51,51; - --bg-color: 250,250,250; /*rgb code*/ - --bg-color-secondary: #e4e4e4; - --border-color: rgb(169, 169, 169); - --badge-color: #a5a5a5; - } +#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; user-select: text; } +