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