mirror of
https://gitlab.com/walljm/dynamicbible.git
synced 2025-07-23 07:19:50 -04:00
Merge branch 'fix-swipe-menu-bugs' into 'main'
Display Bug Fixes See merge request walljm/dynamicbible!16
This commit is contained in:
commit
743dbd4199
@ -13,7 +13,6 @@
|
||||
"serverClientId": "200739882604-i4mk6rp4mcb8n590j5kc8i6bncpm5bo1.apps.googleusercontent.com",
|
||||
"forceCodeForRefreshToken" : true
|
||||
}
|
||||
|
||||
},
|
||||
"cordova": {}
|
||||
}
|
||||
|
@ -11,8 +11,10 @@
|
||||
(cdkDropListDropped)="moveSavedPageCard($event)"
|
||||
>
|
||||
<div class="card-item" cdkDrag *ngFor="let q of savedPage.queries">
|
||||
|
||||
<span matLine><mat-icon class="page_item_icon" [ngClass]="class(q)">{{ icons(q) }}</mat-icon>{{ format(q) }}</span>
|
||||
<div class="drag-handle" cdkDragHandle>
|
||||
<mat-icon>drag_handle</mat-icon>
|
||||
</div>
|
||||
<span class="item-title" matLine><mat-icon class="page_item_icon" [ngClass]="class(q)">{{ icons(q) }}</mat-icon>{{ format(q) }}</span>
|
||||
<button mat-icon-button (click)="onRemoveCard(q)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
|
@ -3,8 +3,7 @@
|
||||
}
|
||||
|
||||
.page_item_icon {
|
||||
vertical-align: text-bottom;
|
||||
margin-right: 3px;
|
||||
margin-right: .8rem;
|
||||
}
|
||||
.card-actions {
|
||||
color: var(--page-color-primary);
|
||||
@ -26,6 +25,14 @@
|
||||
color: var(--note-color-primary);
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: move;
|
||||
display: inline-block;
|
||||
width: 3rem;
|
||||
text-align: center;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
overflow-y: auto;
|
||||
max-height: 25rem;
|
||||
@ -50,13 +57,16 @@
|
||||
border-bottom: 1px solid whitesmoke;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
cursor: move;
|
||||
background: white;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
.item-title {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-item:last-child {
|
||||
border: none;
|
||||
|
@ -54,13 +54,13 @@ export class SavedPageCardComponent extends SubscriberBase implements OnInit {
|
||||
|
||||
format(item: DataReference) {
|
||||
if (item.type === CardType.Note) {
|
||||
return `Note: ${(getFromCardCache(item, this.cache).data as NoteItem).title}`;
|
||||
return `${(getFromCardCache(item, this.cache).data as NoteItem).title}`;
|
||||
} else if (item.type === CardType.Passage) {
|
||||
return `Passage: ${item.qry}`;
|
||||
return `${item.qry}`;
|
||||
} else if (item.type === CardType.Strongs) {
|
||||
return `Strongs: ${item.qry}`;
|
||||
return `${item.qry}`;
|
||||
} else if (item.type === CardType.Word) {
|
||||
return `Word Search: ${item.qry}`;
|
||||
return `${item.qry}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -15,6 +15,5 @@ mat-card {
|
||||
padding: 0 1rem 0 1rem;
|
||||
overflow-y: scroll;
|
||||
height: calc(100vh - 66px);
|
||||
width: calc(100% - 15px);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
@ -15,6 +15,5 @@ mat-card {
|
||||
padding: 0 1rem 0 1rem;
|
||||
overflow-y: scroll;
|
||||
height: calc(100vh - 66px);
|
||||
width: calc(100% - 15px);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ export class Swipe {
|
||||
y2: 0,
|
||||
scrolling: null,
|
||||
manual: false,
|
||||
side: null,
|
||||
};
|
||||
|
||||
constructor(private leftDrawer: MatSidenav, private rightDrawer: MatSidenav, private cd: ChangeDetectorRef) {}
|
||||
@ -58,12 +59,13 @@ export class Swipe {
|
||||
this.swipeInfo.y2 = 0;
|
||||
this.swipeInfo.scrolling = null;
|
||||
this.swipeInfo.manual = false;
|
||||
this.swipeInfo.side = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles touch move events to detect if the user is attempting to scroll or swipe.
|
||||
* If the user moves the touch more than 5 px vertically then we assume the user is scrolling.
|
||||
* If the user moves the touch more than 5 px horizontally then we assume the user is swiping and disable scrolling.
|
||||
* If the user moves the touch more than 10 px horizontally then we assume the user is swiping and disable scrolling.
|
||||
* Touch end cleans up the scroll disabling.
|
||||
*/
|
||||
private bodyTouchMove(event: TouchEvent) {
|
||||
@ -75,6 +77,17 @@ export class Swipe {
|
||||
let offset = this.swipeInfo.x2 - this.swipeInfo.x1;
|
||||
const side = this.determineSide(offset);
|
||||
|
||||
// if the user swipes one direction then the other without removing the touch,
|
||||
// we should ignore it... i think...
|
||||
if (
|
||||
this.swipeInfo.side !== null &&
|
||||
this.swipeInfo.side.direction !== null &&
|
||||
this.swipeInfo.side.direction !== side.direction
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.swipeInfo.side = side;
|
||||
|
||||
// the user is swiping
|
||||
// ignore swiping if the menu is not over
|
||||
if (side.drawer.mode !== 'over') {
|
||||
@ -85,14 +98,14 @@ export class Swipe {
|
||||
let translate = 0;
|
||||
if (side.drawer.opened) {
|
||||
// if nav is open then offset should be negative
|
||||
if (this.isOpening(offset, side.drawer)) {
|
||||
if (this.isOpening(offset)) {
|
||||
return;
|
||||
}
|
||||
|
||||
translate = offset;
|
||||
} else {
|
||||
// if nav is closed then offset should be positive
|
||||
if (!this.isOpening(offset, side.drawer)) {
|
||||
if (!this.isOpening(offset)) {
|
||||
return;
|
||||
}
|
||||
// make sure the offset is not greater than sidenav width
|
||||
@ -129,43 +142,52 @@ export class Swipe {
|
||||
this.swipeInfo.y2 = t.pageY;
|
||||
|
||||
const offset = this.swipeInfo.x2 - this.swipeInfo.x1;
|
||||
const side = this.determineSide(offset);
|
||||
|
||||
// decide if we need to hide or show the sidenav
|
||||
if (this.swipeInfo.scrolling === false) {
|
||||
// enable scrolling again
|
||||
window.document.body.classList.remove('lock-scroll');
|
||||
|
||||
// restore backdrop transition
|
||||
this.backdropEl.style.transitionDuration = null;
|
||||
|
||||
// if the menu is not over then ignore
|
||||
if (side.drawer.mode !== 'over') {
|
||||
if (this.swipeInfo.side.drawer.mode !== 'over') {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the offset is < 0 and the sidenav is not open then ignore it
|
||||
// if the offset is > 0 and the sideNav is open then ignore it
|
||||
if (
|
||||
(!this.isOpening(offset, side.drawer) && !side.drawer.opened) ||
|
||||
(this.isOpening(offset, side.drawer) && side.drawer.opened)
|
||||
) {
|
||||
// if you're swiping open and the drawer is already open.
|
||||
if (this.isOpening(offset) && this.swipeInfo.side.drawer.opened) {
|
||||
console.log('ignoring end event (already open)');
|
||||
return;
|
||||
}
|
||||
|
||||
// is the offset < 50% of width then ignore and reset position
|
||||
if (Math.abs(this.swipeInfo.x2 - this.swipeInfo.x1) < side.drawer._width * 0.5) {
|
||||
// if you're swiping closed and the drawer is not open
|
||||
if (!this.isOpening(offset) && !this.swipeInfo.side.drawer.opened) {
|
||||
console.log('resetting to closed (already closed)');
|
||||
this.swipeInfo.side.el.style.transform = null;
|
||||
this.swipeInfo.side.el.style.boxShadow = 'none';
|
||||
this.backdropEl.style.visibility = null;
|
||||
if (side.drawer.opened) {
|
||||
// reset drawer position
|
||||
side.el.style.transform = 'none';
|
||||
// reset background opacity
|
||||
this.backdropEl.style.backgroundColor = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// if the change is less than the min, just ignore it.
|
||||
// this block puts everything back the way it was.
|
||||
console.log(`Offset: ${Math.abs(offset)}, Tolerance: ${this.swipeInfo.side.drawer._width * 0.08}`);
|
||||
if (Math.abs(offset) < this.swipeInfo.side.drawer._width * 0.08) {
|
||||
this.backdropEl.style.visibility = null;
|
||||
if (this.swipeInfo.side.drawer.opened) {
|
||||
// reset to open position
|
||||
console.log('resetting to open (no tolerance)');
|
||||
this.swipeInfo.side.el.style.transform = 'none';
|
||||
this.backdropEl.style.backgroundColor = 'rgba(0,0,0,0.6)';
|
||||
} else {
|
||||
// reset drawer position
|
||||
side.el.style.transform = null;
|
||||
// reset background opacity
|
||||
// reset to closed position
|
||||
console.log('resetting to closed (no tolerance)');
|
||||
this.swipeInfo.side.el.style.transform = null;
|
||||
this.swipeInfo.side.el.style.boxShadow = 'none';
|
||||
this.backdropEl.style.backgroundColor = null;
|
||||
side.el.style.boxShadow = 'none';
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -177,21 +199,23 @@ export class Swipe {
|
||||
this.disableAnimation$.next(true);
|
||||
this.cd.markForCheck();
|
||||
// wait for the end of the transition so we can reset anything we hacked to make this work
|
||||
side.el.addEventListener('transitionend', this.transitionEndHandler);
|
||||
this.swipeInfo.side.el.addEventListener('transitionend', this.transitionEndHandler);
|
||||
// wait one frame for the handler to be established before setting the transition
|
||||
requestAnimationFrame(() => {
|
||||
side.el.style.transition = '400ms cubic-bezier(0.25, 0.8, 0.25, 1)';
|
||||
this.swipeInfo.side.el.style.transition = '400ms cubic-bezier(0.25, 0.8, 0.25, 1)';
|
||||
this.cd.markForCheck();
|
||||
if (side.drawer.opened) {
|
||||
if (this.swipeInfo.side.drawer.opened) {
|
||||
console.log('manually transitioning (closed)');
|
||||
// update translate3d of sidenav so that it animates closed
|
||||
if (side.direction === 'left') {
|
||||
side.el.style.transform = `translate3d(-100%, 0, 0)`;
|
||||
if (this.swipeInfo.side.direction === 'left') {
|
||||
this.swipeInfo.side.el.style.transform = 'translate3d(-100%, 0, 0)';
|
||||
} else {
|
||||
side.el.style.transform = `translate3d(100%, 0, 0)`;
|
||||
this.swipeInfo.side.el.style.transform = 'translate3d(100%, 0, 0)';
|
||||
}
|
||||
} else {
|
||||
console.log('manually transitioning (open)');
|
||||
// update the transform on the sidenav so that it animates open
|
||||
side.el.style.transform = `none`;
|
||||
this.swipeInfo.side.el.style.transform = 'none';
|
||||
// reset background opacity
|
||||
this.backdropEl.style.backgroundColor = 'rgba(0,0,0,0.6)';
|
||||
}
|
||||
@ -200,32 +224,22 @@ export class Swipe {
|
||||
}
|
||||
|
||||
private resetDrawer() {
|
||||
const offset = this.swipeInfo.x2 - this.swipeInfo.x1;
|
||||
const side = this.determineSide(offset);
|
||||
|
||||
side.el.removeEventListener('transitionend', this.transitionEndHandler);
|
||||
|
||||
this.swipeInfo.side.el.removeEventListener('transitionend', this.transitionEndHandler);
|
||||
this.swipeInfo.side.el.style.transition = null;
|
||||
this.backdropEl.style.visibility = null;
|
||||
if (side.drawer.opened) {
|
||||
this.backdropEl.style.backgroundColor = null;
|
||||
|
||||
if (this.swipeInfo.side.drawer.opened) {
|
||||
console.log('manually transitioning (final closed)');
|
||||
// make the backdrop hide as if the sidenav is closed
|
||||
this.backdropEl.classList.remove('mat-drawer-shown');
|
||||
// reset the backgroundColor override we set so it will work normally in the future
|
||||
this.backdropEl.style.backgroundColor = null;
|
||||
// reset the transition and transform properties so the sidenav doesn't get confused when it closes
|
||||
side.el.style.transition = null;
|
||||
side.el.style.transform = 'none';
|
||||
|
||||
// update the sidenav state to closed
|
||||
side.drawer.toggle(false);
|
||||
this.swipeInfo.side.el.style.transform = 'none';
|
||||
this.swipeInfo.side.drawer.toggle(false);
|
||||
} else {
|
||||
console.log('manually transitioning (final open)');
|
||||
// make the backdrop show as if the sidenav is open
|
||||
this.backdropEl.classList.add('mat-drawer-shown');
|
||||
// reset the backgroundColor override we set so it will work normally in the future
|
||||
this.backdropEl.style.backgroundColor = null;
|
||||
// reset the transition and transform properties so the sidenav doesn't get confused when it closes
|
||||
side.el.style.transition = null;
|
||||
|
||||
side.drawer.toggle(true);
|
||||
this.swipeInfo.side.drawer.toggle(true);
|
||||
}
|
||||
|
||||
this.cd.markForCheck();
|
||||
@ -237,8 +251,8 @@ export class Swipe {
|
||||
});
|
||||
}
|
||||
|
||||
private isOpening(offset: number, drawer: MatSidenav) {
|
||||
if (drawer.position === 'end') {
|
||||
private isOpening(offset: number) {
|
||||
if (this.swipeInfo.side.direction === 'right') {
|
||||
return offset < 0; // its on the right not the left, so its inverted.
|
||||
} else {
|
||||
return offset > 0;
|
||||
@ -263,13 +277,14 @@ export class Swipe {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Math.abs(this.swipeInfo.x2 - this.swipeInfo.x1) > 5) {
|
||||
if (Math.abs(this.swipeInfo.x2 - this.swipeInfo.x1) > 10) {
|
||||
// if the user has moved more than 5 pixels x then they're swiping
|
||||
this.swipeInfo.scrolling = false;
|
||||
// disable scrolling
|
||||
window.document.body.classList.add('lock-scroll');
|
||||
if (this.isIosDevice) {
|
||||
// css overflow:hidden doesn't work on the body for iOS so we have to use a non-passive listener and preventdefault to prevent scrolling
|
||||
// css overflow:hidden doesn't work on the body for iOS so we have to use a
|
||||
// non-passive listener and preventdefault to prevent scrolling
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
@ -278,7 +293,7 @@ export class Swipe {
|
||||
return false;
|
||||
}
|
||||
|
||||
private determineSide(offset: number) {
|
||||
private determineSide(offset: number): Side {
|
||||
if (this.leftDrawer.opened) {
|
||||
return { drawer: this.leftDrawer, el: this.leftDrawerEl, direction: 'left' };
|
||||
}
|
||||
@ -298,6 +313,12 @@ export class Swipe {
|
||||
}
|
||||
}
|
||||
|
||||
interface Side {
|
||||
drawer: MatSidenav;
|
||||
el: HTMLElement;
|
||||
direction: 'left' | 'right' | null;
|
||||
}
|
||||
|
||||
export interface SwipeInfo {
|
||||
x1: number;
|
||||
y1: number;
|
||||
@ -305,6 +326,7 @@ export interface SwipeInfo {
|
||||
y2: number;
|
||||
scrolling: boolean | null;
|
||||
manual: boolean;
|
||||
side: Side;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
|
Loading…
x
Reference in New Issue
Block a user