From 87825a0e058162e82634503c81deeff1a59634e5 Mon Sep 17 00:00:00 2001 From: Brandon Cohen Date: Sun, 11 Sep 2022 22:07:37 -0400 Subject: [PATCH] feat: pull down to refresh (#2908) * feat: pull down to refresh functionality Custom pull down to refresh added to replace the default browser pull down to refresh. This will allow you to manually reload the page if you are using it as a PWA. * test: update test to check api call correctly changed api call for test and made sure it pulls down all the way to trigger refresh * fix: changed positioning of pull to refresh Refresh indicator now has absolute positioning and will prevent the top edge from pulling down. --- cypress/e2e/pull-to-refresh.cy.ts | 25 ++++++++++++++++++ cypress/support/commands.ts | 1 + package.json | 3 +++ src/components/Layout/index.tsx | 2 ++ src/components/PullToRefresh/index.tsx | 36 ++++++++++++++++++++++++++ src/styles/globals.css | 20 ++++++++++++++ yarn.lock | 15 +++++++++++ 7 files changed, 102 insertions(+) create mode 100644 cypress/e2e/pull-to-refresh.cy.ts create mode 100644 src/components/PullToRefresh/index.tsx diff --git a/cypress/e2e/pull-to-refresh.cy.ts b/cypress/e2e/pull-to-refresh.cy.ts new file mode 100644 index 00000000..d56c5589 --- /dev/null +++ b/cypress/e2e/pull-to-refresh.cy.ts @@ -0,0 +1,25 @@ +describe('Pull To Refresh', () => { + beforeEach(() => { + cy.login(Cypress.env('ADMIN_EMAIL'), Cypress.env('ADMIN_PASSWORD')); + cy.viewport(390, 844); + cy.visitMobile('/'); + }); + + it('reloads the current page', () => { + cy.wait(500); + + cy.intercept({ + method: 'GET', + url: '/api/v1/*', + }).as('apiCall'); + + cy.get('.searchbar').swipe('bottom', [190, 400]); + + cy.wait('@apiCall').then((interception) => { + assert.isNotNull( + interception.response.body, + 'API was called and received data' + ); + }); + }); +}); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index e1afafe7..0eb9c869 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,4 +1,5 @@ /// +import 'cy-mobile-commands'; Cypress.Commands.add('login', (email, password) => { cy.session( diff --git a/package.json b/package.json index f739ebfb..57c20b81 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "openpgp": "5.4.0", "plex-api": "5.3.2", "pug": "3.0.2", + "pulltorefreshjs": "0.1.22", "react": "18.2.0", "react-ace": "10.1.0", "react-animate-height": "2.1.2", @@ -116,6 +117,7 @@ "@types/node": "17.0.36", "@types/node-schedule": "2.1.0", "@types/nodemailer": "6.4.5", + "@types/pulltorefreshjs": "0.1.5", "@types/react": "18.0.17", "@types/react-dom": "18.0.6", "@types/react-transition-group": "4.4.5", @@ -133,6 +135,7 @@ "babel-plugin-react-intl-auto": "3.3.0", "commitizen": "4.2.5", "copyfiles": "2.4.1", + "cy-mobile-commands": "0.3.0", "cypress": "10.6.0", "cz-conventional-changelog": "3.3.0", "eslint": "8.22.0", diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 5cff7aaa..22c131ae 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -1,6 +1,7 @@ import SearchInput from '@app/components/Layout/SearchInput'; import Sidebar from '@app/components/Layout/Sidebar'; import UserDropdown from '@app/components/Layout/UserDropdown'; +import PullToRefresh from '@app/components/PullToRefresh'; import type { AvailableLocale } from '@app/context/LanguageContext'; import useLocale from '@app/hooks/useLocale'; import useSettings from '@app/hooks/useSettings'; @@ -57,6 +58,7 @@ const Layout = ({ children }: LayoutProps) => { setSidebarOpen(false)} />
+
{ + useEffect(() => { + PR.init({ + mainElement: '#pull-to-refresh', + onRefresh() { + Router.reload(); + }, + iconArrow: ReactDOMServer.renderToString( + + ), + iconRefreshing: ReactDOMServer.renderToString( + + ), + instructionsPullToRefresh: ReactDOMServer.renderToString(
), + instructionsReleaseToRefresh: ReactDOMServer.renderToString(
), + instructionsRefreshing: ReactDOMServer.renderToString(
), + distReload: 55, + }); + return () => { + PR.destroyAll(); + }; + }, []); + + return
; +}; + +export default PullToRefresh; diff --git a/src/styles/globals.css b/src/styles/globals.css index facd630d..42d89245 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -11,6 +11,7 @@ body { @apply bg-gray-900; + overscroll-behavior-y: contain; } code { @@ -453,3 +454,22 @@ } } } + +.ptr--ptr { + box-shadow: initial !important; + position: absolute !important; + z-index: 30 !important; +} + +.ptr--refresh { + overflow: visible !important; + z-index: 30 !important; +} + +.ptr--pull { + z-index: 30 !important; +} + +.ptr--ptr .ptr--box { + margin-bottom: -13px !important; +} diff --git a/yarn.lock b/yarn.lock index 5ba1c017..56551cdb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3047,6 +3047,11 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/pulltorefreshjs@0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@types/pulltorefreshjs/-/pulltorefreshjs-0.1.5.tgz#f15c9dbc91b8fdd8135093d81ece9e9d4d2324d7" + integrity sha512-/VRTgBettvBg1KI8mGnA9oeWs359tTXQ7qsxLuXnksL88jvK6ZNMStG5T9x9vUO9O7jLsgREB0cElz/BWFfdew== + "@types/qs@*": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -4942,6 +4947,11 @@ csurf@1.11.0: csrf "3.1.0" http-errors "~1.7.3" +cy-mobile-commands@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/cy-mobile-commands/-/cy-mobile-commands-0.3.0.tgz#2bf242093149154d846b755977da197b4730429e" + integrity sha512-Bj5P2ylw88hPqolLu68xWB6euVH5uNt8zyh+Ju8sBukGv39mWZxpjp6LtnUX/LK/YMthwvILYHhvr9SG1TP+4w== + cypress@10.6.0: version "10.6.0" resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe" @@ -10157,6 +10167,11 @@ pug@3.0.2, pug@^3.0.2: pug-runtime "^3.0.1" pug-strip-comments "^2.0.0" +pulltorefreshjs@0.1.22: + version "0.1.22" + resolved "https://registry.yarnpkg.com/pulltorefreshjs/-/pulltorefreshjs-0.1.22.tgz#ddb5e3feee0b2a49fd46e1b18e84fffef2c47ac0" + integrity sha512-haxNVEHnS4NCQA7NeG7TSV69z4uqy/N7nfPRuc4dPWe8H6ygUrMjdNeohE+6v0lVVX/ukSjbLYwPUGUYtFKfvQ== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"