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"