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 000000000..d56c55897 --- /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 e1afafe7c..0eb9c869a 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 f739ebfb9..57c20b812 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 5cff7aaa2..22c131aee 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 facd630d8..42d892452 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 5ba1c0171..56551cdbd 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"