Browse Source

FF64 fixes:

Fix grid (slider) layout
Fix button dropdowns
Fix ripple
Disabled parallax
master
Eduard Kuzmenko 3 years ago
parent
commit
aae32daf16
  1. 14
      src/components/button.ts
  2. 2
      src/components/buttonIcon.ts
  3. 3
      src/components/buttonMenuToggle.ts
  4. 22
      src/components/ripple.ts
  5. 36
      src/components/sidebarRight/tabs/sharedMedia.ts
  6. 1
      src/helpers/userAgent.ts
  7. 5
      src/pages/pageSignQR.ts
  8. 10
      src/scss/partials/_button.scss
  9. 3
      src/scss/partials/_leftSidebar.scss
  10. 4
      src/scss/partials/_profile.scss
  11. 2
      src/scss/partials/_rightSidebar.scss
  12. 1
      src/scss/partials/_ripple.scss
  13. 10
      src/scss/partials/_slider.scss

14
src/components/button.ts

@ -7,8 +7,16 @@ @@ -7,8 +7,16 @@
import { i18n, LangPackKey } from "../lib/langPack";
import { ripple } from "./ripple";
const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: true, icon: string, rippleSquare: true, text: LangPackKey, disabled: boolean}> = {}) => {
const button = document.createElement('button');
const Button = (className: string, options: Partial<{
noRipple: true,
onlyMobile: true,
icon: string,
rippleSquare: true,
text: LangPackKey,
disabled: boolean,
asDiv: boolean
}> = {}) => {
const button: HTMLButtonElement = document.createElement(options.asDiv ? 'div' : 'button') as any;
button.className = className + (options.icon ? ' tgico-' + options.icon : '');
if(!options.noRipple) {
@ -24,7 +32,7 @@ const Button = (className: string, options: Partial<{noRipple: true, onlyMobile: @@ -24,7 +32,7 @@ const Button = (className: string, options: Partial<{noRipple: true, onlyMobile:
}
if(options.disabled) {
button.disabled = true;
button.setAttribute('disabled', 'true');
}
if(options.text) {

2
src/components/buttonIcon.ts

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
import Button from "./button";
const ButtonIcon = (className: string, options: Partial<{noRipple: true, onlyMobile: true}> = {}) => {
const ButtonIcon = (className: string, options: Partial<{noRipple: true, onlyMobile: true, asDiv: boolean}> = {}) => {
const button = Button('btn-icon', {icon: className, ...options});
return button;
};

3
src/components/buttonMenuToggle.ts

@ -10,7 +10,8 @@ import ButtonIcon from "./buttonIcon"; @@ -10,7 +10,8 @@ import ButtonIcon from "./buttonIcon";
import ButtonMenu, { ButtonMenuItemOptions } from "./buttonMenu";
import { closeBtnMenu, openBtnMenu } from "./misc";
const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true, listenerSetter: ListenerSetter}> = {}, direction: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right', buttons: ButtonMenuItemOptions[], onOpen?: (e: Event) => void) => {
const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true, listenerSetter: ListenerSetter, asDiv: boolean}> = {}, direction: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right', buttons: ButtonMenuItemOptions[], onOpen?: (e: Event) => void) => {
options.asDiv = true;
const button = ButtonIcon('more btn-menu-toggle', options);
const btnMenu = ButtonMenu(buttons, options.listenerSetter);

22
src/components/ripple.ts

@ -129,6 +129,11 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool @@ -129,6 +129,11 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
//});
};
const isRippleUnneeded = (e: Event) => e.target !== elem && (
['BUTTON', 'A'].includes((e.target as HTMLElement).tagName)
|| findUpClassName(e.target as HTMLElement, 'c-ripple') !== r
);
// TODO: rename this variable
let touchStartFired = false;
if(isTouchSupported) {
@ -142,10 +147,7 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool @@ -142,10 +147,7 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
}
//console.log('ripple touchstart', e);
if(e.touches.length > 1
|| touchStartFired
|| (['BUTTON', 'A'].includes((e.target as HTMLElement).tagName) && e.target !== elem)
|| findUpClassName(e.target as HTMLElement, 'c-ripple') !== r) {
if(e.touches.length > 1 || touchStartFired || isRippleUnneeded(e)) {
return;
}
@ -174,17 +176,17 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool @@ -174,17 +176,17 @@ export function ripple(elem: HTMLElement, callback: (id: number) => Promise<bool
}
//console.log('ripple mousedown', e, e.target, findUpClassName(e.target as HTMLElement, 'c-ripple') === r);
if(elem.dataset.ripple === '0' || findUpClassName(e.target as HTMLElement, 'c-ripple') !== r || (e.target as HTMLElement).tagName === 'A') {
return false;
if(elem.dataset.ripple === '0' || isRippleUnneeded(e)) {
return;
} else if(touchStartFired) {
touchStartFired = false;
return false;
return;
}
let {clientX, clientY} = e;
drawRipple(clientX, clientY);
window.addEventListener('mouseup', handler, {once: true});
window.addEventListener('contextmenu', handler, {once: true});
});
window.addEventListener('mouseup', handler, {once: true, passive: true});
window.addEventListener('contextmenu', handler, {once: true, passive: true});
}, {passive: true});
}
}

36
src/components/sidebarRight/tabs/sharedMedia.ts

@ -44,6 +44,7 @@ import PopupPickUser from "../../popups/pickUser"; @@ -44,6 +44,7 @@ import PopupPickUser from "../../popups/pickUser";
import PopupPeer from "../../popups/peer";
import Scrollable from "../../scrollable";
import { isTouchSupported } from "../../../helpers/touchSupport";
import { isFirefox } from "../../../helpers/userAgent";
let setText = (text: string, row: Row) => {
//fastRaf(() => {
@ -52,6 +53,8 @@ let setText = (text: string, row: Row) => { @@ -52,6 +53,8 @@ let setText = (text: string, row: Row) => {
//});
};
const PARALLAX_SUPPORTED = !isFirefox;
type ListLoaderResult<T> = {count: number, items: any[]};
class ListLoader<T> {
public current: T;
@ -164,14 +167,16 @@ class ListLoader<T> { @@ -164,14 +167,16 @@ class ListLoader<T> {
}
class PeerProfileAvatars {
public static BASE_CLASS = 'profile-avatars';
private static BASE_CLASS = 'profile-avatars';
private static SCALE = PARALLAX_SUPPORTED ? 2 : 1;
private static TRANSLATE_TEMPLATE = PARALLAX_SUPPORTED ? `translate3d({x}, 0, -1px) scale(${PeerProfileAvatars.SCALE})` : 'translate({x}, 0)';
public container: HTMLElement;
public avatars: HTMLElement;
public gradient: HTMLElement;
public info: HTMLElement;
public tabs: HTMLDivElement;
public listLoader: ListLoader<string | Message.messageService>;
public peerId: number;
private tabs: HTMLDivElement;
private listLoader: ListLoader<string | Message.messageService>;
private peerId: number;
constructor(public scrollable: Scrollable) {
this.container = document.createElement('div');
@ -266,11 +271,11 @@ class PeerProfileAvatars { @@ -266,11 +271,11 @@ class PeerProfileAvatars {
element: this.avatars,
onSwipe: (xDiff, yDiff) => {
lastDiffX = xDiff;
let lastX = x + xDiff * -2;
let lastX = x + xDiff * -PeerProfileAvatars.SCALE;
if(lastX > 0) lastX = 0;
else if(lastX < minX) lastX = minX;
this.avatars.style.transform = `translate3d(${lastX}px, 0, -1px) scale(2)`;
this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', lastX + 'px');
//console.log(xDiff, yDiff);
return false;
},
@ -294,13 +299,13 @@ class PeerProfileAvatars { @@ -294,13 +299,13 @@ class PeerProfileAvatars {
x = -width * lastIndex; */
x = rect.left - this.container.getBoundingClientRect().left;
this.avatars.style.transform = `translate3d(${x}px, 0, -1px) scale(2)`;
this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', x + 'px');
this.avatars.classList.add('no-transition');
void this.avatars.offsetLeft; // reflow
},
onReset: () => {
const addIndex = Math.ceil(Math.abs(lastDiffX) / (width / 2)) * (lastDiffX >= 0 ? 1 : -1);
const addIndex = Math.ceil(Math.abs(lastDiffX) / (width / PeerProfileAvatars.SCALE)) * (lastDiffX >= 0 ? 1 : -1);
cancelNextClick();
//console.log(addIndex);
@ -372,7 +377,8 @@ class PeerProfileAvatars { @@ -372,7 +377,8 @@ class PeerProfileAvatars {
onJump: (item, older) => {
const id = this.listLoader.index;
//const nextId = Math.max(0, id);
this.avatars.style.transform = `translate3d(-${200 * id}%, 0, -1px) scale(2)`;
const x = 100 * PeerProfileAvatars.SCALE * id;
this.avatars.style.transform = PeerProfileAvatars.TRANSLATE_TEMPLATE.replace('{x}', `-${x}%`);
const activeTab = this.tabs.querySelector('.active');
if(activeTab) activeTab.classList.remove('active');
@ -457,7 +463,9 @@ class PeerProfile { @@ -457,7 +463,9 @@ class PeerProfile {
private threadId: number;
constructor(public scrollable: Scrollable) {
if(!PARALLAX_SUPPORTED) {
this.scrollable.container.classList.add('no-parallax');
}
}
public init() {
@ -609,13 +617,17 @@ class PeerProfile { @@ -609,13 +617,17 @@ class PeerProfile {
if(oldAvatars) oldAvatars.container.replaceWith(this.avatars.container);
else this.element.prepend(this.avatars.container);
this.scrollable.container.classList.add('parallax');
if(PARALLAX_SUPPORTED) {
this.scrollable.container.classList.add('parallax');
}
return;
}
}
this.scrollable.container.classList.remove('parallax');
if(PARALLAX_SUPPORTED) {
this.scrollable.container.classList.remove('parallax');
}
if(this.avatars) {
this.avatars.container.remove();

1
src/helpers/userAgent.ts

@ -25,6 +25,7 @@ export const isAppleMobile = (/iPad|iPhone|iPod/.test(navigator.platform) || @@ -25,6 +25,7 @@ export const isAppleMobile = (/iPad|iPhone|iPod/.test(navigator.platform) ||
!ctx.MSStream;
export const isSafari = !!('safari' in ctx) || !!(userAgent && (/\b(iPad|iPhone|iPod)\b/.test(userAgent) || (!!userAgent.match('Safari') && !userAgent.match('Chrome'))))/* || true */;
export const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
export const isMobileSafari = isSafari && isAppleMobile;

5
src/pages/pageSignQR.ts

@ -161,9 +161,14 @@ let onFirstMount = async() => { @@ -161,9 +161,14 @@ let onFirstMount = async() => {
break;
default:
console.error('pageSignQR: default error:', err);
stop = true;
break;
}
return true;
}
return false;
};
await iterate(false);

10
src/scss/partials/_button.scss

@ -366,14 +366,14 @@ @@ -366,14 +366,14 @@
}
.btn-circle {
--size: 54px;
border-radius: 50%;
height: 54px;
width: 54px;
line-height: 54px;
height: var(--size);
width: var(--size) !important;
line-height: var(--size);
@include respond-to(handhelds) {
height: 46px;
width: 46px;
--size: 46px;
}
path {

3
src/scss/partials/_leftSidebar.scss

@ -357,8 +357,7 @@ @@ -357,8 +357,7 @@
}
@include respond-to(handhelds) {
width: 54px;
height: 54px;
--size: 54px;
bottom: 14px;
right: 14px;

4
src/scss/partials/_profile.scss

@ -33,6 +33,10 @@ @@ -33,6 +33,10 @@
transition: transform .2s ease-in-out;
position: absolute;
.scrollable.no-parallax & {
transform: translate(0, 0);
}
&:before {
content: " ";
top: 0;

2
src/scss/partials/_rightSidebar.scss

@ -110,7 +110,7 @@ @@ -110,7 +110,7 @@
max-height: calc((var(--vh, 1vh) * 100) - 100% - 56px);
}
} */
.scrollable {
.scrollable:not(.no-parallax) {
perspective: 0px;
perspective-origin: left top;

1
src/scss/partials/_ripple.scss

@ -57,6 +57,7 @@ @@ -57,6 +57,7 @@
//animation-timing-function: ease-out;
transition: .35s opacity, .35s background-color;
//overflow: hidden;
pointer-events: none;
.btn-menu &, .c-ripple.is-square & {
animation-name: ripple-effect-handhelds;

10
src/scss/partials/_slider.scss

@ -118,10 +118,12 @@ @@ -118,10 +118,12 @@
// }
> div {
height: 100%;
max-height: 100%;
width: 100%;
max-width: 100%;
// * can't define these rules because of old firefox, though they don't work
//height: 100%;
//max-height: 100%;
//width: 100%;
//max-width: 100%;
display: none;
flex-direction: column;
position: relative;

Loading…
Cancel
Save