@@ -675,6 +677,9 @@
+
+
+
diff --git a/public/scripts/localization.js b/public/scripts/localization.js
index 230e066..4d64947 100644
--- a/public/scripts/localization.js
+++ b/public/scripts/localization.js
@@ -2,7 +2,7 @@ class Localization {
constructor() {
Localization.defaultLocale = "en";
Localization.supportedLocales = ["ar", "de", "en", "es", "fr", "id", "it", "ja", "nb", "nl", "ro", "ru", "tr", "zh-CN"];
- Localization.supportedLocalesRTL = ["ar"];
+ Localization.supportedLocalesRtl = ["ar"];
Localization.translations = {};
Localization.defaultTranslations = {};
@@ -20,8 +20,12 @@ class Localization {
return Localization.supportedLocales.indexOf(locale) > -1;
}
- static isRTLLanguage(locale) {
- return Localization.supportedLocalesRTL.indexOf(locale) > -1;
+ static isRtlLanguage(locale) {
+ return Localization.supportedLocalesRtl.indexOf(locale) > -1;
+ }
+
+ static isCurrentLocaleRtl() {
+ return Localization.isRtlLanguage(Localization.locale);
}
static getSupportedOrDefault(locales) {
@@ -46,7 +50,7 @@ class Localization {
const htmlRootNode = document.querySelector('html');
- if (Localization.isRTLLanguage(locale)) {
+ if (Localization.isRtlLanguage(locale)) {
htmlRootNode.setAttribute('dir', 'rtl');
}
else {
diff --git a/public/scripts/main.js b/public/scripts/main.js
index 59c750f..530c436 100644
--- a/public/scripts/main.js
+++ b/public/scripts/main.js
@@ -1,7 +1,7 @@
class PairDrop {
constructor() {
- this.$headerNotificationButton = $('notification');
+ this.$headerNotificationBtn = $('notification');
this.$headerEditPairedDevicesBtn = $('edit-paired-devices');
this.$footerPairedDevicesBadge = $$('.discovery-wrapper .badge-room-secret');
this.$headerInstallBtn = $('install');
@@ -46,7 +46,8 @@ class PairDrop {
await this.footerUI.showLoading();
// Evaluate css shifting UI elements and fade in UI elements
- await this.evaluateUI();
+ await this.evaluatePermissionsAndRoomSecrets();
+ await this.headerUI.evaluateOverflowing();
await this.headerUI.fadeIn();
await this.footerUI._evaluateFooterBadges();
await this.footerUI.fadeIn();
@@ -87,10 +88,10 @@ class PairDrop {
return e.preventDefault();
}
- async evaluateUI() {
+ async evaluatePermissionsAndRoomSecrets() {
// Check whether notification permissions have already been granted
if ('Notification' in window && Notification.permission !== 'granted') {
- this.$headerNotificationButton.removeAttribute('hidden');
+ this.$headerNotificationBtn.removeAttribute('hidden');
}
let roomSecrets = await PersistentStorage.getAllRoomSecrets();
diff --git a/public/scripts/ui-main.js b/public/scripts/ui-main.js
index 1107121..41cf99c 100644
--- a/public/scripts/ui-main.js
+++ b/public/scripts/ui-main.js
@@ -114,12 +114,62 @@ class ThemeUI {
class HeaderUI {
constructor() {
- this.$header = $$('header.opacity-0');
+ this.$header = $$('header');
+ this.$expandBtn = $('expand');
+ Events.on("resize", _ => this.evaluateOverflowing());
+ this.$expandBtn.addEventListener('click', _ => this.onExpandBtnClick());
}
async fadeIn() {
this.$header.classList.remove('opacity-0');
}
+
+ async evaluateOverflowing() {
+ // remove and reset bracket icon before evaluating
+ this.$expandBtn.setAttribute('hidden', true);
+ this.$expandBtn.classList.add('flipped');
+
+ const rtlLocale = Localization.isCurrentLocaleRtl();
+ let icon;
+ const $headerIconsShown = document.querySelectorAll('body > header:first-of-type > *:not([hidden])');
+
+ for (let i= 1; i < $headerIconsShown.length; i++) {
+ let isFurtherLeftThanLastIcon = $headerIconsShown[i].offsetLeft >= $headerIconsShown[i-1].offsetLeft;
+ let isFurtherRightThanLastIcon = $headerIconsShown[i].offsetLeft <= $headerIconsShown[i-1].offsetLeft;
+ if ((!rtlLocale && isFurtherLeftThanLastIcon) || (rtlLocale && isFurtherRightThanLastIcon)) {
+ // we have found the first icon on second row. Use previous icon.
+ icon = $headerIconsShown[i-1];
+ break;
+ }
+ }
+ if (icon) {
+ // overflowing
+ // add overflowing-hidden class
+ this.$header.classList.add('overflow-hidden');
+ // add expand btn 2 before icon
+ this.$expandBtn.removeAttribute('hidden');
+ icon.before(this.$expandBtn);
+ }
+ else {
+ // no overflowing
+ // add overflowing-hidden class
+ this.$header.classList.remove('overflow-hidden');
+ }
+ }
+
+ onExpandBtnClick() {
+ // toggle overflowing-hidden class and flip expand btn icon
+ if (this.$header.classList.contains('overflow-hidden')) {
+ this.$header.classList.remove('overflow-hidden');
+ this.$header.classList.add('overflow-expanded');
+ this.$expandBtn.classList.remove('flipped');
+ }
+ else {
+ this.$header.classList.add('overflow-hidden');
+ this.$header.classList.remove('overflow-expanded');
+ this.$expandBtn.classList.add('flipped');
+ }
+ }
}
class CenterUI {
diff --git a/public/styles/styles-main.css b/public/styles/styles-main.css
index ae70041..e502af3 100644
--- a/public/styles/styles-main.css
+++ b/public/styles/styles-main.css
@@ -130,7 +130,7 @@ html {
}
header {
- position: absolute;
+ position: relative;
align-items: baseline;
padding: 8px 12px;
box-sizing: border-box;
@@ -140,67 +140,95 @@ header {
right: 0;
}
-header > .row-reverse > * {
+header.overflow-hidden {
+ overflow: hidden;
+}
+
+header:not(.overflow-expanded) {
+ height: 56px;
+}
+
+header > * {
margin-left: 4px;
margin-right: 4px;
}
-header > .row-reverse > div {
+header > * {
display: flex;
flex-direction: column;
align-self: flex-start;
touch-action: manipulation;
}
-header > .row-reverse > div .icon-button {
+header > .icon-button {
height: 40px;
+}
+
+header * {
transition: all 300ms;
}
-header > .row-reverse > div > div {
+#theme-wrapper > div {
display: flex;
flex-direction: column;
}
-header > .row-reverse > div:not(:hover) .icon-button:not(.selected) {
+/* expand theme buttons */
+#theme-wrapper:not(:hover) .icon-button:not(.selected) {
height: 0;
opacity: 0;
}
#theme-wrapper:hover::before {
border-radius: 20px;
- background: currentColor;
- opacity: 0.1;
+ background: var(--primary-color);
+ opacity: 0.2;
transition: opacity 300ms;
content: '';
position: absolute;
width: 40px;
+ height: 120px;
top: 0;
- bottom: 0;
margin-top: 8px;
margin-bottom: 8px;
}
-header > .row-reverse > div:hover .icon-button.selected::before {
- opacity: 0.1;
+#theme-wrapper:hover .icon-button:not(.selected):hover:before {
+ opacity: 0.3;
+}
+
+#theme-wrapper:hover .icon-button.selected::before {
+ opacity: 0.3;
}
@media (pointer: coarse) {
- header > .row-reverse > div:hover .icon-button.selected:hover::before {
- opacity: 0.2;
+ #theme-wrapper:hover .icon-button.selected:hover::before {
+ opacity: 0.3;
}
- header > .row-reverse > div .icon-button:not(.selected) {
+ #theme-wrapper .icon-button:not(.selected) {
height: 0;
opacity: 0;
pointer-events: none;
}
- header > .row-reverse > div > div {
+ #theme-wrapper > div {
flex-direction: column-reverse;
}
}
+#expand > .icon {
+ transition: transform 150ms ease-out
+}
+
+html:not([dir="rtl"]) #expand.flipped > .icon {
+ transform: rotate(-90deg);
+}
+
+html[dir="rtl"] #expand.flipped > .icon {
+ transform: rotate(90deg);
+}
+
[hidden] {
display: none !important;
}
@@ -334,19 +362,16 @@ x-noscript {
/* Animations */
+/* Opacity for elements at keyframe 100% is set on element (default 1) */
@keyframes fade-in {
0% {
opacity: 0;
}
- 100% {
- opacity: 1;
- }
}
#center {
position: relative;
display: flex;
- margin-top: 56px;
flex-direction: column-reverse;
flex-grow: 1;
justify-content: space-around;
@@ -359,18 +384,10 @@ x-noscript {
/* Peers */
-#x-peers-filler {
- display: flex;
- 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;
@@ -382,8 +399,6 @@ x-peers {
--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 */
@@ -597,6 +612,7 @@ x-dialog:not([show]) x-background {
left: 0;
right: 0;
bottom: 0;
+ z-index: -1;
opacity: 0;
background-color: var(--accent-color);
transition: opacity 300ms;
@@ -604,17 +620,17 @@ x-dialog:not([show]) x-background {
.btn:not([disabled]):hover:before,
.icon-button:hover:before {
- opacity: 0.1;
+ opacity: 0.3;
}
.btn[selected],
.icon-button[selected] {
- opacity: 0.1;
+ opacity: 0.3;
}
.btn:focus:before,
.icon-button:focus:before {
- opacity: 0.2;
+ opacity: 0.4;
}
.btn-round {
@@ -810,14 +826,12 @@ x-dialog[show] ~ div x-toast {
/* Instructions */
x-instructions {
+ display: flex;
position: relative;
opacity: 0.5;
text-align: center;
- margin-left: 10px;
- margin-right: 10px;
- display: flex;
+ margin: 50px 10px 0px;
flex-direction: column;
- flex-grow: 1;
justify-content: center;
}
@@ -834,8 +848,9 @@ x-instructions[drop-bg]:not([drop-peer]):before {
}
+x-peers:empty,
x-peers:empty~x-instructions {
- opacity: 0 !important;
+ display: none;
}
@media (hover: none) and (pointer: coarse) {