mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-03-24 18:31:26 +01:00
Merge pull request #517 from eitchtee/dev
feat(frontend): add pull to refresh for iOS PWA
This commit is contained in:
@@ -9,9 +9,10 @@
|
||||
{% include 'includes/scripts/hyperscript/sounds.html' %}
|
||||
{% include 'includes/scripts/hyperscript/swal.html' %}
|
||||
{% include 'includes/scripts/hyperscript/autosize.html' %}
|
||||
{% include 'includes/scripts/pull_to_refresh_i18n.html' %}
|
||||
|
||||
<script defer>
|
||||
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
var tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
if (!tz) {
|
||||
tz = "UTC"
|
||||
}
|
||||
|
||||
6
app/templates/includes/scripts/pull_to_refresh_i18n.html
Normal file
6
app/templates/includes/scripts/pull_to_refresh_i18n.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% load i18n %}
|
||||
<span id="ptr-i18n"
|
||||
class="hidden"
|
||||
data-pull="{% translate 'Pull down to refresh' %}"
|
||||
data-release="{% translate 'Release to refresh' %}"
|
||||
data-refreshing="{% translate 'Refreshing' %}"></span>
|
||||
7
frontend/package-lock.json
generated
7
frontend/package-lock.json
generated
@@ -28,6 +28,7 @@
|
||||
"hyperscript.org": "^0.9.14",
|
||||
"mathjs": "^15.1.0",
|
||||
"postcss": "^8.5.6",
|
||||
"pulltorefreshjs": "^0.1.22",
|
||||
"sass": "^1.94.0",
|
||||
"sweetalert2": "^11.26.3",
|
||||
"tailwindcss": "^4.1.17",
|
||||
@@ -2309,6 +2310,12 @@
|
||||
"version": "4.2.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pulltorefreshjs": {
|
||||
"version": "0.1.22",
|
||||
"resolved": "https://registry.npmjs.org/pulltorefreshjs/-/pulltorefreshjs-0.1.22.tgz",
|
||||
"integrity": "sha512-haxNVEHnS4NCQA7NeG7TSV69z4uqy/N7nfPRuc4dPWe8H6ygUrMjdNeohE+6v0lVVX/ukSjbLYwPUGUYtFKfvQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
"hyperscript.org": "^0.9.14",
|
||||
"mathjs": "^15.1.0",
|
||||
"postcss": "^8.5.6",
|
||||
"pulltorefreshjs": "^0.1.22",
|
||||
"sass": "^1.94.0",
|
||||
"sweetalert2": "^11.26.3",
|
||||
"tailwindcss": "^4.1.17",
|
||||
|
||||
112
frontend/src/js/pulltorefresh.js
Normal file
112
frontend/src/js/pulltorefresh.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import PullToRefresh from 'pulltorefreshjs';
|
||||
|
||||
const isOverlayOpen = () => !!document.querySelector('.offcanvas.show, .swal2-container');
|
||||
|
||||
const isIosPwa = () => {
|
||||
const ua = window.navigator.userAgent.toLowerCase();
|
||||
const isIos = /iphone|ipad|ipod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
||||
const isStandalone = window.navigator.standalone === true || window.matchMedia('(display-mode: standalone)').matches;
|
||||
return true || isIos && isStandalone;
|
||||
};
|
||||
|
||||
const ptrMarkup = `
|
||||
<div class="__PREFIX__box">
|
||||
<div class="__PREFIX__content">
|
||||
<div class="__PREFIX__icon"></div>
|
||||
<div class="__PREFIX__text"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const ptrStyles = `
|
||||
.__PREFIX__ptr {
|
||||
box-shadow: inset 0 -3px 5px rgba(0, 0, 0, 0.12);
|
||||
pointer-events: none;
|
||||
font-size: 0.85em;
|
||||
font-weight: bold;
|
||||
top: 0;
|
||||
height: 0;
|
||||
transition: height 0.3s, min-height 0.3s;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
align-content: stretch;
|
||||
}
|
||||
|
||||
.__PREFIX__box {
|
||||
padding: 10px;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.__PREFIX__pull {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.__PREFIX__text {
|
||||
margin-top: .33em;
|
||||
color: var(--color-base-content);
|
||||
}
|
||||
|
||||
.__PREFIX__icon {
|
||||
color: var(--color-base-content);
|
||||
transition: transform .3s;
|
||||
}
|
||||
|
||||
/*
|
||||
When at the top of the page, disable vertical overscroll so passive touch
|
||||
listeners can take over.
|
||||
*/
|
||||
.__PREFIX__top {
|
||||
touch-action: pan-x pan-down pinch-zoom;
|
||||
}
|
||||
|
||||
.__PREFIX__release .__PREFIX__icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
`;
|
||||
|
||||
const getPtrStrings = () => {
|
||||
const ptrStringsEl = document.querySelector('#ptr-i18n');
|
||||
return {
|
||||
pull: ptrStringsEl?.dataset.pull,
|
||||
release: ptrStringsEl?.dataset.release,
|
||||
refreshing: ptrStringsEl?.dataset.refreshing
|
||||
};
|
||||
};
|
||||
|
||||
const initPullToRefresh = () => {
|
||||
const ptrStrings = getPtrStrings();
|
||||
|
||||
PullToRefresh.destroyAll();
|
||||
let ptr = PullToRefresh.init({
|
||||
mainElement: 'body',
|
||||
triggerElement: '#content',
|
||||
getMarkup() {
|
||||
return ptrMarkup;
|
||||
},
|
||||
getStyles() {
|
||||
return ptrStyles;
|
||||
},
|
||||
instructionsPullToRefresh: ptrStrings.pull || 'Pull down to refresh',
|
||||
instructionsReleaseToRefresh: ptrStrings.release || 'Release to refresh',
|
||||
instructionsRefreshing: ptrStrings.refreshing || 'Refreshing',
|
||||
shouldPullToRefresh() {
|
||||
return isIosPwa() && !isOverlayOpen() && window.scrollY === 0;
|
||||
},
|
||||
onRefresh() {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (isIosPwa()) {
|
||||
initPullToRefresh();
|
||||
|
||||
document.body.addEventListener('htmx:afterSwap', (event) => {
|
||||
if (event.detail.target === document.body) {
|
||||
initPullToRefresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -10,3 +10,4 @@ import './js/sweetalert2.js';
|
||||
import './js/style.js';
|
||||
import './js/_utils.js';
|
||||
import './js/hide_amounts.js';
|
||||
import './js/pulltorefresh.js';
|
||||
|
||||
Reference in New Issue
Block a user