FF64 fixes:
Fix grid (slider) layout Fix button dropdowns Fix ripple Disabled parallax
This commit is contained in:
parent
34766ce846
commit
aae32daf16
@ -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:
|
||||
}
|
||||
|
||||
if(options.disabled) {
|
||||
button.disabled = true;
|
||||
button.setAttribute('disabled', 'true');
|
||||
}
|
||||
|
||||
if(options.text) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
//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
|
||||
}
|
||||
//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});
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
//});
|
||||
};
|
||||
|
||||
const PARALLAX_SUPPORTED = !isFirefox;
|
||||
|
||||
type ListLoaderResult<T> = {count: number, items: any[]};
|
||||
class ListLoader<T> {
|
||||
public current: 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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -357,8 +357,7 @@
|
||||
}
|
||||
|
||||
@include respond-to(handhelds) {
|
||||
width: 54px;
|
||||
height: 54px;
|
||||
--size: 54px;
|
||||
bottom: 14px;
|
||||
right: 14px;
|
||||
|
||||
|
@ -33,6 +33,10 @@
|
||||
transition: transform .2s ease-in-out;
|
||||
position: absolute;
|
||||
|
||||
.scrollable.no-parallax & {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: " ";
|
||||
top: 0;
|
||||
|
@ -110,7 +110,7 @@
|
||||
max-height: calc((var(--vh, 1vh) * 100) - 100% - 56px);
|
||||
}
|
||||
} */
|
||||
.scrollable {
|
||||
.scrollable:not(.no-parallax) {
|
||||
perspective: 0px;
|
||||
perspective-origin: left top;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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…
Reference in New Issue
Block a user