From 063bfc11f433a2d5665e7660e9d45d17752f2261 Mon Sep 17 00:00:00 2001 From: Tanmoy Basak Anjan Date: Thu, 4 Nov 2021 15:25:46 +0600 Subject: [PATCH] merge dev into billing (#1694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Release latest to Stage (#988) * Add French translation and set the language selection (#978) * should be almost set * dropdown styling * done with translation * nits here and there * Apply suggestions from code review Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * missing translations * add locale with dayjs * lingui extract Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: GitHub Actions * Fix design nits (#987) * setup warning * colors * icon * buttons * dropdown menu 14 * images * nits * title too big and switch buttons order * Apply suggestions from code review Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * update link closes #849 Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Michael Yankelev Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: GitHub Actions * fix link (#1025) * create buckets for new users * remove depraecated files call * [Storage] Copy cid functionality (#1437) * Copy features added, overflow issue still present * Swapped to button * lingui extract * Updated button * lingui extract * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Fixed size * lingui extract * minmax * lingui extract * revert unrelated changes * lingui extract * Apply suggestions from code review Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Tanmoy Basak Anjan Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan * [STORAGE] Rename file in bucket (#1471) * formik submit not firing * fix mobile * lingui extract * Update packages/storage-ui/src/Components/Modules/FileSystemItem/FileSystemTableItem.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * make eslint :) Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * 10min timeout for everyone (#1472) * Translated using Weblate (French) (#1478) Currently translated at 100.0% (262 of 262 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * add ui tests for search (#1479) * bump cypress to v8.3.1 (#1480) * Sharing feature explainer (#1477) * refactor modal * steps logic * image centered * lingui extract * lingui extract * typo * refactor with hook, change icon, ad to share menu * nits * fix storage building Co-authored-by: GitHub Actions * Adding multi selects on mobile view with long press (#1470) * using long press * dragg preview problems * typos * events almost ready * resets * long press options * long press updates * formats * dark mode colors * added hover with breakpoints * lingui extract * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * curly spacing * borders * clicks proper placement * reverted linting * removed preview on mobile Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * bump to 1.18.5 (#1493) * [Files] - New survey - Discord link and tiny fix (#1487) * a nice mix of things * lingui extract Co-authored-by: GitHub Actions * Translations update from Weblate (#1496) * Translated using Weblate (French) Currently translated at 100.0% (266 of 266 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (German) Currently translated at 73.3% (195 of 266 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/de/ Co-authored-by: J. Lavoie * update axios (#1498) * Added docs link (#1497) * Added doc link * lingui extract Co-authored-by: GitHub Actions * upgrade (#1501) * Published (#1503) Co-authored-by: Tanmoy Basak Anjan * Add ui tests for file preview (#1489) * Toasts refactor (#1495) * Toast content ready * toast animations * toasts before relative positioning * component ready, start integration * normal notifications ready * downloads ready * toasts ready * toasts inn storage * Toasts refactor okk * lingui extract * minor changes * Update packages/common-components/src/index.ts Co-authored-by: Ryan Noble * translates * post merge updates * translates update * progress and overrides * updates in lock file * updates ready * lingui extract * removing dark theme from storage and gaming * Update packages/common-components/src/Toasts/types.ts Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * toasts types * missed type updates * update element identifier for toast * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContent.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * download error messages * Update packages/common-components/src/Toasts/types.ts Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * lingui extract * Update packages/files-ui/src/App.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * storybooks update * using usref (#1513) Co-authored-by: GitHub Actions Co-authored-by: Ryan Noble Co-authored-by: Michael Yankelev Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Progress cancellations (#1500) * Toast content ready * toast animations * toasts before relative positioning * component ready, start integration * normal notifications ready * downloads ready * toasts ready * toasts inn storage * Toasts refactor okk * lingui extract * minor changes * Update packages/common-components/src/index.ts Co-authored-by: Ryan Noble * translates * post merge updates * translates update * progress and overrides * updates in lock file * updates ready * lingui extract * removing dark theme from storage and gaming * Update packages/common-components/src/Toasts/types.ts Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * toasts types * missed type updates * uploads ready * uploads ready * lingui extract * update element identifier for toast * cancel source tokens * toasts added * Update packages/common-components/src/stories/Toasts.stories.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContent.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/common-components/src/Toasts/ToastContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * download error messages * Update packages/common-components/src/Toasts/types.ts Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Components/Modules/FileBrowsers/SharedFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * lingui extract * resolved errors and lints * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * added closabble states * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Ryan Noble Co-authored-by: Michael Yankelev Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * survey banner on safari fix (#1512) * banner fix * Update packages/files-ui/src/Components/SurveyBanner.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * fix what I broke (#1518) Co-authored-by: Tanmoy Basak Anjan * Change the survey to a call for a user interview (#1517) * change fore a user interview call * lingui extract * Apply suggestions from code review Co-authored-by: Andrew Snaith Co-authored-by: GitHub Actions Co-authored-by: Andrew Snaith * bump cypress to v8.4 (#1521) * Translations update from Weblate (#1522) * Translated using Weblate (French) Currently translated at 100.0% (271 of 271 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (German) Currently translated at 71.9% (195 of 271 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/de/ Co-authored-by: J. Lavoie * Adjusting login screen sizes. (#1519) * login screen sizes * check for instanceof Error Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Thibaut Sardan * Gaming Dashboard overhaul (#1504) * Updating the dashboard api * Reflected functionality * lingui extract * CS favicon * Update packages/gaming-ui/src/Components/Modules/ApiKeys.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update packages/gaming-ui/src/Components/Pages/LoginPage.tsx Co-authored-by: Tanmoy Basak Anjan Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Tanmoy Basak Anjan * bulk recover operation (#1526) * recovers working * removed consoles * Add new ui tests for illogical folder and file move errors (#1520) * Add tests for illogical folder move attempts * Add new check to spec file * Finalize changes to spec file * Removed string checking following PR feedback Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Posthog Analytics Integration (#1514) * added posthog integration * Banner logic working correctly * handle uninitialized posthog * fix lint * extract messages * lingui extract * resolve warning Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Michael Yankelev Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * Translated using Weblate (French) (#1528) Currently translated at 100.0% (272 of 272 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * [Files] - Share to home or other shared folder (#1527) * share to home or other shared folder * small changes for a better UX * lingui extract * lingui extract * Update packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx Co-authored-by: Tanmoy Basak Anjan * fix console warnings Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Tanmoy Basak Anjan * Folder uploads (#1515) * add basic folder upload * wire up folder uploads for modal * Rename Modal * fix types * remove types * lingui extract * fix lint * add source attribution * lingui extract * incorporate feedback * lingui extract * fix lint * Fix casing * Rename component for consistency * lingui extract * clean up types Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Ryan Noble * Translated using Weblate (French) (#1532) Currently translated at 100.0% (276 of 276 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * Don't track before opt-in (#1531) * dont track users before they opt-in * nits and remove log, calls are still fires * default to not track * lingui extract * with init check * Update packages/files-ui/src/Contexts/PosthogContext.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * [Files] - Show current bucket decryption key (#1534) * show current bucket decryption key * lingui extract Co-authored-by: GitHub Actions * [Files] - Get admin public key from the api (#1485) * bump * use api client * merge dev * lingui extract * support several keys * wih scroll because pub/decryption key are long Co-authored-by: GitHub Actions * Add lint rules for test debug commands (#1535) * prevent double opening (#1538) * Add test coverage for storage summary adjustments (#1536) * Translated using Weblate (French) (#1540) Currently translated at 100.0% (278 of 278 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * Better colors for dark mode select and tagsinput components (#1550) * better colors for dark mode * lingui extract * fix typo Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: GitHub Actions * Filter out current bucket (#1548) * filter out current bucket * Update packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx * fix color (#1555) * Fix user lookup spamming the api, and throwing (#1553) * oh yeaah * lingui extract * lingui extract * Apply suggestions from code review * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan * Upgrade Torus dependencies (#1549) * [wip] update dependencies * Revert "[wip] update dependencies" This reverts commit 04b593bbbe5f8c4c5d6e220c744aae88c2cd95e4. * update torus dependencies * fix storage test Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * reset fields for shared folders (#1577) * reset forms and fix a couple error types (#1578) * Translations update from Weblate (#1557) * Translated using Weblate (French) Currently translated at 100.0% (281 of 281 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (German) Currently translated at 69.7% (196 of 281 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/de/ Co-authored-by: J. Lavoie * hide when ther's no menu item (#1576) * Add "maintenance" label to weblate PRs automatically (#1581) * Upgrade api client and fix issue with shared folder renaming (#1582) * upgrade api client and fix issue * Update packages/files-ui/src/Contexts/FilesContext.tsx * lingui extract Co-authored-by: GitHub Actions * run lint --fix (#1585) * Gaming dashboard - API keys as cards (#1575) * Dashboard cards done * lingui extract * extra padding * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * lingui extract * Feedback * Removed link * Apply suggestions from code review * Made warning bigger * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * New navigations buttons (#1574) * wip * lingui extract * center and add posthog * Update .eslintrc.json * Add team feature fake door (#1587) * wip * modal and tracking * use data-posthog instead Co-authored-by: GitHub Actions * fix tertiary buttons (#1592) * Posthog identify user on login (#1590) * identify user on login * fix effect deps * show username if known (#1597) * remove fade effect (#1598) * Translations update from Weblate (#1599) * Translated using Weblate (French) Currently translated at 100.0% (285 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (German) Currently translated at 71.2% (203 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/de/ * Update packages/files-ui/src/locales/fr/messages.po Co-authored-by: J. Lavoie Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Mv and rm batch calls (#1596) * wire up all api calls * lingui extract * fix lint * move to helper * fix linting * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan * refresh buckets after deletion (#1604) * Toast messages update (#1602) * messages updated * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Translations update from Weblate (#1600) * Translated using Weblate (French) Currently translated at 100.0% (285 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 41.4% (118 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/nb_NO/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 41.4% (118 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/nb_NO/ * Translated using Weblate (German) Currently translated at 71.2% (203 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/de/ * Translated using Weblate (Spanish) Currently translated at 56.1% (160 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/es/ Co-authored-by: J. Lavoie Co-authored-by: Allan Nordhøy * Translated using Weblate (Norwegian Bokmål) (#1607) Currently translated at 41.4% (118 of 285 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/nb_NO/ * Fix move single file and test (#1608) * fix move single file and test * remove only * lingui extract Co-authored-by: GitHub Actions * bump cypress to v8.5 (#1609) * Migrate to API local store cache (#1591) * Updating for local store manager * lingui extract * Wired up store * lingui extract * Localstore for Files wired up * lingui extract * lingui extract * Removed done * Update packages/files-ui/src/Contexts/UserContext.tsx Co-authored-by: Tanmoy Basak Anjan Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Tanmoy Basak Anjan * webkit color added (#1612) * added resolve browser (#1613) Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Detect and dismiss toasts in ui tests (#1610) * bump cypress to v8.5 * define necessary toast identifiers * redefine toasts as separate test objects * update spec file with new toast interaction, detect and dismiss * make toast close button identifiers unique * Add more checks for toasts for greater reliability Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * update tests for unsupported preview * Transfer multiple files and folders (#1606) * initial restructure * folder transfers * sharing working as expected * sharing is ready * toasts and error handling * error messages * transfer progress ready * lingui extract * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * using reduce and handling each file share error * updated terms * lingui extract * added no files check * lingui extract * share messages * lingui extract * lint Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Translations update from Weblate (#1625) * Translated using Weblate (French) Currently translated at 100.0% (282 of 282 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (French) Currently translated at 100.0% (294 of 294 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * bump cypress to v8.6 (#1628) * bump cypress to v8.6 * lingui extract * Update test Co-authored-by: GitHub Actions * Update api error handling (#1626) * implement error handling changes * whoops missed one * lingui extract * lingui extract * resolve linting * fix TS error * lingui extract * lingui extract * fix package version * fix package versions * update create folder modal error * lingui extract * lingui extract * revert change from preview branch * lingui extract * make error handling safer * update comment for consistency * more safety added * fix linting Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Hide network requests from cypress test runner (#1643) * hide requests from the test runner window * add extra steps for test reliability Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * [Files] Fix survey banner and sharing explainer (#1634) * fix survey banner and sharing explainer * fix case where localstore is empty * add init for the 404 * Translated using Weblate (French) (#1645) Currently translated at 100.0% (289 of 289 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * Fix Webpack Build with node 17 (#1651) * Fix build for node 17 * lingui extract Co-authored-by: GitHub Actions * add ui test coverage for the survey banner (#1648) * Add Support for heic images (#1618) * add support for heic * Update packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * fix lint, useMemo * use thenable instead of async/await * fix preview tests * rename variable * remove not null check in test * resolve test issue, add loader * fix lint * update image preview test * use jpg instead of png * lingui extract * update image preview markup * fix lint * lingui extract * fix revocation * fix wrong image * remove unused ref * fix lint * Update packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx Co-authored-by: Tanmoy Basak Anjan * Update packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx * resolve openssl issue * update remaining build commands Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan * Menu dark mode colors (#1650) * colors changed * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * [EPIC] Link Sharing (#1632) * Create a link sharing from a shared folder manage access (#1619) * wip * add jose and some any on error * with jsrsasign * convert raw to PEM * valid JWT * wrap up link overview * lingui extract * Apply suggestions from code review * generic link * git add fix shared folder creation * Apply suggestions from code review Co-authored-by: Tanmoy Basak Anjan * no more hack :D * Link-sharing landing page (#1620) * link-sharing route and verification * login message * nicer messages * nits * onBrowseBucket * Apply suggestions from code review Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * fix comments * try-catch * cleanup * Update packages/files-ui/src/Components/Modules/LinkSharingModule.tsx Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * nit color * Update packages/files-ui/src/Utils/pathUtils.ts Co-authored-by: Ryan Noble Co-authored-by: Michael Yankelev Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Ryan Noble * trans * Merge dev to epic/link sharing (#1633) * update tests for unsupported preview * Transfer multiple files and folders (#1606) * initial restructure * folder transfers * sharing working as expected * sharing is ready * toasts and error handling * error messages * transfer progress ready * lingui extract * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * using reduce and handling each file share error * updated terms * lingui extract * added no files check * lingui extract * share messages * lingui extract * lint Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Translations update from Weblate (#1625) * Translated using Weblate (French) Currently translated at 100.0% (282 of 282 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (French) Currently translated at 100.0% (294 of 294 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * bump cypress to v8.6 (#1628) * bump cypress to v8.6 * lingui extract * Update test Co-authored-by: GitHub Actions * trans Co-authored-by: Michael Yankelev Co-authored-by: Tanmoy Basak Anjan Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Weblate (bot) Co-authored-by: J. Lavoie Co-authored-by: Andrew Snaith * Merge dev to epic/lin-sharing (#1653) * update tests for unsupported preview * Transfer multiple files and folders (#1606) * initial restructure * folder transfers * sharing working as expected * sharing is ready * toasts and error handling * error messages * transfer progress ready * lingui extract * Update packages/files-ui/src/Contexts/FilesContext.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * using reduce and handling each file share error * updated terms * lingui extract * added no files check * lingui extract * share messages * lingui extract * lint Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Translations update from Weblate (#1625) * Translated using Weblate (French) Currently translated at 100.0% (282 of 282 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Translated using Weblate (French) Currently translated at 100.0% (294 of 294 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * bump cypress to v8.6 (#1628) * bump cypress to v8.6 * lingui extract * Update test Co-authored-by: GitHub Actions * trans * Update api error handling (#1626) * implement error handling changes * whoops missed one * lingui extract * lingui extract * resolve linting * fix TS error * lingui extract * lingui extract * fix package version * fix package versions * update create folder modal error * lingui extract * lingui extract * revert change from preview branch * lingui extract * make error handling safer * update comment for consistency * more safety added * fix linting Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Hide network requests from cypress test runner (#1643) * hide requests from the test runner window * add extra steps for test reliability Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> * [Files] Fix survey banner and sharing explainer (#1634) * fix survey banner and sharing explainer * fix case where localstore is empty * add init for the 404 * Translated using Weblate (French) (#1645) Currently translated at 100.0% (289 of 289 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * Fix Webpack Build with node 17 (#1651) * Fix build for node 17 * lingui extract Co-authored-by: GitHub Actions * add ui test coverage for the survey banner (#1648) * Add Support for heic images (#1618) * add support for heic * Update packages/files-ui/src/Components/Modules/FileBrowsers/CSFFileBrowser.tsx Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * fix lint, useMemo * use thenable instead of async/await * fix preview tests * rename variable * remove not null check in test * resolve test issue, add loader * fix lint * update image preview test * use jpg instead of png * lingui extract * update image preview markup * fix lint * lingui extract * fix revocation * fix wrong image * remove unused ref * fix lint * Update packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx Co-authored-by: Tanmoy Basak Anjan * Update packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx * resolve openssl issue * update remaining build commands Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan Co-authored-by: Michael Yankelev Co-authored-by: Tanmoy Basak Anjan Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Weblate (bot) Co-authored-by: J. Lavoie Co-authored-by: Andrew Snaith Co-authored-by: Andrew Snaith * Apply suggestions from code review Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Michael Yankelev Co-authored-by: GitHub Actions Co-authored-by: Tanmoy Basak Anjan Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Ryan Noble Co-authored-by: Weblate (bot) Co-authored-by: J. Lavoie Co-authored-by: Andrew Snaith Co-authored-by: Andrew Snaith * Translated using Weblate (French) (#1661) Currently translated at 100.0% (299 of 299 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ Co-authored-by: J. Lavoie * add ui test coverage for the sharing explainer (#1659) * update nav identifiers * add header button identifiers * add identifiers for sharing explainer * fix mistake in identifiers * add spec file for sharing explainer tests * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Update test spec after pr feedback * lingui extract Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: GitHub Actions * Fix toast type when no files successfully shared (#1662) * fix toast type * fix lint * lingui extract Co-authored-by: GitHub Actions Co-authored-by: Andrew Snaith * Update maintenance mode message (#1669) * Files changes * update Files markup * update storage login screen * lingui extract * lingui extract * fix lint * Apply suggestions from code review Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * removed unnecessary copy * lingui extract * lingui extract * update examples Co-authored-by: GitHub Actions Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * Make intercepts in tests less version specific (#1658) * [Files] Fix home page and nav menu display issues on smaller screens (#1677) * remove absolute positioning * fix button connection * nav bar * Update AppNav.tsx (#1689) * Translations update from Weblate (#1686) * Translated using Weblate (French) Currently translated at 100.0% (300 of 300 strings) Translation: ChainSafe Files/Chainsafe Files user interface Translate-URL: https://hosted.weblate.org/projects/chainsafe-files/chainsafe-files-user-interface/fr/ * Apply suggestions from code review Co-authored-by: J. Lavoie Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> * mobile search (#1676) Co-authored-by: Tanmoy Basak Anjan * [Files] Verfy a sharing link asap and give nice error (#1674) * ugly redirect * better UX * lingui extract * consistancy * hide loader when link is invalid * typo and icon color * add button to go back * lingui extract * nice error with malformed jwt * lingui extract * redirect to / Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev <12774278+FSM1@users.noreply.github.com> Co-authored-by: Thibaut Sardan <33178835+Tbaut@users.noreply.github.com> Co-authored-by: GitHub Actions Co-authored-by: Michael Yankelev Co-authored-by: Shiva <82167447+RamidiShiva@users.noreply.github.com> Co-authored-by: Cindy Chau <47398578+sweetpea22@users.noreply.github.com> Co-authored-by: Andrew Snaith Co-authored-by: Thibaut Sardan Co-authored-by: Priom Chowdhury Co-authored-by: Ryan Noble Co-authored-by: Weblate (bot) Co-authored-by: J. Lavoie Co-authored-by: Andrew Snaith Co-authored-by: Weblate (bot) Co-authored-by: Allan Nordhøy --- .../src/Router/ConditionalRoute.tsx | 5 +- packages/files-ui/.env.example | 4 +- .../cypress/fixtures/filesTestData.ts | 3 +- packages/files-ui/cypress/support/index.ts | 14 ++ .../cypress/support/page-objects/homePage.ts | 2 + .../modals/sharingExplainerModal.ts | 5 + .../support/page-objects/navigationMenu.ts | 9 +- .../toasts/recoverSuccessToast.ts | 4 + .../cypress/tests/file-management-spec.ts | 15 +- .../cypress/tests/file-preview-spec.ts | 16 +- .../cypress/tests/sharing-explainer-spec.ts | 57 ++++++ .../cypress/tests/survey-banner-spec.ts | 74 +++++++ packages/files-ui/package.json | 10 +- .../files-ui/src/Components/FilesRoutes.tsx | 17 +- .../src/Components/Layouts/AppHeader.tsx | 40 ++-- .../src/Components/Layouts/AppNav.tsx | 16 +- .../Modules/FileBrowsers/BinFileBrowser.tsx | 3 +- .../Modules/FileBrowsers/CSFFileBrowser.tsx | 17 +- .../FileBrowsers/CreateFolderModal.tsx | 6 +- .../CreateOrEditSharedFolderModal.tsx | 16 ++ .../FileBrowsers/LinkSharing/LinkList.tsx | 176 ++++++++++++++++ .../FileBrowsers/LinkSharing/SharingLink.tsx | 145 ++++++++++++++ .../FileBrowsers/SearchFileBrowser.tsx | 2 +- .../Modules/FileBrowsers/ShareModal.tsx | 4 +- .../FileBrowsers/SharedFoldersOverview.tsx | 2 +- .../Modules/FileBrowsers/UploadFileModal.tsx | 8 +- .../Modules/FileBrowsers/hooks/useGetFile.tsx | 3 - .../hooks/useSharingExplainerModalFlag.tsx | 18 +- .../Modules/FileBrowsers/views/FilesList.tsx | 21 +- .../Components/Modules/FilePreviewModal.tsx | 51 +++-- .../Components/Modules/LinkSharingModule.tsx | 185 +++++++++++++++++ .../Modules/LoginModule/InitialScreen.tsx | 189 +++++++++++++----- .../Modules/PreviewRenderers/ImagePreview.tsx | 122 ++++++----- .../src/Components/Modules/SearchModule.tsx | 34 ++-- .../Components/Pages/LinkSharingLanding.tsx | 11 + .../src/Components/Pages/LoginPage.tsx | 18 +- .../src/Components/SharingExplainerModal.tsx | 6 +- .../files-ui/src/Components/SurveyBanner.tsx | 10 +- .../files-ui/src/Contexts/FilesContext.tsx | 9 +- .../src/Contexts/ThresholdKeyContext.tsx | 33 ++- .../files-ui/src/Contexts/UserContext.tsx | 88 ++++---- packages/files-ui/src/Themes/DarkTheme.ts | 4 +- .../files-ui/src/Utils/contentTypeGuesser.ts | 5 +- packages/files-ui/src/Utils/pathUtils.ts | 26 +++ packages/files-ui/src/locales/de/messages.po | 135 ++++++++++--- packages/files-ui/src/locales/en/messages.po | 140 ++++++++++--- packages/files-ui/src/locales/es/messages.po | 139 ++++++++++--- packages/files-ui/src/locales/fr/messages.po | 165 +++++++++++---- packages/files-ui/src/locales/no/messages.po | 140 ++++++++++--- packages/files-ui/src/serviceWorker.ts | 2 +- packages/files-ui/src/types.d.ts | 1 + packages/gaming-ui/package.json | 6 +- .../src/Components/Modules/LoginModule.tsx | 17 +- packages/gaming-ui/src/serviceWorker.ts | 2 +- packages/storage-ui/.env.example | 2 + packages/storage-ui/package.json | 6 +- .../CreateFolderModal/CreateFolderModal.tsx | 7 +- .../src/Components/Modules/LoginModule.tsx | 59 ++++-- .../UploadFileModal/UploadFileModal.tsx | 8 +- .../src/Components/StorageRoutes.tsx | 3 +- .../src/Contexts/StorageContext.tsx | 5 +- .../storage-ui/src/locales/en/messages.po | 15 +- packages/storage-ui/src/serviceWorker.ts | 2 +- yarn.lock | 87 ++++++-- 64 files changed, 1912 insertions(+), 532 deletions(-) create mode 100644 packages/files-ui/cypress/support/page-objects/modals/sharingExplainerModal.ts create mode 100644 packages/files-ui/cypress/support/page-objects/toasts/recoverSuccessToast.ts create mode 100644 packages/files-ui/cypress/tests/sharing-explainer-spec.ts create mode 100644 packages/files-ui/cypress/tests/survey-banner-spec.ts create mode 100644 packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/LinkList.tsx create mode 100644 packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx create mode 100644 packages/files-ui/src/Components/Modules/LinkSharingModule.tsx create mode 100644 packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx create mode 100644 packages/files-ui/src/types.d.ts diff --git a/packages/common-components/src/Router/ConditionalRoute.tsx b/packages/common-components/src/Router/ConditionalRoute.tsx index 004c2131a4..5237a38d92 100644 --- a/packages/common-components/src/Router/ConditionalRoute.tsx +++ b/packages/common-components/src/Router/ConditionalRoute.tsx @@ -21,7 +21,7 @@ const ConditionalRoute: React.FC = ({ exact, ...rest }) => { - const { state, pathname } = useLocation<{from?: string} | undefined>() + const { state, pathname, hash } = useLocation<{from?: string} | undefined>() const from = (state as any)?.from return = ({ ? // this may be converted into loading diff --git a/packages/files-ui/.env.example b/packages/files-ui/.env.example index 868fb0981b..cc96080ef7 100644 --- a/packages/files-ui/.env.example +++ b/packages/files-ui/.env.example @@ -16,4 +16,6 @@ REACT_APP_FILES_UUID_VERIFIER_NAME=chainsafe-uuid-testnet # Set to `mainnet` if required REACT_APP_DIRECT_AUTH_NETWORK=testnet SENTRY_AUTH_TOKEN= -REACT_APP_TEST=true \ No newline at end of file +REACT_APP_TEST=true +REACT_APP_MAINTENANCE_MODE=false +REACT_APP_MAINTENANCE_TIMESTAMP= \ No newline at end of file diff --git a/packages/files-ui/cypress/fixtures/filesTestData.ts b/packages/files-ui/cypress/fixtures/filesTestData.ts index 4b21f7812e..df4bec6e18 100644 --- a/packages/files-ui/cypress/fixtures/filesTestData.ts +++ b/packages/files-ui/cypress/fixtures/filesTestData.ts @@ -1,2 +1,3 @@ export const folderName = "Group" -export const folderPath = `/${folderName}` \ No newline at end of file +export const folderPath = `/${folderName}` +export const profileCreatedDate = "2021-05-20T21:26:36.598924Z" diff --git a/packages/files-ui/cypress/support/index.ts b/packages/files-ui/cypress/support/index.ts index cb8233c617..f0febdb6c2 100644 --- a/packages/files-ui/cypress/support/index.ts +++ b/packages/files-ui/cypress/support/index.ts @@ -28,5 +28,19 @@ Cypress.on("uncaught:exception", (err) => { } }) +// Hide fetch/XHR requests +// interim solution until cypress adds configuration support +// source https://gist.github.com/simenbrekken/3d2248f9e50c1143bf9dbe02e67f5399 +const app = window.top + +if(app != null && !app.document.head.querySelector("[data-hide-command-log-request]")) { + const style = app.document.createElement("style") + style.innerHTML = + ".command-name-request, .command-name-xhr { display: none }" + style.setAttribute("data-hide-command-log-request", "") + + app.document.head.appendChild(style) +} + // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/packages/files-ui/cypress/support/page-objects/homePage.ts b/packages/files-ui/cypress/support/page-objects/homePage.ts index cbfd7d260c..337e56f6a4 100644 --- a/packages/files-ui/cypress/support/page-objects/homePage.ts +++ b/packages/files-ui/cypress/support/page-objects/homePage.ts @@ -8,6 +8,8 @@ export const homePage = { ...fileBrowser, // home page specific file browser elements + closeBannerButton: () => cy.get("[data-cy=button-close-banner"), + surveyBanner: () => cy.get("[data-cy=banner-survey]"), newFolderButton: () => cy.get("[data-cy=button-new-folder]"), uploadButton: () => cy.get("[data-cy=button-upload-file]"), moveSelectedButton: () => cy.get("[data-testId=button-move-selected-file]"), diff --git a/packages/files-ui/cypress/support/page-objects/modals/sharingExplainerModal.ts b/packages/files-ui/cypress/support/page-objects/modals/sharingExplainerModal.ts new file mode 100644 index 0000000000..ee9af0ba93 --- /dev/null +++ b/packages/files-ui/cypress/support/page-objects/modals/sharingExplainerModal.ts @@ -0,0 +1,5 @@ +export const sharingExplainerModal = { + body: () => cy.get("[data-testId=modal-container-sharing-explainer]"), + gotItButton: () => cy.get("[data-cy=button-got-it]"), + nextButton: () => cy.get("[data-cy=button-next]") +} diff --git a/packages/files-ui/cypress/support/page-objects/navigationMenu.ts b/packages/files-ui/cypress/support/page-objects/navigationMenu.ts index a19842843e..6e332e44dc 100644 --- a/packages/files-ui/cypress/support/page-objects/navigationMenu.ts +++ b/packages/files-ui/cypress/support/page-objects/navigationMenu.ts @@ -2,12 +2,13 @@ import { basePage } from "./basePage" export const navigationMenu = { ...basePage, - homeNavButton: () => cy.get("[data-cy=home-nav]"), - binNavButton: () => cy.get("[data-cy=bin-nav]"), - settingsNavButton: () => cy.get("[data-cy=settings-nav]"), + homeNavButton: () => cy.get("[data-cy=link-home]"), + binNavButton: () => cy.get("[data-cy=link-bin]"), + settingsNavButton: () => cy.get("[data-cy=link-settings]"), + sharedNavButton: () => cy.get("[data-cy=link-shared]"), spaceUsedLabel: () => cy.get("[data-cy=label-space-used]", { timeout: 10000 }), spaceUsedProgressBar: () => cy.get("[data-cy=progress-bar-space-used]"), - sendFeedbackNavButton: () => cy.get("[data-cy=send-feedback-nav]"), + reportABugButton: () => cy.get("[data-cy=button-report-bug]"), // mobile view only signOutButton: () => cy.get("[data-cy=signout-nav]") } diff --git a/packages/files-ui/cypress/support/page-objects/toasts/recoverSuccessToast.ts b/packages/files-ui/cypress/support/page-objects/toasts/recoverSuccessToast.ts new file mode 100644 index 0000000000..19a1815be4 --- /dev/null +++ b/packages/files-ui/cypress/support/page-objects/toasts/recoverSuccessToast.ts @@ -0,0 +1,4 @@ +export const recoverSuccessToast = { + body: () => cy.get("[data-testId=toast-recover-success]", { timeout: 10000 }), + closeButton: () => cy.get("[data-testid=button-close-toast-recover-success]") +} diff --git a/packages/files-ui/cypress/tests/file-management-spec.ts b/packages/files-ui/cypress/tests/file-management-spec.ts index 67025b40c9..24ebd14914 100644 --- a/packages/files-ui/cypress/tests/file-management-spec.ts +++ b/packages/files-ui/cypress/tests/file-management-spec.ts @@ -11,6 +11,7 @@ import { moveItemModal } from "../support/page-objects/modals/moveItemModal" import { recoverItemModal } from "../support/page-objects/modals/recoverItemModal" import { deleteSuccessToast } from "../support/page-objects/toasts/deleteSuccessToast" import { moveSuccessToast } from "../support/page-objects/toasts/moveSuccessToast" +import { recoverSuccessToast } from "../support/page-objects/toasts/recoverSuccessToast" import { uploadCompleteToast } from "../support/page-objects/toasts/uploadCompleteToast" describe("File management", () => { @@ -89,12 +90,16 @@ describe("File management", () => { // ensure the home root now has the folder and file navigationMenu.homeNavButton().click() - homePage.fileItemRow().should("have.length", 2) + homePage.fileItemRow() + .should("be.visible") + .should("have.length", 2) homePage.fileItemName().should("contain.text", folderName) homePage.fileItemName().should("contain.text", $fileName) - // ensure folder already in the root cannot be moved to Home - homePage.fileItemName().contains(`${$fileName}`).click() + // ensure file already in the root cannot be moved to Home + homePage.fileItemName().contains(`${$fileName}`) + .should("be.visible") + .click() homePage.moveSelectedButton().click() moveItemModal.folderList().contains("Home").click() moveItemModal.errorLabel().should("be.visible") @@ -112,8 +117,10 @@ describe("File management", () => { // select a parent folder and initiate move action homePage.fileItemName().contains("Parent").click() homePage.moveSelectedButton().click() + moveItemModal.body().should("be.visible") // ensure folder already in the root cannot be moved to Home + moveItemModal.folderList().should("be.visible") moveItemModal.folderList().contains("Home").click() moveItemModal.body().should("be.visible") moveItemModal.errorLabel().should("be.visible") @@ -259,6 +266,8 @@ describe("File management", () => { recoverItemModal.folderList().contains("Home").click() recoverItemModal.recoverButton().safeClick() binPage.fileItemRow().should("not.exist") + recoverSuccessToast.body().should("be.visible") + recoverSuccessToast.closeButton().click() // ensure recovered file is correct navigationMenu.homeNavButton().click() diff --git a/packages/files-ui/cypress/tests/file-preview-spec.ts b/packages/files-ui/cypress/tests/file-preview-spec.ts index d20850efd3..6f2dc17cee 100644 --- a/packages/files-ui/cypress/tests/file-preview-spec.ts +++ b/packages/files-ui/cypress/tests/file-preview-spec.ts @@ -11,6 +11,7 @@ describe("File Preview", () => { // add files homePage.uploadFile("../fixtures/uploadedFiles/logo.png") homePage.uploadFile("../fixtures/uploadedFiles/text-file.txt") + homePage.fileItemRow().should("have.length", 2) // store their file names as cypress aliases for later comparison homePage.fileItemName().eq(0).invoke("text").as("fileNameA") @@ -68,19 +69,26 @@ describe("File Preview", () => { homePage.uploadFile("../fixtures/uploadedFiles/file.zip") // setup an api intercepter for download requests - cy.intercept("POST", "https://stage.imploy.site/api/v1/bucket/*/download").as("downloadRequest").then(() => { + cy.intercept("POST", "**/bucket/*/download").as("downloadRequest").then(() => { homePage.fileItemName().dblclick() previewModal.unsupportedFileLabel().should("exist") previewModal.downloadUnsupportedFileButton().should("be.visible") - cy.get("@downloadRequest").should('be.undefined') + // ensure that the file download does not start until the download button is clicked + cy.get("@downloadRequest").then(($request) => { + // retrieving the alias (spy) should yield null because posts should not have been made yet + expect($request).to.be.null + }) + + // begin the file download previewModal.downloadUnsupportedFileButton().click() + // ensure the download request contains the correct file - cy.get("@downloadRequest").its("request.body").should("contain", { + cy.wait("@downloadRequest").its("request.body").should("contain", { path: "/file.zip" }) }) - // return to the home and ensure preview menu option is not shown for unsupported file + // return to home, ensure the preview menu option is not shown for an unsupported file previewModal.closeButton().click() homePage.fileItemKebabButton().click() homePage.previewMenuOption().should("not.exist") diff --git a/packages/files-ui/cypress/tests/sharing-explainer-spec.ts b/packages/files-ui/cypress/tests/sharing-explainer-spec.ts new file mode 100644 index 0000000000..0103251ab8 --- /dev/null +++ b/packages/files-ui/cypress/tests/sharing-explainer-spec.ts @@ -0,0 +1,57 @@ +import { navigationMenu } from "../support/page-objects/navigationMenu" +import { sharingExplainerModal } from "../support/page-objects/modals/sharingExplainerModal" + +describe("Sharing Explainer", () => { + + context("desktop", () => { + + const sharingKey = "csf.dismissedSharingExplainer" + + it("User can view and dismiss the sharing explainer", () => { + // intercept and stub the response to ensure the explainer is displayed + cy.intercept("GET", "**/user/store", { + body: { [sharingKey]: "false" } + }) + + cy.web3Login() + navigationMenu.sharedNavButton().click() + sharingExplainerModal.body().should("be.visible") + + // set up a spy for the POST response + cy.intercept("POST", "**/user/store").as("storePost").then(() => { + + // dismiss the sharing explainer + sharingExplainerModal.nextButton().click() + sharingExplainerModal.nextButton().click() + sharingExplainerModal.gotItButton().click() + sharingExplainerModal.body().should("not.exist") + + // intercept POST to ensure the key was updated after the explainer is dismissed + cy.wait("@storePost").its("request.body").should("contain", { + [sharingKey]: "true" + }) + }) + }) + + it("User should not see sharing explainer if previously dismissed", () => { + cy.intercept("GET", "**/user/store", { + body: { [sharingKey]: "true" } + }) + + cy.web3Login() + + navigationMenu.sharedNavButton().click() + sharingExplainerModal.body().should("not.exist") + }) + + it("User should see the sharing explainer if api response is empty", () => { + cy.intercept("GET", "**/user/store", { + body: {} + }) + + cy.web3Login() + navigationMenu.sharedNavButton().click() + sharingExplainerModal.body().should("be.visible") + }) + }) +}) \ No newline at end of file diff --git a/packages/files-ui/cypress/tests/survey-banner-spec.ts b/packages/files-ui/cypress/tests/survey-banner-spec.ts new file mode 100644 index 0000000000..fb66f27708 --- /dev/null +++ b/packages/files-ui/cypress/tests/survey-banner-spec.ts @@ -0,0 +1,74 @@ +import { profileCreatedDate } from "../fixtures/filesTestData" +import { homePage } from "../support/page-objects/homePage" + +describe("Survey Banner", () => { + + const dismissedSurveyKey = "csf.dismissedSurveyBannerV3" + + context("desktop", () => { + + it("User can view and dismiss the survey banner", () => { + // intercept and stub the account creation date to be > 7 days + cy.intercept("GET", "**/user/profile", (req) => { + req.on("response", (res) => { + res.body.created_at = profileCreatedDate + }) + }) + + // intercept and stub the response to ensure the banner is displayed + cy.intercept("GET", "**/user/store", { + body: { [dismissedSurveyKey]: "false" } + }) + + cy.web3Login() + homePage.surveyBanner().should("be.visible") + + // set up a spy for the POST response + cy.intercept("POST", "**/user/store").as("storePost").then(() => { + + // dismiss the survey banner + homePage.closeBannerButton().click() + homePage.surveyBanner().should("not.exist") + + // intercept POST to ensure the key was updated after the banner is dismissed + cy.wait("@storePost").its("request.body").should("contain", { + [dismissedSurveyKey]: "true" + }) + }) + }) + + it("User should not see the survey banner if previously dismissed", () => { + cy.intercept("GET", "**/user/store", { + body: { [dismissedSurveyKey]: "true" } + }) + + cy.web3Login() + homePage.surveyBanner().should("not.exist") + }) + + it("User should see banner if account age is greater than 7 days and api response is empty", () => { + cy.intercept("GET", "**/user/store", { + body: {} + }) + + cy.web3Login() + homePage.surveyBanner().should("be.visible") + }) + + it("User should not see banner if account age is less than 7 days and api response is empty", () => { + // intercept and stub the account creation date to make it less than 7 days + cy.intercept("GET", "**/user/profile", (req) => { + req.on("response", (res) => { + res.body.created_at = res.body.updated_at + }) + }) + + cy.intercept("GET", "**/user/store", { + body: {} + }) + + cy.web3Login() + homePage.surveyBanner().should("not.exist") + }) + }) +}) diff --git a/packages/files-ui/package.json b/packages/files-ui/package.json index e36bc68b94..c19f77449b 100644 --- a/packages/files-ui/package.json +++ b/packages/files-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "^1.18.16", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", @@ -33,6 +33,9 @@ "ethers": "^5.4.3", "fflate": "^0.7.1", "formik": "^2.2.5", + "heic-convert": "^1.2.4", + "jsrsasign": "^10.4.1", + "key-encoder": "^2.0.3", "mime-matcher": "^1.0.5", "posthog-js": "^1.13.10", "react": "^16.14.0", @@ -63,6 +66,7 @@ "@testing-library/react": "^11.2.2", "@testing-library/user-event": "^12.5.0", "@types/jest": "^26.0.16", + "@types/jsrsasign": "^8.0.13", "@types/node": "^14.14.10", "@types/react": "^17.0.0", "@types/react-beforeunload": "^2.1.0", @@ -72,14 +76,14 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^8.5", + "cypress": "^8.6", "cypress-file-upload": "^5.0.8", "cypress-pipe": "^2.0.0" }, "scripts": { "postinstall": "yarn compile", "start": "yarn compile && craco --max_old_space_size=4096 start", - "build": "craco --max_old_space_size=4096 build", + "build": "craco --max_old_space_size=4096 --openssl-legacy-provider build ", "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "cypress open", diff --git a/packages/files-ui/src/Components/FilesRoutes.tsx b/packages/files-ui/src/Components/FilesRoutes.tsx index b90c6cd350..2d95f3d3c1 100644 --- a/packages/files-ui/src/Components/FilesRoutes.tsx +++ b/packages/files-ui/src/Components/FilesRoutes.tsx @@ -10,8 +10,12 @@ import { useThresholdKey } from "../Contexts/ThresholdKeyContext" import ShareFilesPage from "./Pages/SharedFilesPage" import SharedFoldersOverview from "./Modules/FileBrowsers/SharedFoldersOverview" import PlansPage from "./Pages/PlansPage" +import { NonceResponsePermission } from "@chainsafe/files-api-client" +import LinkSharingLanding from "./Pages/LinkSharingLanding" export const SETTINGS_BASE = "/settings" +export const LINK_SHARING_BASE = "/link-sharing" + export const ROUTE_LINKS = { Landing: "/", PrivacyPolicy: "https://files.chainsafe.io/privacy-policy", @@ -28,6 +32,8 @@ export const ROUTE_LINKS = { Plans: "/plans", SharedFolders: "/shared-overview", SharedFolderBrowserRoot: "/shared", + SharingLink: (permission: NonceResponsePermission, jwt: string, bucketEncryptionKey: string) => + `${LINK_SHARING_BASE}/${permissionPath(permission)}/${encodeURIComponent(jwt)}#${encodeURIComponent(bucketEncryptionKey)}`, SharedFolderExplorer: (bucketId: string, rawCurrentPath: string) => { // bucketId should not have a / at the end // rawCurrentPath can be empty, or / @@ -38,7 +44,8 @@ export const ROUTE_LINKS = { TeamSignup: "https://shrl.ink/cgQy" } -export const SETTINGS_PATHS = ["profile", "security", "plan"] as const +export const permissionPath = (permission: NonceResponsePermission) => permission === "read" ? "read" : "edit" +export const SETTINGS_PATHS = ["profile", "plan", "security"] as const export type SettingsPath = typeof SETTINGS_PATHS[number] const FilesRoutes = () => { @@ -49,6 +56,12 @@ const FilesRoutes = () => { [isLoggedIn, isNewDevice, publicKey, secured, shouldInitializeAccount]) return ( + { redirectPath={ROUTE_LINKS.Landing} /> svg": { + fill: constants.header.hamburger + } + }, logo: { textDecoration: "none", display: "flex", @@ -112,8 +119,7 @@ const useStyles = makeStyles( height: constants.mobileHeaderHeight, position: "absolute", width: "100%", - zIndex: zIndex?.background, - "&.active": {} + zIndex: zIndex?.background } }, options: { @@ -230,7 +236,7 @@ const AppHeader = ({ navOpen, setNavOpen }: IAppHeader) => {
+ with + setNewLinkPermission("read"), + contents: ( +
+ {readRights} +
+ ) + }, + { + onClick: () => setNewLinkPermission("write"), + contents: ( +
+ {editRights} +
+ ) + } + ]} + /> + + { + isLoading && + } + { + !isLoading && nonces.length > 0 && nonces.map((nonce) => + + ) + } + + ) +} + +export default LinkList diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx new file mode 100644 index 0000000000..882f8c64fd --- /dev/null +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/LinkSharing/SharingLink.tsx @@ -0,0 +1,145 @@ + +import { Button, DeleteSvg, Typography } from "@chainsafe/common-components" +import { createStyles, debounce, makeStyles } from "@chainsafe/common-theme" +import { NonceResponse } from "@chainsafe/files-api-client" +import { Trans } from "@lingui/macro" +import React, { useCallback, useEffect, useState } from "react" +import { useFilesApi } from "../../../../Contexts/FilesApiContext" +import { useThresholdKey } from "../../../../Contexts/ThresholdKeyContext" +import { CSFTheme } from "../../../../Themes/types" +import { ROUTE_LINKS } from "../../../FilesRoutes" +import { translatedPermission } from "./LinkList" + +const useStyles = makeStyles( + ({ constants }: CSFTheme) => { + return createStyles({ + root: { + display: "flex", + marginBottom: constants.generalUnit * 0.5 + }, + linkWrapper: { + whiteSpace: "nowrap", + marginRight: constants.generalUnit * 2, + display: "flex", + alignItems: "center", + overflow: "hidden" + }, + permissionWrapper: { + display: "flex", + alignItems: "center", + marginRight: constants.generalUnit, + flex: 1, + whiteSpace: "nowrap" + }, + copyButton: { + flex: 1, + whiteSpace: "nowrap", + marginRight: constants.generalUnit + }, + link: { + textOverflow: "ellipsis", + overflow: "hidden" + }, + menuIcon: { + display: "flex", + justifyContent: "center", + alignItems: "center", + width: 20, + marginRight: constants.generalUnit * 1.5, + fill: constants.fileSystemItemRow.menuIcon + } + }) + } +) + +interface Props { + nonce: NonceResponse + bucketEncryptionKey: string + refreshNonces: () => void +} + +const SharingLink = ({ nonce, bucketEncryptionKey, refreshNonces }: Props) => { + const classes = useStyles() + const { filesApiClient } = useFilesApi() + const [link, setLink] = useState("") + const [jwt, setJwt] = useState("") + const { createJWT } = useThresholdKey() + const [copied, setCopied] = useState(false) + const [isLoading, setIsLoading] = useState(true) + + useEffect(() => { + if(!nonce?.bucket_id || !nonce?.id) { + return + } + + const newJwt = createJWT(nonce.bucket_id, nonce.id, nonce.permission) + newJwt && setJwt(newJwt) + setIsLoading(false) + }, [createJWT, nonce]) + + useEffect(() => { + if(!jwt) { + return + } + + setLink(`${window.location.origin}${ROUTE_LINKS.SharingLink(nonce.permission, jwt, bucketEncryptionKey)}`) + }, [jwt, bucketEncryptionKey, nonce]) + + const debouncedSwitchCopied = debounce(() => setCopied(false), 3000) + + const onCopyInfo = useCallback(() => { + navigator.clipboard.writeText(link) + .then(() => { + setCopied(true) + debouncedSwitchCopied() + }) + .catch(console.error) + }, [debouncedSwitchCopied, link]) + + const onDeleteNonce = useCallback(() => { + setIsLoading(true) + filesApiClient.revokeNonce(nonce.id) + .catch(console.error) + .finally(() => { + refreshNonces() + setIsLoading(false) + }) + }, [filesApiClient, nonce, refreshNonces]) + + return ( +
+
+ + {link} + +
+
+ + {translatedPermission(nonce.permission)} + +
+ + +
+ ) +} + +export default SharingLink diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SearchFileBrowser.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SearchFileBrowser.tsx index 3fc8cd8c90..392ecc47e3 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SearchFileBrowser.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SearchFileBrowser.tsx @@ -84,7 +84,7 @@ const SearchFileBrowser: React.FC = ({ controls = false const getPath = useCallback((cid: string): string => { const searchEntry = getSearchEntry(cid) // Set like this as look ups should always be using available cids - return searchEntry ? searchEntry.path : "" + return searchEntry ? searchEntry.path.replace(searchEntry.content.name, "") : "" }, [getSearchEntry]) const pathContents: FileSystemItem[] = useMemo(() => diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx index d48f5646ab..71424d9a1b 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/ShareModal.tsx @@ -222,8 +222,7 @@ const ShareModal = ({ close, fileSystemItems }: IShareFileProps) => { label: buck.name || t`Home`, value: buck.id })) - } - , [bucket, buckets, profile, accountRestricted]) + }, [bucket, buckets, profile, accountRestricted]) const hasNoSharedBucket = useMemo(() => bucketsOptions.length === 0, [bucketsOptions.length]) @@ -325,7 +324,6 @@ const ShareModal = ({ close, fileSystemItems }: IShareFileProps) => { } -
{isUsingCurrentBucket ? ( diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx index 51f508bf0b..11043af19a 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/SharedFoldersOverview.tsx @@ -278,7 +278,7 @@ const SharedFolderOverview = () => { )} { }) refreshContents && refreshContents() helpers.resetForm() - } catch (errors: any) { - if (errors[0].message.includes("conflict with existing")) { - helpers.setFieldError("files", "File/Folder exists") - } else { - helpers.setFieldError("files", errors[0].message) - } + } catch (error: any) { + console.error(error) } helpers.setSubmitting(false) }, [close, currentPath, uploadFiles, refreshContents, bucket]) diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx index 83890133eb..4f3b9363de 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useGetFile.tsx @@ -40,7 +40,6 @@ export const useGetFile = () => { setError("") try { - const content = await getFileContent( id, { @@ -69,8 +68,6 @@ export const useGetFile = () => { setError(t`There was an error getting the preview.`) } } - - }, [bucket, getFileContent]) return { getFile, isDownloading, error, downloadProgress } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useSharingExplainerModalFlag.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useSharingExplainerModalFlag.tsx index 99d4ea335f..b5c02d9318 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useSharingExplainerModalFlag.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/hooks/useSharingExplainerModalFlag.tsx @@ -6,22 +6,20 @@ export const DISMISSED_SHARING_EXPLAINER_KEY = "csf.dismissedSharingExplainer" export const useSharingExplainerModalFlag = () => { const { localStore, setLocalStore } = useUser() - const [hasSeenSharingExplainerModal, setHasSeenSharingExplainerModal] = useState(false) - const dismissedFlag = localStore ? localStore[DISMISSED_SHARING_EXPLAINER_KEY] : null + const [hasSeenSharingExplainerModal, setHasSeenSharingExplainerModal] = useState(true) useEffect(() => { - if (dismissedFlag === "false"){ - setHasSeenSharingExplainerModal(true) - } else if (dismissedFlag === null) { - // the dismiss flag was never set - setLocalStore({ [DISMISSED_SHARING_EXPLAINER_KEY]: "false" }, "update") - setHasSeenSharingExplainerModal(true) + if (!localStore) { + return } - }, [dismissedFlag, setLocalStore]) + if (localStore[DISMISSED_SHARING_EXPLAINER_KEY] === "false"){ + setHasSeenSharingExplainerModal(false) + } + }, [localStore, setLocalStore]) const hideModal = useCallback(() => { setLocalStore({ [DISMISSED_SHARING_EXPLAINER_KEY]: "true" }, "update") - setHasSeenSharingExplainerModal(false) + setHasSeenSharingExplainerModal(true) }, [setLocalStore]) return { hasSeenSharingExplainerModal, hideModal } diff --git a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx index afe7afb892..0889c68958 100644 --- a/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx +++ b/packages/files-ui/src/Components/Modules/FileBrowsers/views/FilesList.tsx @@ -32,7 +32,6 @@ import { BrowserView, FileOperation, MoveModalMode } from "../types" import { FileSystemItem as FileSystemItemType, useFiles } from "../../../../Contexts/FilesContext" import FileSystemItem from "./FileSystemItem/FileSystemItem" import FilePreviewModal from "../../FilePreviewModal" - import CreateFolderModal from "../CreateFolderModal" import UploadFileModule from "../UploadFileModal" import MoveFileModal from "../MoveFileModal" @@ -41,7 +40,6 @@ import { CONTENT_TYPES } from "../../../../Utils/Constants" import { CSFTheme } from "../../../../Themes/types" import MimeMatcher from "../../../../Utils/MimeMatcher" import { useLanguageContext } from "../../../../Contexts/LanguageContext" -import { getPathWithFile } from "../../../../Utils/pathUtils" import SurveyBanner from "../../../SurveyBanner" import { DragPreviewLayer } from "./DragPreviewLayer" import { useFileBrowser } from "../../../../Contexts/FileBrowserContext" @@ -55,6 +53,7 @@ import { useFilesApi } from "../../../../Contexts/FilesApiContext" import RestrictedModeBanner from "../../../Elements/RestrictedModeBanner" import clsx from "clsx" import EmptySvg from "../../../../Media/Empty.svg" +import { getPathWithFile } from "../../../../Utils/pathUtils" const baseOperations: FileOperation[] = ["download", "info", "preview", "share"] const readerOperations: FileOperation[] = [...baseOperations, "report"] @@ -358,7 +357,7 @@ const FilesList = ({ isShared = false }: Props) => { const { hasSeenSharingExplainerModal, hideModal } = useSharingExplainerModalFlag() const [hasClickedShare, setClickedShare] = useState(false) const showExplainerBeforeShare = useMemo(() => - hasSeenSharingExplainerModal && hasClickedShare + !hasSeenSharingExplainerModal && hasClickedShare , [hasClickedShare, hasSeenSharingExplainerModal] ) const items: FileSystemItemType[] = useMemo(() => { @@ -626,9 +625,10 @@ const FilesList = ({ isShared = false }: Props) => { setIsDeleteModalOpen(true) }, []) - const handleOpenShareDialog = useCallback((e: React.MouseEvent) => { - e.preventDefault() - e.stopPropagation() + const handleOpenShareDialog = useCallback((e?: React.MouseEvent) => { + e?.preventDefault() + e?.stopPropagation() + setClickedShare(true) setIsShareModalOpen(true) }, []) @@ -661,14 +661,9 @@ const FilesList = ({ isShared = false }: Props) => { [classes.menuIcon, accountRestricted]) const onShare = useCallback((fileSystemItem: FileSystemItemType) => { - if(hasSeenSharingExplainerModal) { - setClickedShare(true) - } - setSelectedItems([fileSystemItem]) - setIsShareModalOpen(true) - }, [hasSeenSharingExplainerModal]) - + handleOpenShareDialog() + }, [handleOpenShareDialog]) return ( <> diff --git a/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx b/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx index cf8fac1a96..708a6c1493 100644 --- a/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx +++ b/packages/files-ui/src/Components/Modules/FilePreviewModal.tsx @@ -27,9 +27,11 @@ import { useFileBrowser } from "../../Contexts/FileBrowserContext" import { useGetFile } from "./FileBrowsers/hooks/useGetFile" import { useMemo } from "react" import Menu from "../../UI-components/Menu" +import { getPathWithFile } from "../../Utils/pathUtils" export interface IPreviewRendererProps { contents: Blob + contentType?: string } const SUPPORTED_FILE_TYPES: Record> = { @@ -196,6 +198,13 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath delta: 20 }) + const previewRendererKey = useMemo(() => content_type && + Object.keys(SUPPORTED_FILE_TYPES).find((type) => { + const matcher = new MimeMatcher(type) + + return matcher.match(content_type) + }), [content_type]) + useEffect(() => { let bucketId // Handle preview in Search where a Bucket is not available, but can be assumed to be a `CSF` bucket @@ -205,24 +214,24 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath } else { bucketId = bucket.id } - getFile({ file, filePath, bucketId }) - .then(setFileContent) - .catch(console.error) - }, [file, filePath, getFile, bucket, buckets]) - const validRendererMimeType = - content_type && - Object.keys(SUPPORTED_FILE_TYPES).find((type) => { - const matcher = new MimeMatcher(type) + if (previewRendererKey) { + setFileContent(undefined) + getFile({ file, filePath: getPathWithFile(filePath, file.name), bucketId }) + .then((content) => { + setFileContent(content) + }) + .catch(console.error) + } + }, [file, filePath, getFile, bucket, buckets, previewRendererKey]) + - return matcher.match(content_type) - }) const PreviewComponent = - content_type && - fileContent && - validRendererMimeType && - SUPPORTED_FILE_TYPES[validRendererMimeType] + !!content_type && + !!fileContent && + !!previewRendererKey && + SUPPORTED_FILE_TYPES[previewRendererKey] useHotkeys("Esc,Escape", () => { if (file) { @@ -231,15 +240,11 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath }) useHotkeys("Left,ArrowLeft", () => { - if (file && previousFile) { - previousFile() - } + previousFile && previousFile() }) useHotkeys("Right,ArrowRight", () => { - if (file && nextFile) { - nextFile() - } + nextFile && nextFile() }) const handleDownload = useCallback(() => { @@ -389,7 +394,11 @@ const FilePreviewModal = ({ file, nextFile, previousFile, closePreview, filePath !error && compatibleFilesMatcher.match(content_type) && fileContent && - PreviewComponent && } + PreviewComponent && + + }
{desktop && ( diff --git a/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx new file mode 100644 index 0000000000..db09dd02e6 --- /dev/null +++ b/packages/files-ui/src/Components/Modules/LinkSharingModule.tsx @@ -0,0 +1,185 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react" +import { Button, CheckCircleIcon, ExclamationCircleIcon, Loading, Typography, useHistory, useLocation } from "@chainsafe/common-components" +import { getBucketDecryptionFromHash, getJWT } from "../../Utils/pathUtils" +import { useFilesApi } from "../../Contexts/FilesApiContext" +import { useThresholdKey } from "../../Contexts/ThresholdKeyContext" +import { t, Trans } from "@lingui/macro" +import { useFiles } from "../../Contexts/FilesContext" +import jwtDecode from "jwt-decode" +import { createStyles, makeStyles } from "@chainsafe/common-theme" +import { CSFTheme } from "../../Themes/types" +import { ROUTE_LINKS } from "../FilesRoutes" +import { translatedPermission } from "./FileBrowsers/LinkSharing/LinkList" +import { NonceResponsePermission } from "@chainsafe/files-api-client" + +const useStyles = makeStyles( + ({ constants, palette, breakpoints }: CSFTheme) => + createStyles({ + root:{ + display: "flex", + flexDirection: "column", + alignItems: "center" + }, + box: { + backgroundColor: constants.loginModule.background, + border: `1px solid ${constants.landing.border}`, + boxShadow: constants.landing.boxShadow, + borderRadius: 6, + maxWidth: constants.generalUnit * 70, + padding: constants.generalUnit * 5, + [breakpoints.down("md")]: { + justifyContent: "center", + width: "100%" + } + }, + icon : { + display: "flex", + alignItems: "center", + fontSize: constants.generalUnit * 6, + "& svg": { + fill: palette.additional["gray"][7] + } + }, + errorMessage: { + textAlign: "center" + }, + messageWrapper: { + display: "flex", + flexDirection: "column", + justifyContent: "center", + alignItems: "center" + }, + browseButton : { + marginTop: constants.generalUnit * 2 + } + }) +) + +export interface DecodedNonceJwt { + bucket_id?: string + permission?: NonceResponsePermission + nonce_id?: string +} + +const LinkSharingModule = () => { + const { pathname, hash } = useLocation() + const { redirect } = useHistory() + const jwt = useMemo(() => getJWT(pathname), [pathname]) + const bucketDecryptionKey = useMemo(() => getBucketDecryptionFromHash(hash), [hash]) + const { filesApiClient } = useFilesApi() + const { refreshBuckets, buckets } = useFiles() + const { publicKey, encryptForPublicKey } = useThresholdKey() + const [encryptedEncryptionKey, setEncryptedEncryptionKey] = useState("") + const [error, setError] = useState("") + const classes = useStyles() + const { bucket_id: bucketId, permission, nonce_id } = useMemo(() => { + try { + return (jwt && jwtDecode(jwt)) || {} + }catch (e) { + console.error(e) + setError(t`This link is marlformed. Please verify that you copy/pasted it correctly.`) + return {} + } + }, [jwt]) + const newBucket = useMemo(() => buckets.find((b) => b.id === bucketId), [bucketId, buckets]) + const [isValidNonce, setIsValidNonce] = useState() + + useEffect(() => { + if(!nonce_id) return + + filesApiClient.isNonceValid(nonce_id) + .then((res) => { + setIsValidNonce(res.is_valid) + }) + .catch(console.error) + }, [filesApiClient, nonce_id]) + + useEffect(() => { + if(!publicKey || !bucketDecryptionKey) return + + encryptForPublicKey(publicKey, bucketDecryptionKey) + .then(setEncryptedEncryptionKey) + .catch(console.error) + + }, [bucketDecryptionKey, encryptForPublicKey, publicKey]) + + useEffect(() => { + if(!jwt || !encryptedEncryptionKey || !!newBucket || !isValidNonce) return + + filesApiClient.verifyNonce({ jwt, encryption_key: encryptedEncryptionKey }) + .catch((e:any) => { + console.error(e) + setError(e.error.message) + }) + .finally(() => { + refreshBuckets() + }) + }, [encryptedEncryptionKey, error, filesApiClient, isValidNonce, jwt, newBucket, refreshBuckets]) + + const onBrowseBucket = useCallback(() => { + newBucket && redirect(ROUTE_LINKS.SharedFolderExplorer(newBucket.id, "/")) + }, [newBucket, redirect]) + + return ( +
+
+
+ {!error && !newBucket && isValidNonce !== false && ( + <> + + + {isValidNonce === undefined + ? Verifying the link... + : Adding you to the shared folder... + } + + + + )} + {!error && newBucket && permission && isValidNonce && ( + <> + + + + You were added to the shared folder ({translatedPermission(permission)}): {newBucket.name} + + + + + )} + {(!!error || isValidNonce === false) && ( + <> + + + { isValidNonce === false + ? This link is not valid any more. + : error + } + + + )} +
+
+
+ ) +} + +export default LinkSharingModule diff --git a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx index 0da2e6c486..d8f8a5747b 100644 --- a/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx +++ b/packages/files-ui/src/Components/Modules/LoginModule/InitialScreen.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from "react" +import React, { useCallback, useEffect, useMemo, useState } from "react" import { Button, GithubLogoIcon, @@ -7,7 +7,10 @@ import { Loading, Typography, FormikTextInput, - EthereumLogoIcon + EthereumLogoIcon, + useLocation, + ExclamationCircleIcon, + useHistory } from "@chainsafe/common-components" import { createStyles, makeStyles, useThemeSwitcher } from "@chainsafe/common-theme" import { CSFTheme } from "../../../Themes/types" @@ -16,12 +19,16 @@ import { useFilesApi } from "../../../Contexts/FilesApiContext" import { useWeb3 } from "@chainsafe/web3-context" import { useThresholdKey } from "../../../Contexts/ThresholdKeyContext" import { LOGIN_TYPE } from "@toruslabs/torus-direct-web-sdk" -import { ROUTE_LINKS } from "../../FilesRoutes" +import { LINK_SHARING_BASE, ROUTE_LINKS } from "../../FilesRoutes" import clsx from "clsx" import { IdentityProvider } from "@chainsafe/files-api-client" import PasswordlessEmail from "./PasswordlessEmail" import { Form, FormikProvider, useFormik } from "formik" import { emailValidation } from "../../../Utils/validationSchema" +import { getJWT } from "../../../Utils/pathUtils" +import jwtDecode from "jwt-decode" +import { DecodedNonceJwt } from "../LinkSharingModule" +import dayjs from "dayjs" const useStyles = makeStyles( ({ constants, palette, breakpoints, typography }: CSFTheme) => @@ -34,7 +41,6 @@ const useStyles = makeStyles( borderRadius: 6, [breakpoints.up("md")]:{ minHeight: "64vh", - justifyContent: "space-between", width: 440 }, [breakpoints.down("md")]: { @@ -44,17 +50,11 @@ const useStyles = makeStyles( } }, buttonSection: { - [breakpoints.up("md")]: { - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)" - }, - [breakpoints.down("md")]: { - display: "flex", - flexDirection: "column", - justifyContent: "space-evenly" - } + display: "flex", + flexDirection: "column", + marginBottom: constants.generalUnit * 2, + alignItems: "center", + flex: 1 }, connectingWallet: { textAlign: "center", @@ -91,14 +91,14 @@ const useStyles = makeStyles( maxWidth: 240 }, headerText: { + textAlign: "center", [breakpoints.up("md")]: { paddingTop: constants.generalUnit * 4, paddingBottom: constants.generalUnit * 8 }, [breakpoints.down("md")]: { paddingTop: constants.generalUnit * 3, - paddingBottom: constants.generalUnit * 3, - textAlign: "center" + paddingBottom: constants.generalUnit * 3 } }, footer: { @@ -152,6 +152,26 @@ const useStyles = makeStyles( }, secondaryLoginText: { paddingTop: constants.generalUnit * 2 + }, + exclamationIcon: { + fontSize: 48, + "& svg": { + marginRight: constants.generalUnit, + fill: palette.additional["gray"][7] + } + }, + maintenanceMessage: { + display: "block", + textAlign: "justify", + width: 240 + }, + maintenanceActiveMessage: { + color: palette.error.main + }, + connectWalletRoot: { + display: "flex", + flexDirection: "column", + flex: 1 } }) ) @@ -170,9 +190,36 @@ const InitialScreen = ({ className }: IInitialScreen) => { const [error, setError] = useState() const [errorEmail, setErrorEmail] = useState("") const maintenanceMode = process.env.REACT_APP_MAINTENANCE_MODE === "true" + const maintenanceWindowTimestamp = Number(process.env.REACT_APP_MAINTENANCE_TIMESTAMP) const [isConnecting, setIsConnecting] = useState(false) const { filesApiClient } = useFilesApi() const [email, setEmail] = useState("") + const { state } = useLocation<{from?: string}>() + const isSharing = useMemo(() => state?.from?.includes(LINK_SHARING_BASE), [state]) + const [isValidNonce, setIsValidNonce] = useState() + const { redirect } = useHistory() + + useEffect(() => { + if (!isSharing) return + + const jwt = getJWT(state?.from) + let nonce = "" + + try { + nonce = (jwt && jwtDecode(jwt).nonce_id) || "" + }catch (e) { + setError(t`The link you typed in looks malformed. Please verify it.`) + console.error(e) + } + + if (!nonce) return + + filesApiClient.isNonceValid(nonce) + .then((res) => { + setIsValidNonce(res.is_valid) + }) + .catch(console.error) + }, [filesApiClient, isSharing, state]) const handleSelectWalletAndConnect = async () => { setError(undefined) @@ -197,6 +244,7 @@ const InitialScreen = ({ className }: IInitialScreen) => { setErrorEmail("") setLoginMode(undefined) resetStatus() + setIsValidNonce(undefined) } const handleLogin = async (loginType: IdentityProvider) => { @@ -205,27 +253,23 @@ const InitialScreen = ({ className }: IInitialScreen) => { setLoginMode(loginType) try { await login(loginType) - } catch (error) { + } catch (error: any) { let errorMessage = t`There was an error authenticating` - console.log(error) - if (Array.isArray(error) && error[0]) { - if ( - error[0].type === "signature" && - error[0].message === "Invalid signature" - ) { - errorMessage = t`Failed to validate signature. + // Invalid signature, or contract wallet not deployed + if (error?.error?.code === 403 && error?.error?.message?.includes("Invalid signature")) { + errorMessage = t`Failed to validate signature. If you are using a contract wallet, please make sure you have activated your wallet.` - } } - // WalletConnect be sassy - if ((error instanceof Error && error.message === "Just nope") || ((error as any).code === 4001)) { + // User rejected the signature request (WalletConnect be sassy) + if (error?.message === "Just nope" || error?.code === 4001) { errorMessage = t`Failed to get signature` } - if (error instanceof Error && error?.message === "user closed popup") { + // DirectAuth popup was closed + if (error?.message === "user closed popup") { errorMessage = t`The authentication popup was closed` } @@ -267,7 +311,7 @@ const InitialScreen = ({ className }: IInitialScreen) => { } return ( -
+
+ {maintenanceMode && ( + + We are performing routine maintenance of the system. Service status updates will be posted on the{" "} + Files Support Channel{" "} + on Discord + + + )} + {!maintenanceMode && !!maintenanceWindowTimestamp && dayjs.unix(maintenanceWindowTimestamp).isAfter(dayjs()) && ( + + + System maintenance is scheduled to start at{" "} + {dayjs.unix(maintenanceWindowTimestamp).format("YYYY-MM-DD HH:mm")}.{" "} + The system will be unavailable. + + + )}
) diff --git a/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx b/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx index 997a693218..a2217961b1 100644 --- a/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx +++ b/packages/files-ui/src/Components/Modules/PreviewRenderers/ImagePreview.tsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from "react" import { IPreviewRendererProps } from "../FilePreviewModal" import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch" +import heicConvert from "heic-convert" + import { makeStyles, ITheme, @@ -11,7 +13,8 @@ import { Button, ZoomInIcon, ZoomOutIcon, - FullscreenIcon + FullscreenIcon, + Loading } from "@chainsafe/common-components" const useStyles = makeStyles( @@ -41,67 +44,82 @@ const useStyles = makeStyles( }) ) -const ImagePreview: React.FC = ({ contents }) => { +const ImagePreview: React.FC = ({ contents, contentType }) => { const [imageUrl, setImageUrl] = useState() - + const [loading, setLoading] = useState(false) useEffect(() => { - setImageUrl(URL.createObjectURL(contents)) - - return () => { - imageUrl && URL.revokeObjectURL(imageUrl) + if (contentType !== "image/heic") { + setImageUrl(URL.createObjectURL(contents)) + } else { + setLoading(true) + contents.arrayBuffer() + .then(b => heicConvert({ + buffer: Buffer.from(b), + format: "JPEG", + quality: 0.5 + })) + .catch(console.error) + .then(c => setImageUrl(URL.createObjectURL(new Blob([c])))) + .finally(() => setLoading(false)) } - // eslint-disable-next-line - }, [contents]) + }, [contents, contentType]) + const classes = useStyles() const { desktop } = useThemeSwitcher() return (
- - { + {loading + ? + : + { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - ({ zoomIn, zoomOut, resetTransform }) => ( - <> - {desktop && ( -
- - - -
- )} - - - - - ) - } -
+ ({ zoomIn, zoomOut, resetTransform }) => ( + <> + {desktop && ( +
+ + + +
+ )} + + imageUrl && URL.revokeObjectURL(imageUrl)} /> + + + ) + } +
+ }
) } diff --git a/packages/files-ui/src/Components/Modules/SearchModule.tsx b/packages/files-ui/src/Components/Modules/SearchModule.tsx index 2a87556cd6..c8c5dac485 100644 --- a/packages/files-ui/src/Components/Modules/SearchModule.tsx +++ b/packages/files-ui/src/Components/Modules/SearchModule.tsx @@ -143,7 +143,7 @@ const useStyles = makeStyles( interface ISearchModule { className?: string searchActive: boolean - setSearchActive(searchActive: boolean): void + setSearchActive: (searchActive: boolean) => void } const SearchModule: React.FC = ({ @@ -186,8 +186,8 @@ const SearchModule: React.FC = ({ try { const results = await getSearchResults(searchString) setSearchResults({ results, query: searchString }) - } catch (err) { - // + } catch (e) { + console.error(e) } } @@ -236,9 +236,7 @@ const SearchModule: React.FC = ({ return (
{ - if (!searchActive) setSearchActive(true) - }} + onClick={() => { !searchActive && setSearchActive(true)}} ref={ref} className={clsx(classes.root, className, { active: searchActive @@ -267,17 +265,15 @@ const SearchModule: React.FC = ({ testId = "input-search-bar" /> - {searchQuery && searchResults?.query ? ( -
+ {searchQuery && searchResults?.query && ( +
- {searchResults?.query && !searchResults.results.length ? ( + {searchResults?.query && !searchResults.results.length && ( No search results for {` ${searchResults.query}`} - ) : null} - {searchResultsFiles && searchResultsFiles.length ? ( + )} + {searchResultsFiles && searchResultsFiles.length && (
= ({
))}
- ) : null} - {searchResultsFolders && searchResultsFolders.length ? ( + )} + {searchResultsFolders && searchResultsFolders.length && (
= ({
))}
- ) : null} + )}
- {!desktop ? ( + {!desktop && (
setSearchActive(false)} /> - ) : null} + )}
- ) : null} + )}
) } diff --git a/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx b/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx new file mode 100644 index 0000000000..17a5f585b0 --- /dev/null +++ b/packages/files-ui/src/Components/Pages/LinkSharingLanding.tsx @@ -0,0 +1,11 @@ +import React from "react" +import { usePageTrack } from "../../Contexts/PosthogContext" +import LinkSharingModule from "../Modules/LinkSharingModule" + +const LinkSharingLanding = () => { + usePageTrack() + + return +} + +export default LinkSharingLanding diff --git a/packages/files-ui/src/Components/Pages/LoginPage.tsx b/packages/files-ui/src/Components/Pages/LoginPage.tsx index 8b32ef849e..7ac2c5b9b5 100644 --- a/packages/files-ui/src/Components/Pages/LoginPage.tsx +++ b/packages/files-ui/src/Components/Pages/LoginPage.tsx @@ -12,7 +12,6 @@ import BottomDarkSVG from "../../Media/landing/layers/dark/Bottom.dark.svg" import TopDarkSVG from "../../Media/landing/layers/dark/Top.dark.svg" import BottomLightSVG from "../../Media/landing/layers/light/Bottom.light.svg" import TopLightSVG from "../../Media/landing/layers/light/Top.light.svg" -// import { ForegroundSVG } from "../../Media/landing/layers/ForegroundSVG" import MigrateAccount from "../Modules/LoginModule/MigrateAccount" import InitializeAccount from "../Modules/LoginModule/InitializeAccount" import { useFilesApi } from "../../Contexts/FilesApiContext" @@ -73,6 +72,7 @@ const useStyles = makeStyles( alignItems: "center", justifyContent: "center", marginTop: "2rem", + marginBottom: "1rem", fontWeight: typography.fontWeight.regular, [breakpoints.up("md")]:{ ...typography.h2 @@ -100,12 +100,6 @@ const useStyles = makeStyles( inner: { display: "flex", flexDirection: "column", - flex: "1 1 0", - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - zIndex: zIndex?.layer1, backgroundColor: constants.loginModule.background, border: `1px solid ${constants.landing.border}`, boxShadow: constants.landing.boxShadow, @@ -115,6 +109,10 @@ const useStyles = makeStyles( width: "100%" } }, + loginContainer: { + display: "flex", + justifyContent: "center" + }, logo: { height: 60, width: 60 @@ -167,8 +165,6 @@ const LoginPage = () => { ChainSafe Files - <> - { themeKey === "dark" ? <> @@ -194,7 +190,9 @@ const LoginPage = () => {
- +
+ +
) } diff --git a/packages/files-ui/src/Components/SharingExplainerModal.tsx b/packages/files-ui/src/Components/SharingExplainerModal.tsx index 4061e965dd..39c97327a7 100644 --- a/packages/files-ui/src/Components/SharingExplainerModal.tsx +++ b/packages/files-ui/src/Components/SharingExplainerModal.tsx @@ -132,9 +132,9 @@ const SharingExplainerModal = ({ showModal, onHide }: Props) => { return } else { switch (next) { - case 3: + case STEP_NUMBER: setLocalStore({ [DISMISSED_SHARING_EXPLAINER_KEY]: "true" }, "update") - setStep(3) + setStep(STEP_NUMBER) break case STEP_NUMBER + 1: onHide() @@ -153,6 +153,7 @@ const SharingExplainerModal = ({ showModal, onHide }: Props) => { maxWidth="sm" onClose={onHide} mobileStickyBottom={false} + testId="sharing-explainer" >
{ diff --git a/packages/files-ui/src/Components/SurveyBanner.tsx b/packages/files-ui/src/Components/SurveyBanner.tsx index 8a08f3a066..07ec39da8b 100644 --- a/packages/files-ui/src/Components/SurveyBanner.tsx +++ b/packages/files-ui/src/Components/SurveyBanner.tsx @@ -62,13 +62,16 @@ const SurveyBanner = ({ onHide }: Props) => { setLocalStore({ [DISMISSED_SURVEY_KEY]: "true" }, "update") }, [setLocalStore, onHide]) - const onOpen = useCallback(() => { + const onOpenLink = useCallback(() => { onClose() window.open(ROUTE_LINKS.UserSurvey, "_blank") }, [onClose]) return ( -
+
@@ -77,7 +80,7 @@ const SurveyBanner = ({ onHide }: Props) => { Schedule a 15 min call @@ -85,6 +88,7 @@ const SurveyBanner = ({ onHide }: Props) => {
{ setUploadsInProgress(false) // setting error let errorMessage = t`Something went wrong. We couldn't upload your file` - // uploads cancelled through button if (axios.isCancel(error)) { errorMessage = t`Uploads cancelled` } // we will need a method to parse server errors - if (Array.isArray(error) && error[0].message.includes("conflict")) { + if (error?.error?.code === 409) { errorMessage = t`A file with the same name already exists` } updateToast(toastId, { @@ -663,7 +662,7 @@ const FilesProvider = ({ children }: FilesContextProps) => { return Promise.resolve() } catch (error: any) { console.error(error) - let errorMessage = `${t`An error occurred: `} ${typeof(error) === "string" ? error : error.length ? error[0].message : ""}` + let errorMessage = `${t`An error occurred: `} ${typeof(error) === "string" ? error : error.error.message ? error.error.message : ""}` if (axios.isCancel(error)) { errorMessage = t`Downloads cancelled` } @@ -839,7 +838,7 @@ const FilesProvider = ({ children }: FilesContextProps) => { : successCount ? t`${successCount} files transferred successfully, ${totalFileNumber - successCount} failed` : t`${inSharedBucket ? "Copying" : "Sharing"} failed`, - type: "success", + type: successCount ? "success" : "error", progress: undefined, isClosable: true }, true) @@ -868,6 +867,8 @@ const FilesProvider = ({ children }: FilesContextProps) => { } }).catch((error) => { console.error(error) + }).finally(() => { + refreshBuckets() }) }, [getFileContent, encryptAndUploadFiles, filesApiClient, refreshBuckets, addToast, updateToast, getFileList]) diff --git a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx index 9259fe6413..b9788d080c 100644 --- a/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx +++ b/packages/files-ui/src/Contexts/ThresholdKeyContext.tsx @@ -15,12 +15,14 @@ import EthCrypto from "eth-crypto" import { useWeb3 } from "@chainsafe/web3-context" import ShareTransferRequestModal from "../Components/Elements/ShareTransferRequestModal" import BN from "bn.js" -import { IdentityProvider } from "@chainsafe/files-api-client" +import { IdentityProvider, NonceResponsePermission } from "@chainsafe/files-api-client" import { capitalize, centerEllipsis } from "../Utils/Helpers" import { t } from "@lingui/macro" import jwtDecode from "jwt-decode" import { IdentityToken } from "@chainsafe/files-api-client" import dayjs from "dayjs" +import keyEncoder from "key-encoder" +import { KJUR } from "jsrsasign" const TORUS_POSTBOX_KEY = "csf.postboxKey" const TKEY_STORE_KEY = "csf.tkeyStore" @@ -68,6 +70,7 @@ export type TThresholdKeyContext = { getAvailableShareIndices(): string[] | undefined refreshTKeyMeta(): Promise loggedinAs: string + createJWT: (bucketId: string, nonceId: string, nonce: NonceResponsePermission) => string | undefined } type ThresholdKeyProviderProps = { @@ -396,6 +399,31 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f } }, [userInfo, address]) + const createJWT = useCallback((bucketId: string, nonceId: string, permission: NonceResponsePermission) => { + + if(!privateKey) { + console.error("no private key found") + return + } + + const ke = new keyEncoder("secp256k1") + const pem = ke.encodePrivate(privateKey, "raw", "pem") + const header = { alg: "ES256", typ: "JWT" } + const payload = { + type: "link_sharing", + permission, + iat: KJUR.jws.IntDate.get("now"), + bucket_id: bucketId, + nonce_id: nonceId + } + + const sHeader = JSON.stringify(header) + const sPayload = JSON.stringify(payload) + + const sJWT = KJUR.jws.JWS.sign("ES256", sHeader, sPayload, pem) + return sJWT + }, [privateKey]) + const login = async (loginType: IdentityProvider, tokenInfo?: {token: string; email: string}) => { if (!TKeySdk || maintenanceMode) return try { @@ -828,7 +856,8 @@ const ThresholdKeyProvider = ({ children, network = "mainnet", enableLogging = f resetStatus: () => setStatus("initialized"), getAvailableShareIndices, refreshTKeyMeta, - loggedinAs + loggedinAs, + createJWT }} > {!isNewDevice && pendingShareTransferRequests.length > 0 && process.env.REACT_APP_TEST !== "true" && ( diff --git a/packages/files-ui/src/Contexts/UserContext.tsx b/packages/files-ui/src/Contexts/UserContext.tsx index 3250078193..54fb81d282 100644 --- a/packages/files-ui/src/Contexts/UserContext.tsx +++ b/packages/files-ui/src/Contexts/UserContext.tsx @@ -3,6 +3,9 @@ import { useCallback, useEffect } from "react" import { useFilesApi } from "./FilesApiContext" import { useState } from "react" import { t } from "@lingui/macro" +import { DISMISSED_SHARING_EXPLAINER_KEY } from "../Components/Modules/FileBrowsers/hooks/useSharingExplainerModalFlag" +import { DISMISSED_SURVEY_KEY } from "../Components/SurveyBanner" +import { Details } from "@chainsafe/files-api-client" type UserContextProps = { children: React.ReactNode | React.ReactNode[] @@ -43,23 +46,19 @@ const UserContext = React.createContext(undefined) const UserProvider = ({ children }: UserContextProps) => { const { filesApiClient, isLoggedIn } = useFilesApi() - const [profile, setProfile] = useState(undefined) const [localStore, _setLocalStore] = useState() const setLocalStore = useCallback((newData: ILocalStore, method: "update" | "overwrite" = "update") => { - switch (method) { - case "update": - _setLocalStore({ - ...localStore, - ...newData - }) - break - case "overwrite": - _setLocalStore(newData) - break - } - }, [localStore]) + const toStore = method === "update" + ? { ...localStore, ...newData } + : newData + + filesApiClient.updateUserLocalStore(toStore) + .then(_setLocalStore) + .catch(console.error) + + }, [filesApiClient, localStore]) const refreshProfile = useCallback(async () => { try { @@ -77,40 +76,48 @@ const UserProvider = ({ children }: UserContextProps) => { setProfile(profileState) return Promise.resolve() } catch (error) { + console.error(error) return Promise.reject("There was an error getting profile.") } }, [filesApiClient]) - useEffect(() => { - const manageAsync = async () => { - if (!localStore) { - // Fetch - try { - const fetched = await filesApiClient.getUserLocalStore() - if (!fetched) { - _setLocalStore({}) - } else { - _setLocalStore(fetched) - } - } catch(error) { - console.error(error) - _setLocalStore({}) - } - } else { - // Store - await filesApiClient.updateUserLocalStore(localStore) - } + const initLocalStore = useCallback((apiStore: ILocalStore | undefined) => { + let initStore = apiStore || {} + + if (apiStore?.[DISMISSED_SHARING_EXPLAINER_KEY] === undefined) { + initStore = { ...initStore, [DISMISSED_SHARING_EXPLAINER_KEY]: "false" } } - if (isLoggedIn) { - manageAsync() + + if (apiStore?.[DISMISSED_SURVEY_KEY] === undefined) { + initStore = { ...initStore, [DISMISSED_SURVEY_KEY]: "false" } + } + + _setLocalStore(initStore) + }, []) + + useEffect(() => { + if (!isLoggedIn) { + return } - }, [isLoggedIn, localStore, filesApiClient]) + + filesApiClient.getUserLocalStore() + .then((apiStore) => { + initLocalStore(apiStore) + }) + .catch((e) => { + console.error(e) + initLocalStore({}) + }) + }, [isLoggedIn, filesApiClient, initLocalStore]) useEffect(() => { - if (isLoggedIn) { - refreshProfile() - .catch(console.error) + if (!isLoggedIn) { + return } + + refreshProfile() + .catch(console.error) + }, [isLoggedIn, refreshProfile]) const updateProfile = async (firstName?: string, lastName?: string) => { @@ -160,9 +167,10 @@ const UserProvider = ({ children }: UserContextProps) => { }) return Promise.resolve() } catch (error: any) { + console.error(error) return Promise.reject( - Array.isArray(error) && error[0] - ? error[0].message + Array.isArray(error.error.details) + ? error.error.details.map((e: Details) => e.message).join(",") : t`There was an error when setting username.` ) } diff --git a/packages/files-ui/src/Themes/DarkTheme.ts b/packages/files-ui/src/Themes/DarkTheme.ts index 8ed5c7491c..30ddf80969 100644 --- a/packages/files-ui/src/Themes/DarkTheme.ts +++ b/packages/files-ui/src/Themes/DarkTheme.ts @@ -332,9 +332,9 @@ export const darkTheme = createTheme({ ...UI_CONSTANTS, ...({ menu:{ - backgroundColor: "var(--gray1)", + backgroundColor: "var(--gray2)", color: "var(--gray8)", - backgroundOptionHover: "var(--gray2)" + backgroundOptionHover: "var(--gray3)" }, landing: { background: "var(--gray2)", diff --git a/packages/files-ui/src/Utils/contentTypeGuesser.ts b/packages/files-ui/src/Utils/contentTypeGuesser.ts index ae7b19cdd3..49ccbe92f7 100644 --- a/packages/files-ui/src/Utils/contentTypeGuesser.ts +++ b/packages/files-ui/src/Utils/contentTypeGuesser.ts @@ -1,7 +1,7 @@ const guessContentType = (fileName: string) => { const { length, [length - 1]: ext } = fileName.split(".") - switch (ext) { + switch (ext.toLowerCase()) { case "pdf": return "application/pdf" case "jpg": @@ -9,7 +9,8 @@ const guessContentType = (fileName: string) => { case "png": case "gif": case "bmp": - return `image/${ext}` + case "heic": + return `image/${ext.toLowerCase()}` case "mp3": case "m4a": return `audio/${ext}` diff --git a/packages/files-ui/src/Utils/pathUtils.ts b/packages/files-ui/src/Utils/pathUtils.ts index ee3cf3a5f6..0d01539479 100644 --- a/packages/files-ui/src/Utils/pathUtils.ts +++ b/packages/files-ui/src/Utils/pathUtils.ts @@ -103,6 +103,32 @@ export const isSubFolder = (fold1: string, fold2: string) => { return result } +// get the jwt from /link-sharing/permision/jwt +export const getJWT = (pathname?: string) => { + + if(!pathname) return + + const arrayOfPaths = getArrayOfPaths(pathname) + + if(arrayOfPaths.length !== 3){ + console.error("JWT extraction error, unexpected path", pathname) + return + } + + return decodeURIComponent(arrayOfPaths[2]) +} + +// return the hash from #hash +export const getBucketDecryptionFromHash = (hash: string) => { + + if(!hash.startsWith("#")){ + console.error("Bucket encryption key extraction error, unexpected hash", hash) + return + } + + return decodeURIComponent(hash.substr(1)) +} + export const getUrlSafePathWithFile = (path: string, fileName: string) => { let urlSafePath = getURISafePathFromArray(getArrayOfPaths(path)) if (urlSafePath === "/") { diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index c643a7cf1d..287d10f932 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -52,8 +52,11 @@ msgstr "Weitere Dateien hinzufügen" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" -msgid "An error occurred while downloading the file" -msgstr "Beim Herunterladen der Datei ist ein Fehler aufgetreten" +msgid "Adding you to the shared folder..." +msgstr "" + +#~ msgid "An error occurred while downloading the file" +#~ msgstr "Beim Herunterladen der Datei ist ein Fehler aufgetreten" msgid "An error occurred:" msgstr "Es ist ein Fehler aufgetreten:" @@ -82,14 +85,17 @@ msgstr "" msgid "Bin" msgstr "Papierkorb" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "Browser:" msgid "Bucket id" msgstr "" -msgid "Buy more storage" -msgstr "" +#~ msgid "Buy more storage" +#~ msgstr "" msgid "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" msgstr "" @@ -109,6 +115,9 @@ msgstr "" msgid "Change Password" msgstr "Passwort ändern" +msgid "Change Plan" +msgstr "" + msgid "Change password" msgstr "Passwort ändern" @@ -163,17 +172,23 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" msgid "Copy to" msgstr "" +msgid "Copying files" +msgstr "" + msgid "Create" msgstr "Erstellen" msgid "Create Folder" -msgstr "Ordner erstellen" +msgstr "" msgid "Create Shared Folder" msgstr "" @@ -187,6 +202,9 @@ msgstr "" msgid "Create folder" msgstr "Ordner erstellen" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -259,15 +277,12 @@ msgstr "" msgid "Drop to upload files" msgstr "Zum Hochladen von Dateien ablegen" -msgid "Early Adopter: Free up to {0}" -msgstr "" +#~ msgid "Early Adopter: Free up to {0}" +#~ msgstr "" msgid "Email is required" msgstr "E-Mail ist erforderlich" -msgid "Encrypting & uploading" -msgstr "" - msgid "Enter backup secret phrase:" msgstr "Geben Sie den Sicherungsgeheimsatz ein:" @@ -373,6 +388,9 @@ msgstr "Zurück" msgid "Go to Payments" msgstr "" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -397,7 +415,7 @@ msgstr "Infos" msgid "I’m done saving my backup secret phrase" msgstr "Ich bin fertig mit dem Speichern meines Sixherungsgeheimsatzes" -msgid "Keep original file" +msgid "Keep original files" msgstr "" msgid "Language" @@ -436,8 +454,8 @@ msgstr "" msgid "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" msgstr "Sieht aus, als würden Sie sich über einen neuen Browser anmelden. Bitte wählen Sie eine der folgenden Möglichkeiten, um fortzufahren:" -msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." -msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." msgid "Manage Access" msgstr "" @@ -478,8 +496,14 @@ msgstr "" msgid "No file to download." msgstr "" -#~ msgid "No files to show" -#~ msgstr "Keine Dateien zum Anzeigen" +msgid "No files to copy" +msgstr "" + +msgid "No files to share" +msgstr "" + +msgid "No files to show" +msgstr "Keine Dateien zum Anzeigen" msgid "No folders" msgstr "Keine Ordner" @@ -497,7 +521,7 @@ msgid "Number of copies (Replication Factor)" msgstr "Anzahl der Kopien (Replikationsfaktor)" msgid "OK" -msgstr "OK" +msgstr "" msgid "One sec, getting files ready…" msgstr "Eine Sekunde, die Dateien werden vorbereitet …" @@ -541,8 +565,8 @@ msgstr "Passwörter müssen übereinstimmen" msgid "Payment and Subscriptions" msgstr "" -msgid "Plan" -msgstr "" +#~ msgid "Plan" +#~ msgstr "" msgid "Please enter a file name" msgstr "Bitte geben Sie einen Dateinamen ein" @@ -688,6 +712,9 @@ msgstr "" msgid "Share file" msgstr "" +msgid "Share selected" +msgstr "" + msgid "Shared" msgstr "Geteilt" @@ -700,10 +727,10 @@ msgstr "" msgid "Shared with" msgstr "" -msgid "Sharing cancelled" +msgid "Sharing files" msgstr "" -msgid "Sharing your file (Downloading)" +msgid "Sharing link" msgstr "" msgid "Sign Out" @@ -715,6 +742,9 @@ msgstr "Anmelden" msgid "Sign in with a different account" msgstr "Mit einem anderen Konto anmelden" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -748,8 +778,8 @@ msgstr "Hochladen starten" msgid "Start a team" msgstr "" -msgid "Storage Plan" -msgstr "Speicherplan" +#~ msgid "Storage Plan" +#~ msgstr "Speicherplan" msgid "Stored by miner" msgstr "" @@ -757,6 +787,9 @@ msgstr "" msgid "Subscription Plan" msgstr "" +msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." +msgstr "" + msgid "Teams" msgstr "" @@ -772,8 +805,8 @@ msgstr "" msgid "The files are already in this folder" msgstr "" -msgid "The system is undergoing maintenance, thank you for being patient." -msgstr "Das System wird gerade gewartet, wir danken Ihnen für Ihre Geduld." +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" msgid "The username is too long" msgstr "" @@ -787,6 +820,9 @@ msgstr "Es gab einen Fehler bei der Authentifizierung" msgid "There was an error connecting your wallet" msgstr "" +msgid "There was an error creating the folder {0}" +msgstr "" + msgid "There was an error deleting your data" msgstr "" @@ -808,6 +844,12 @@ msgstr "" msgid "This is the free product." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -820,9 +862,6 @@ msgstr "" msgid "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" msgstr "" -msgid "Transfer complete" -msgstr "" - msgid "Try again" msgstr "Erneut versuchen" @@ -889,6 +928,9 @@ msgstr "Verifizierungscode nicht korrekt!" msgid "Verification code sent!" msgstr "Verifizierungscode gesendet!" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Ordner anzeigen" @@ -898,6 +940,9 @@ msgstr "" msgid "Want to help shape this product?" msgstr "" +msgid "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" +msgstr "" + msgid "We can't encrypt files larger than 2GB. Some items will not be uploaded" msgstr "" @@ -931,14 +976,17 @@ msgstr "Sie können keine Ordner in diesen Pfad verschieben" msgid "You haven't set a username yet." msgstr "Sie haben noch keinen Benutzernamen festgelegt." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" msgid "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" msgstr "" -msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" -msgstr "" +#~ msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgstr "" msgid "Your plan" msgstr "" @@ -946,15 +994,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Ihr Wiederherstellungsschlüssel kann zur Wiederherstellung Ihres Kontos anstelle Ihres Sicherungsgeheimsatz verwendet werden." +msgid "edit rights" +msgstr "" + msgid "me" msgstr "ich" msgid "on" msgstr "am" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "unbekannt" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {{1} Datei wird heruntergeladen} other {{2} Dateien werden heruntergeladen}}" @@ -964,5 +1021,23 @@ msgstr "{0, plural, one {{1} Datei wird verschlüsselt und hochgeladen} other {{ msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "{0, plural, one {Sie sind dabei, {1} Artikel zu löschen.} other {Sie sind dabei, {2} Artikel zu löschen.}}" -msgid "{0} of {1} used ({2}%)" +msgid "{0} cancelled" +msgstr "" + +msgid "{0} cancelled - {successCount} files {1} successfully" +msgstr "" + +msgid "{0} complete" +msgstr "" + +msgid "{0} failed" +msgstr "" + +msgid "{0} of {1} used" +msgstr "" + +msgid "{0} {fileProgress} - {1}" +msgstr "" + +msgid "{successCount} files transferred successfully, {0} failed" msgstr "" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index 9c19316004..ba5e3be258 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -52,8 +52,8 @@ msgstr "Add more files" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "Add viewers and editors by username, sharing id or Ethereum address." -msgid "An error occurred while downloading the file" -msgstr "An error occurred while downloading the file" +msgid "Adding you to the shared folder..." +msgstr "Adding you to the shared folder..." msgid "An error occurred:" msgstr "An error occurred:" @@ -82,14 +82,17 @@ msgstr "Billed Yearly" msgid "Bin" msgstr "Bin" +msgid "Browse {0}" +msgstr "Browse {0}" + msgid "Browser:" msgstr "Browser:" msgid "Bucket id" msgstr "Bucket id" -msgid "Buy more storage" -msgstr "Buy more storage" +#~ msgid "Buy more storage" +#~ msgstr "Buy more storage" msgid "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" msgstr "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" @@ -109,6 +112,9 @@ msgstr "Card inputs invalid" msgid "Change Password" msgstr "Change Password" +msgid "Change Plan" +msgstr "Change Plan" + msgid "Change password" msgstr "Change password" @@ -163,12 +169,18 @@ msgstr "Copy file" msgid "Copy info" msgstr "Copy info" +msgid "Copy link" +msgstr "Copy link" + msgid "Copy over" msgstr "Copy over" msgid "Copy to" msgstr "Copy to" +msgid "Copying files" +msgstr "Copying files" + msgid "Create" msgstr "Create" @@ -187,6 +199,9 @@ msgstr "Create a new shared folder" msgid "Create folder" msgstr "Create folder" +msgid "Create new link" +msgstr "Create new link" + msgid "Create your public username in <0>Settings!" msgstr "Create your public username in <0>Settings!" @@ -259,15 +274,12 @@ msgstr "Downloads failed" msgid "Drop to upload files" msgstr "Drop to upload files" -msgid "Early Adopter: Free up to {0}" -msgstr "Early Adopter: Free up to {0}" +#~ msgid "Early Adopter: Free up to {0}" +#~ msgstr "Early Adopter: Free up to {0}" msgid "Email is required" msgstr "Email is required" -msgid "Encrypting & uploading" -msgstr "Encrypting & uploading" - msgid "Enter backup secret phrase:" msgstr "Enter backup secret phrase:" @@ -376,6 +388,9 @@ msgstr "Go back" msgid "Go to Payments" msgstr "Go to Payments" +msgid "Go to login" +msgstr "Go to login" + msgid "Got it" msgstr "Got it" @@ -400,8 +415,8 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "I’m done saving my backup secret phrase" -msgid "Keep original file" -msgstr "Keep original file" +msgid "Keep original files" +msgstr "Keep original files" msgid "Language" msgstr "Language" @@ -439,8 +454,8 @@ msgstr "Loading..." msgid "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" msgstr "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" -msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." -msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." msgid "Manage Access" msgstr "Manage Access" @@ -481,8 +496,14 @@ msgstr "No Card" msgid "No file to download." msgstr "No file to download." -#~ msgid "No files to show" -#~ msgstr "No files to show" +msgid "No files to copy" +msgstr "No files to copy" + +msgid "No files to share" +msgstr "No files to share" + +msgid "No files to show" +msgstr "No files to show" msgid "No folders" msgstr "No folders" @@ -544,8 +565,8 @@ msgstr "Passwords must match" msgid "Payment and Subscriptions" msgstr "Payment and Subscriptions" -msgid "Plan" -msgstr "Plan" +#~ msgid "Plan" +#~ msgstr "Plan" msgid "Please enter a file name" msgstr "Please enter a file name" @@ -691,6 +712,9 @@ msgstr "Share" msgid "Share file" msgstr "Share file" +msgid "Share selected" +msgstr "Share selected" + msgid "Shared" msgstr "Shared" @@ -703,11 +727,11 @@ msgstr "Shared folders" msgid "Shared with" msgstr "Shared with" -msgid "Sharing cancelled" -msgstr "Sharing cancelled" +msgid "Sharing files" +msgstr "Sharing files" -msgid "Sharing your file (Downloading)" -msgstr "Sharing your file (Downloading)" +msgid "Sharing link" +msgstr "Sharing link" msgid "Sign Out" msgstr "Sign Out" @@ -718,6 +742,9 @@ msgstr "Sign in" msgid "Sign in with a different account" msgstr "Sign in with a different account" +msgid "Sign in/up to access the shared folder" +msgstr "Sign in/up to access the shared folder" + msgid "Sign me up!" msgstr "Sign me up!" @@ -751,8 +778,8 @@ msgstr "Start Upload" msgid "Start a team" msgstr "Start a team" -msgid "Storage Plan" -msgstr "Storage Plan" +#~ msgid "Storage Plan" +#~ msgstr "Storage Plan" msgid "Stored by miner" msgstr "Stored by miner" @@ -760,6 +787,9 @@ msgstr "Stored by miner" msgid "Subscription Plan" msgstr "Subscription Plan" +msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." +msgstr "System maintenance is scheduled to start at {0}. The system will be unavailable." + msgid "Teams" msgstr "Teams" @@ -775,8 +805,8 @@ msgstr "The authentication popup was closed" msgid "The files are already in this folder" msgstr "The files are already in this folder" -msgid "The system is undergoing maintenance, thank you for being patient." -msgstr "The system is undergoing maintenance, thank you for being patient." +msgid "The link you typed in looks malformed. Please verify it." +msgstr "The link you typed in looks malformed. Please verify it." msgid "The username is too long" msgstr "The username is too long" @@ -790,6 +820,9 @@ msgstr "There was an error authenticating" msgid "There was an error connecting your wallet" msgstr "There was an error connecting your wallet" +msgid "There was an error creating the folder {0}" +msgstr "There was an error creating the folder {0}" + msgid "There was an error deleting your data" msgstr "There was an error deleting your data" @@ -811,6 +844,12 @@ msgstr "There was an error when setting username." msgid "This is the free product." msgstr "This is the free product." +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "This link is marlformed. Please verify that you copy/pasted it correctly." + +msgid "This link is not valid any more." +msgstr "This link is not valid any more." + msgid "This username is already taken" msgstr "This username is already taken" @@ -823,8 +862,8 @@ msgstr "This website uses cookies" msgid "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" msgstr "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" -msgid "Transfer complete" -msgstr "Transfer complete" +#~ msgid "Transfer complete" +#~ msgstr "Transfer complete" msgid "Try again" msgstr "Try again" @@ -892,6 +931,9 @@ msgstr "Verification code not correct!" msgid "Verification code sent!" msgstr "Verification code sent!" +msgid "Verifying the link..." +msgstr "Verifying the link..." + msgid "View folder" msgstr "View folder" @@ -901,6 +943,9 @@ msgstr "Wallet address" msgid "Want to help shape this product?" msgstr "Want to help shape this product?" +msgid "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" +msgstr "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" + msgid "We can't encrypt files larger than 2GB. Some items will not be uploaded" msgstr "We can't encrypt files larger than 2GB. Some items will not be uploaded" @@ -934,14 +979,17 @@ msgstr "You can't move folders to this path" msgid "You haven't set a username yet." msgstr "You haven't set a username yet." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "You were added to the shared folder ({0}): {1}" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "You will need to sign a message in your wallet to complete sign in." msgid "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" msgstr "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" -msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" -msgstr "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgstr "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" msgid "Your plan" msgstr "Your plan" @@ -949,15 +997,24 @@ msgstr "Your plan" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Your recovery key can be used to restore your account in place of your backup secret phrase." +msgid "edit rights" +msgstr "edit rights" + msgid "me" msgstr "me" msgid "on" msgstr "on" +msgid "read rights" +msgstr "read rights" + msgid "unknown" msgstr "unknown" +msgid "with" +msgstr "with" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" @@ -967,5 +1024,26 @@ msgstr "{0, plural, one {Encrypting and uploading {1} file} other {Encrypting an msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" -msgid "{0} of {1} used ({2}%)" -msgstr "{0} of {1} used ({2}%)" +msgid "{0} cancelled" +msgstr "{0} cancelled" + +msgid "{0} cancelled - {successCount} files {1} successfully" +msgstr "{0} cancelled - {successCount} files {1} successfully" + +msgid "{0} complete" +msgstr "{0} complete" + +msgid "{0} failed" +msgstr "{0} failed" + +msgid "{0} of {1} used" +msgstr "{0} of {1} used" + +#~ msgid "{0} of {1} used ({2}%)" +#~ msgstr "{0} of {1} used ({2}%)" + +msgid "{0} {fileProgress} - {1}" +msgstr "{0} {fileProgress} - {1}" + +msgid "{successCount} files transferred successfully, {0} failed" +msgstr "{successCount} files transferred successfully, {0} failed" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index e0d407f7f1..fe85f1eac4 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -53,9 +53,12 @@ msgstr "Agrega mas archivos" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" -msgid "An error occurred while downloading the file" +msgid "Adding you to the shared folder..." msgstr "" +#~ msgid "An error occurred while downloading the file" +#~ msgstr "" + msgid "An error occurred:" msgstr "" @@ -83,14 +86,17 @@ msgstr "" msgid "Bin" msgstr "Papelera" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "Navegador:" msgid "Bucket id" msgstr "" -msgid "Buy more storage" -msgstr "" +#~ msgid "Buy more storage" +#~ msgstr "" msgid "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" msgstr "Al conectar su billetera, acepta nuestras <0> Condiciones de servicio y <1> Política de privacidad " @@ -110,6 +116,9 @@ msgstr "" msgid "Change Password" msgstr "Cambiar la contraseña" +msgid "Change Plan" +msgstr "" + msgid "Change password" msgstr "Cambiar la contraseña" @@ -164,17 +173,23 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" msgid "Copy to" msgstr "" +msgid "Copying files" +msgstr "" + msgid "Create" msgstr "Crear" msgid "Create Folder" -msgstr "Crear Carpeta" +msgstr "" msgid "Create Shared Folder" msgstr "" @@ -188,6 +203,9 @@ msgstr "" msgid "Create folder" msgstr "Crear Carpeta" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -260,15 +278,12 @@ msgstr "" msgid "Drop to upload files" msgstr "Suelta para subir archivos" -msgid "Early Adopter: Free up to {0}" -msgstr "" +#~ msgid "Early Adopter: Free up to {0}" +#~ msgstr "" msgid "Email is required" msgstr "" -msgid "Encrypting & uploading" -msgstr "" - msgid "Enter backup secret phrase:" msgstr "" @@ -377,6 +392,9 @@ msgstr "Regresar" msgid "Go to Payments" msgstr "" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -401,7 +419,7 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "" -msgid "Keep original file" +msgid "Keep original files" msgstr "" msgid "Language" @@ -440,8 +458,8 @@ msgstr "" msgid "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" msgstr "Parece que está iniciando sesión desde un nuevo navegador. Elija una de las siguientes opciones para continuar:" -msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." -msgstr "Lorem ipsum Aenean, y un gran maquillaje. Usamos más y colocamos en ratas. Ahora elemento libre, pero mucho del valle. , Quien no se doblegue, de la vida de una fringilla molestie." +#~ msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgstr "Lorem ipsum Aenean, y un gran maquillaje. Usamos más y colocamos en ratas. Ahora elemento libre, pero mucho del valle. , Quien no se doblegue, de la vida de una fringilla molestie." msgid "Manage Access" msgstr "" @@ -482,8 +500,14 @@ msgstr "" msgid "No file to download." msgstr "" -#~ msgid "No files to show" -#~ msgstr "No hay archivos para mostrar" +msgid "No files to copy" +msgstr "" + +msgid "No files to share" +msgstr "" + +msgid "No files to show" +msgstr "No hay archivos para mostrar" msgid "No folders" msgstr "Sin carpetas" @@ -501,7 +525,7 @@ msgid "Number of copies (Replication Factor)" msgstr "Número de copias (factor de replicación)" msgid "OK" -msgstr "OK" +msgstr "" msgid "One sec, getting files ready…" msgstr "" @@ -545,8 +569,8 @@ msgstr "Las contraseñas deben coincidir" msgid "Payment and Subscriptions" msgstr "" -msgid "Plan" -msgstr "" +#~ msgid "Plan" +#~ msgstr "" msgid "Please enter a file name" msgstr "Ingrese un nombre de archivo" @@ -692,6 +716,9 @@ msgstr "" msgid "Share file" msgstr "" +msgid "Share selected" +msgstr "" + msgid "Shared" msgstr "" @@ -704,12 +731,18 @@ msgstr "" msgid "Shared with" msgstr "" -msgid "Sharing cancelled" +#~ msgid "Sharing cancelled" +#~ msgstr "" + +msgid "Sharing files" msgstr "" -msgid "Sharing your file (Downloading)" +msgid "Sharing link" msgstr "" +#~ msgid "Sharing your file (Downloading)" +#~ msgstr "" + msgid "Sign Out" msgstr "Desconectar" @@ -719,6 +752,9 @@ msgstr "Registrarse" msgid "Sign in with a different account" msgstr "Inicie sesión con una cuenta diferente" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -752,8 +788,8 @@ msgstr "Iniciar la subida" msgid "Start a team" msgstr "" -msgid "Storage Plan" -msgstr "Plan de almacenamiento" +#~ msgid "Storage Plan" +#~ msgstr "Plan de almacenamiento" msgid "Stored by miner" msgstr "Almacenado por el minero" @@ -761,6 +797,9 @@ msgstr "Almacenado por el minero" msgid "Subscription Plan" msgstr "" +msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." +msgstr "" + msgid "Teams" msgstr "" @@ -776,8 +815,8 @@ msgstr "Se cerró la ventana emergente de autenticación" msgid "The files are already in this folder" msgstr "" -msgid "The system is undergoing maintenance, thank you for being patient." -msgstr "El sistema está en mantenimiento, gracias por su paciencia." +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" msgid "The username is too long" msgstr "" @@ -791,6 +830,9 @@ msgstr "Hubo un error de autenticación." msgid "There was an error connecting your wallet" msgstr "Hubo un error al conectar su billetera" +msgid "There was an error creating the folder {0}" +msgstr "" + msgid "There was an error deleting your data" msgstr "" @@ -812,6 +854,12 @@ msgstr "" msgid "This is the free product." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -824,9 +872,6 @@ msgstr "" msgid "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" msgstr "" -msgid "Transfer complete" -msgstr "" - msgid "Try again" msgstr "Intentar otra vez" @@ -893,6 +938,9 @@ msgstr "" msgid "Verification code sent!" msgstr "" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Utilice un navegador guardado" @@ -902,6 +950,9 @@ msgstr "Utilice un navegador guardado" msgid "Want to help shape this product?" msgstr "" +msgid "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" +msgstr "" + msgid "We can't encrypt files larger than 2GB. Some items will not be uploaded" msgstr "" @@ -935,14 +986,17 @@ msgstr "" msgid "You haven't set a username yet." msgstr "" +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Deberá firmar un mensaje en su billetera para completar el inicio de sesión." msgid "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" msgstr "" -msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" -msgstr "" +#~ msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgstr "" msgid "Your plan" msgstr "" @@ -950,15 +1004,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" +msgid "edit rights" +msgstr "" + msgid "me" msgstr "" msgid "on" msgstr "en" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "" @@ -968,5 +1031,23 @@ msgstr "" msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "" -msgid "{0} of {1} used ({2}%)" +msgid "{0} cancelled" +msgstr "" + +msgid "{0} cancelled - {successCount} files {1} successfully" +msgstr "" + +msgid "{0} complete" +msgstr "" + +msgid "{0} failed" +msgstr "" + +msgid "{0} of {1} used" +msgstr "" + +msgid "{0} {fileProgress} - {1}" +msgstr "" + +msgid "{successCount} files transferred successfully, {0} failed" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index d9f12da1a1..f61eca6de8 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-04-23 11:05+0200\n" -"PO-Revision-Date: 2021-09-29 19:36+0000\n" +"PO-Revision-Date: 2021-10-30 12:33+0000\n" "Last-Translator: J. Lavoie \n" "Language-Team: French \n" "Language: fr\n" @@ -53,8 +53,11 @@ msgstr "Ajouter d’autres fichiers" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "Ajoutez des personnes pouvant visualiser ou afficher par nom d'utilisateur, identifiant de partage ou adresse Ethereum." -msgid "An error occurred while downloading the file" -msgstr "Une erreur s'est produite lors du téléchargement du fichier" +msgid "Adding you to the shared folder..." +msgstr "Je vous ajoute au dossier partagé…" + +#~ msgid "An error occurred while downloading the file" +#~ msgstr "Une erreur s'est produite lors du téléchargement du fichier" msgid "An error occurred:" msgstr "Une erreur s'est produite :" @@ -83,14 +86,17 @@ msgstr "" msgid "Bin" msgstr "Corbeille" +msgid "Browse {0}" +msgstr "Parcourir {0}" + msgid "Browser:" msgstr "Explorateur :" msgid "Bucket id" msgstr "Identifiant du seau" -msgid "Buy more storage" -msgstr "" +#~ msgid "Buy more storage" +#~ msgstr "" msgid "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" msgstr "En connectant votre portefeuille, vous acceptez nos <0>conditions de service et notre <1>politique de confidentialité" @@ -110,6 +116,9 @@ msgstr "" msgid "Change Password" msgstr "Changer le mot de passe" +msgid "Change Plan" +msgstr "" + msgid "Change password" msgstr "Changer le mot de passe" @@ -164,12 +173,18 @@ msgstr "Copier le fichier" msgid "Copy info" msgstr "Copier les infos" +msgid "Copy link" +msgstr "Copier le lien" + msgid "Copy over" msgstr "Copier" msgid "Copy to" msgstr "Copier vers" +msgid "Copying files" +msgstr "Copie de fichiers" + msgid "Create" msgstr "Créer" @@ -188,6 +203,9 @@ msgstr "Créer un nouveau dossier partagé" msgid "Create folder" msgstr "Créer un dossier" +msgid "Create new link" +msgstr "Créer un nouveau lien" + msgid "Create your public username in <0>Settings!" msgstr "Créez votre nom d'utilisateur public dans <0>Paramètres !" @@ -198,16 +216,16 @@ msgid "Dark Theme" msgstr "Thème sombre" msgid "Data deleted successfully" -msgstr "" +msgstr "Données supprimées avec succès" msgid "Data moved successfully" -msgstr "" +msgstr "Données déplacées avec succès" msgid "Data moved to bin successfully" -msgstr "" +msgstr "Les données ont été déplacées vers la poubelle avec succès" msgid "Data restored successfully" -msgstr "" +msgstr "Données restaurées avec succès" msgid "Date uploaded" msgstr "Téléversé le" @@ -260,15 +278,12 @@ msgstr "Les téléchargements ont échoué" msgid "Drop to upload files" msgstr "Faire glisser pour téléverser un fichier" -msgid "Early Adopter: Free up to {0}" -msgstr "" +#~ msgid "Early Adopter: Free up to {0}" +#~ msgstr "" msgid "Email is required" msgstr "Un courriel est requis" -msgid "Encrypting & uploading" -msgstr "Chiffrement et téléversement" - msgid "Enter backup secret phrase:" msgstr "Phrase secrète de sauvegarde :" @@ -288,7 +303,7 @@ msgstr "Entrez le code de vérification :" #~ msgstr "Erreur lors du téléchargement de {0}" #~ msgid "Error while uploading {0}" -#~ msgstr "Erreur lors du téléversement de {0} +#~ msgstr "Erreur lors du téléversement de {0}" #~ msgid "Essentials - Free" #~ msgstr "Essentials - Gratuit" @@ -377,6 +392,9 @@ msgstr "Retour" msgid "Go to Payments" msgstr "" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "Compris" @@ -401,8 +419,8 @@ msgstr "Infos" msgid "I’m done saving my backup secret phrase" msgstr "Phrase de sauvegarde secrète enregistrée" -msgid "Keep original file" -msgstr "Conserver le fichier original" +msgid "Keep original files" +msgstr "Conserver les fichiers originaux" msgid "Language" msgstr "Langue" @@ -440,8 +458,8 @@ msgstr "Chargement…" msgid "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" msgstr "Il semble que vous vous connectiez à partir d’un nouveau navigateur. Veuillez choisir une des options suivantes pour continuer :" -msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." -msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgstr "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." msgid "Manage Access" msgstr "Gérer l’accès" @@ -482,8 +500,14 @@ msgstr "" msgid "No file to download." msgstr "Aucun fichier à télécharger." -#~ msgid "No files to show" -#~ msgstr "Aucun fichier à afficher" +msgid "No files to copy" +msgstr "" + +msgid "No files to share" +msgstr "" + +msgid "No files to show" +msgstr "" msgid "No folders" msgstr "Aucun dossier" @@ -545,8 +569,8 @@ msgstr "Les mots de passes de correspondent pas" msgid "Payment and Subscriptions" msgstr "" -msgid "Plan" -msgstr "" +#~ msgid "Plan" +#~ msgstr "" msgid "Please enter a file name" msgstr "Veuillez entrer un nom de fichier" @@ -692,6 +716,9 @@ msgstr "Partager" msgid "Share file" msgstr "Partager le fichier" +msgid "Share selected" +msgstr "Partager la sélection" + msgid "Shared" msgstr "Partagé" @@ -704,11 +731,17 @@ msgstr "Dossiers partagés" msgid "Shared with" msgstr "Partagé avec" -msgid "Sharing cancelled" -msgstr "Partage annulé" +#~ msgid "Sharing cancelled" +#~ msgstr "Partage annulé" + +msgid "Sharing files" +msgstr "Partage des fichiers" + +msgid "Sharing link" +msgstr "Lien de partage" -msgid "Sharing your file (Downloading)" -msgstr "Partager votre fichier (Téléchargement)" +#~ msgid "Sharing your file (Downloading)" +#~ msgstr "Partager votre fichier (Téléchargement)" msgid "Sign Out" msgstr "Se déconnecter" @@ -719,6 +752,9 @@ msgstr "Se connecter" msgid "Sign in with a different account" msgstr "Se connecter avec un autre compte" +msgid "Sign in/up to access the shared folder" +msgstr "Se connecter/s'inscrire pour accéder au dossier partagé" + msgid "Sign me up!" msgstr "S'inscrire !" @@ -752,8 +788,8 @@ msgstr "Démarrer le téléversement" msgid "Start a team" msgstr "Créer une équipe" -msgid "Storage Plan" -msgstr "Plan de stockage" +#~ msgid "Storage Plan" +#~ msgstr "Plan de stockage" msgid "Stored by miner" msgstr "Sauvegardé par le mineur" @@ -761,6 +797,9 @@ msgstr "Sauvegardé par le mineur" msgid "Subscription Plan" msgstr "" +msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." +msgstr "Une maintenance du système est prévue pour démarrer à {0}. Le système sera indisponible." + msgid "Teams" msgstr "Équipes" @@ -776,8 +815,8 @@ msgstr "Le popup d’authentification a été fermé" msgid "The files are already in this folder" msgstr "Les fichiers sont déjà dans ce dossier" -msgid "The system is undergoing maintenance, thank you for being patient." -msgstr "Le système est en cours de maintenance, merci d’être patient." +msgid "The link you typed in looks malformed. Please verify it." +msgstr "" msgid "The username is too long" msgstr "Le nom d'utilisateur est trop long" @@ -791,8 +830,11 @@ msgstr "Une erreur s’est produite lors de l’authentification" msgid "There was an error connecting your wallet" msgstr "Une erreur s’est produite lors de la connexion de votre wallet" +msgid "There was an error creating the folder {0}" +msgstr "Il y a eu une erreur lors de la création du dossier {0}" + msgid "There was an error deleting your data" -msgstr "" +msgstr "Une erreur s'est produite lors de la suppression de vos données" msgid "There was an error getting search results" msgstr "Une erreur s’est produite lors de l’obtention des résultats de recherche" @@ -804,12 +846,18 @@ msgid "There was an error moving your data" msgstr "" msgid "There was an error restoring your data" -msgstr "" +msgstr "Une erreur s'est produite lors de la restauration de vos données" msgid "There was an error when setting username." -msgstr "" +msgstr "Une erreur s'est produite lors de la définition du nom d'utilisateur." msgid "This is the free product." +msgstr "Une erreur s'est produite lors du transfert de vos données" + +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." msgstr "" msgid "This username is already taken" @@ -824,8 +872,8 @@ msgstr "Ce site web utilise des cookies" msgid "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" msgstr "Ce site web utilise des cookies qui l'aident à fonctionner et à suivre les interactions à des fins d'analyse. Vous avez le droit de refuser notre utilisation des cookies. Pour que nous puissions vous offrir une expérience utilisateur personnalisable, veuillez cliquer sur le bouton Accepter ci-dessous.<0>En savoir plus" -msgid "Transfer complete" -msgstr "Transfert terminé" +#~ msgid "Transfer complete" +#~ msgstr "Transfert terminé" msgid "Try again" msgstr "Essayer de nouveau" @@ -893,6 +941,9 @@ msgstr "Code de vérification incorrect !" msgid "Verification code sent!" msgstr "Code de vérification envoyé !" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Voir le dossier" @@ -902,6 +953,9 @@ msgstr "Addresse du wallet" msgid "Want to help shape this product?" msgstr "Vous voulez participer à l'élaboration de ce produit ?" +msgid "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" +msgstr "Nous effectuons une maintenance de routine du système. Les mises à jour de l'état du service seront postées sur le canal <0>Files Support<0> sur Discord" + msgid "We can't encrypt files larger than 2GB. Some items will not be uploaded" msgstr "Nous ne pouvons pas chiffrer les fichiers de plus de 2 Go. Certains éléments ne pourront pas être téléversés" @@ -935,14 +989,17 @@ msgstr "Vous ne pouvez pas déplacer les dossiers vers ce chemin" msgid "You haven't set a username yet." msgstr "Vous n’avez pas encore défini de nom d’utilisateur." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "Vous avez été ajouté(e) au dossier partagé ({0}) : {1}" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "Vous devrez signer un message avec votre wallet pour terminer la procédure connexion." msgid "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" msgstr "" -msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" -msgstr "" +#~ msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgstr "" msgid "Your plan" msgstr "" @@ -950,15 +1007,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "Votre clé de récupération peut être utilisée pour restaurer votre compte à la place de votre phrase de sauvegarde secrète." +msgid "edit rights" +msgstr "droits de modification" + msgid "me" msgstr "moi" msgid "on" msgstr "le" +msgid "read rights" +msgstr "droits de lecture" + msgid "unknown" msgstr "inconnu" +msgid "with" +msgstr "avec" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "{0, plural, one {Téléchargement de {1} fichier} other {Téléchargement de {2} fichiers}}" @@ -968,5 +1034,26 @@ msgstr "{0, plural, one {Chiffrement et téléversement de {1} fichier} other {C msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "{0, plural, one {Vous êtes sur le point de supprimer {1} élément.} other {Vous êtes sur le point de supprimer {2} éléments.}}" -msgid "{0} of {1} used ({2}%)" +msgid "{0} cancelled" +msgstr "{0} annulé(s)" + +msgid "{0} cancelled - {successCount} files {1} successfully" +msgstr "{0} annulé – {successCount} fichiers {1} avec succès" + +msgid "{0} complete" +msgstr "{0} terminé" + +msgid "{0} failed" +msgstr "échec de {0}" + +msgid "{0} of {1} used" msgstr "" + +#~ msgid "{0} of {1} used ({2}%)" +#~ msgstr "" + +msgid "{0} {fileProgress} - {1}" +msgstr "{0} {fileProgress} – {1}" + +msgid "{successCount} files transferred successfully, {0} failed" +msgstr "{successCount} fichiers transférés avec succès, {0} échec(s)" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index 7d177b2fc3..b5c5ad2595 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -52,9 +52,12 @@ msgstr "Legg til flere filer" msgid "Add viewers and editors by username, sharing id or Ethereum address." msgstr "" -msgid "An error occurred while downloading the file" +msgid "Adding you to the shared folder..." msgstr "" +#~ msgid "An error occurred while downloading the file" +#~ msgstr "" + msgid "An error occurred:" msgstr "" @@ -82,14 +85,17 @@ msgstr "" msgid "Bin" msgstr "" +msgid "Browse {0}" +msgstr "" + msgid "Browser:" msgstr "" msgid "Bucket id" msgstr "" -msgid "Buy more storage" -msgstr "" +#~ msgid "Buy more storage" +#~ msgstr "" msgid "By connecting your wallet, you agree to our <0>Terms of Service and <1>Privacy Policy" msgstr "" @@ -109,6 +115,9 @@ msgstr "" msgid "Change Password" msgstr "Endre passord" +msgid "Change Plan" +msgstr "" + msgid "Change password" msgstr "Endre passord" @@ -163,17 +172,23 @@ msgstr "" msgid "Copy info" msgstr "" +msgid "Copy link" +msgstr "" + msgid "Copy over" msgstr "" msgid "Copy to" msgstr "" +msgid "Copying files" +msgstr "" + msgid "Create" msgstr "Opprett" msgid "Create Folder" -msgstr "Opprett mappe" +msgstr "" msgid "Create Shared Folder" msgstr "" @@ -187,6 +202,9 @@ msgstr "" msgid "Create folder" msgstr "Opprett mappe" +msgid "Create new link" +msgstr "" + msgid "Create your public username in <0>Settings!" msgstr "" @@ -259,15 +277,12 @@ msgstr "" msgid "Drop to upload files" msgstr "Dra for å laste opp filer" -msgid "Early Adopter: Free up to {0}" -msgstr "" +#~ msgid "Early Adopter: Free up to {0}" +#~ msgstr "" msgid "Email is required" msgstr "E-post kreves" -msgid "Encrypting & uploading" -msgstr "" - msgid "Enter backup secret phrase:" msgstr "" @@ -286,7 +301,7 @@ msgstr "Skriv inn bekreftelseskoden:" #~ msgid "Error while downloading {0}" #~ msgstr "" -#~ msgid "Error while uploading {0} +#~ msgid "Error while uploading {0}" #~ msgstr "" #~ msgid "Essentials - Free" @@ -373,6 +388,9 @@ msgstr "Tilbake" msgid "Go to Payments" msgstr "" +msgid "Go to login" +msgstr "" + msgid "Got it" msgstr "" @@ -397,7 +415,7 @@ msgstr "Info" msgid "I’m done saving my backup secret phrase" msgstr "" -msgid "Keep original file" +msgid "Keep original files" msgstr "" msgid "Language" @@ -436,8 +454,8 @@ msgstr "" msgid "Looks like you’re signing in from a new browser. Please choose one of the following to continue:" msgstr "" -msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." -msgstr "" +#~ msgid "Lorem ipsum aenean et rutrum magna. Morbi nec placerat erat. Nunc elementum sed libero sit amet convallis. Quisque non arcu vitae ex fringilla molestie." +#~ msgstr "" msgid "Manage Access" msgstr "" @@ -478,8 +496,14 @@ msgstr "" msgid "No file to download." msgstr "" -#~ msgid "No files to show" -#~ msgstr "Ingen filer å vise" +msgid "No files to copy" +msgstr "" + +msgid "No files to share" +msgstr "" + +msgid "No files to show" +msgstr "Ingen filer å vise" msgid "No folders" msgstr "Ingen mapper" @@ -497,7 +521,7 @@ msgid "Number of copies (Replication Factor)" msgstr "" msgid "OK" -msgstr "OK" +msgstr "" msgid "One sec, getting files ready…" msgstr "" @@ -541,8 +565,8 @@ msgstr "Passordene må samsvare" msgid "Payment and Subscriptions" msgstr "" -msgid "Plan" -msgstr "" +#~ msgid "Plan" +#~ msgstr "" msgid "Please enter a file name" msgstr "Skriv inn et filnavn" @@ -688,6 +712,9 @@ msgstr "" msgid "Share file" msgstr "" +msgid "Share selected" +msgstr "" + msgid "Shared" msgstr "Delt" @@ -700,12 +727,18 @@ msgstr "" msgid "Shared with" msgstr "" -msgid "Sharing cancelled" +#~ msgid "Sharing cancelled" +#~ msgstr "" + +msgid "Sharing files" msgstr "" -msgid "Sharing your file (Downloading)" +msgid "Sharing link" msgstr "" +#~ msgid "Sharing your file (Downloading)" +#~ msgstr "" + msgid "Sign Out" msgstr "Logg ut" @@ -715,6 +748,9 @@ msgstr "Logg inn" msgid "Sign in with a different account" msgstr "Logg inn med en annen konto" +msgid "Sign in/up to access the shared folder" +msgstr "" + msgid "Sign me up!" msgstr "" @@ -748,8 +784,8 @@ msgstr "" msgid "Start a team" msgstr "" -msgid "Storage Plan" -msgstr "" +#~ msgid "Storage Plan" +#~ msgstr "" msgid "Stored by miner" msgstr "" @@ -757,6 +793,9 @@ msgstr "" msgid "Subscription Plan" msgstr "" +msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." +msgstr "" + msgid "Teams" msgstr "" @@ -772,7 +811,7 @@ msgstr "" msgid "The files are already in this folder" msgstr "" -msgid "The system is undergoing maintenance, thank you for being patient." +msgid "The link you typed in looks malformed. Please verify it." msgstr "" msgid "The username is too long" @@ -787,6 +826,9 @@ msgstr "" msgid "There was an error connecting your wallet" msgstr "" +msgid "There was an error creating the folder {0}" +msgstr "" + msgid "There was an error deleting your data" msgstr "" @@ -808,6 +850,12 @@ msgstr "" msgid "This is the free product." msgstr "" +msgid "This link is marlformed. Please verify that you copy/pasted it correctly." +msgstr "" + +msgid "This link is not valid any more." +msgstr "" + msgid "This username is already taken" msgstr "" @@ -820,8 +868,8 @@ msgstr "" msgid "This website uses cookies that help the website function and track interactions for analytics purposes. You have the right to decline our use of cookies. For us to provide a customizable user experience to you, please click on the Accept button below.<0>Learn more" msgstr "" -msgid "Transfer complete" -msgstr "" +#~ msgid "Transfer complete" +#~ msgstr "" msgid "Try again" msgstr "Prøv igjen" @@ -889,6 +937,9 @@ msgstr "" msgid "Verification code sent!" msgstr "" +msgid "Verifying the link..." +msgstr "" + msgid "View folder" msgstr "Vis mappe" @@ -898,6 +949,9 @@ msgstr "" msgid "Want to help shape this product?" msgstr "" +msgid "We are performing routine maintenance of the system. Service status updates will be posted on the <0>Files Support Channel on Discord" +msgstr "" + msgid "We can't encrypt files larger than 2GB. Some items will not be uploaded" msgstr "" @@ -931,14 +985,17 @@ msgstr "" msgid "You haven't set a username yet." msgstr "Du har ikke satt noe brukernavn enda." +msgid "You were added to the shared folder ({0}): {1}" +msgstr "" + msgid "You will need to sign a message in your wallet to complete sign in." msgstr "" msgid "You've got a payment due. Until you've settled up, we've placed your account in restricted mode" msgstr "" -msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" -msgstr "" +#~ msgid "Your first {0} are free, and you’ll get a discount on our monthly plan once you need more than that" +#~ msgstr "" msgid "Your plan" msgstr "" @@ -946,15 +1003,24 @@ msgstr "" msgid "Your recovery key can be used to restore your account in place of your backup secret phrase." msgstr "" +msgid "edit rights" +msgstr "" + msgid "me" msgstr "" msgid "on" msgstr "" +msgid "read rights" +msgstr "" + msgid "unknown" msgstr "" +msgid "with" +msgstr "" + msgid "{0, plural, one {Downloading {1} file} other {Downloading {2} files}}" msgstr "" @@ -964,5 +1030,23 @@ msgstr "" msgid "{0, plural, one {You are about to delete {1} item.} other {You are about to delete {2} items.}}" msgstr "" -msgid "{0} of {1} used ({2}%)" +msgid "{0} cancelled" +msgstr "" + +msgid "{0} cancelled - {successCount} files {1} successfully" +msgstr "" + +msgid "{0} complete" +msgstr "" + +msgid "{0} failed" +msgstr "" + +msgid "{0} of {1} used" +msgstr "" + +msgid "{0} {fileProgress} - {1}" +msgstr "" + +msgid "{successCount} files transferred successfully, {0} failed" msgstr "" diff --git a/packages/files-ui/src/serviceWorker.ts b/packages/files-ui/src/serviceWorker.ts index 8e951fbfee..8e879f512e 100644 --- a/packages/files-ui/src/serviceWorker.ts +++ b/packages/files-ui/src/serviceWorker.ts @@ -139,7 +139,7 @@ export function unregister() { .then(registration => { registration.unregister() }) - .catch(error => { + .catch((error: any) => { console.error(error.message) }) } diff --git a/packages/files-ui/src/types.d.ts b/packages/files-ui/src/types.d.ts new file mode 100644 index 0000000000..86a0e1233b --- /dev/null +++ b/packages/files-ui/src/types.d.ts @@ -0,0 +1 @@ +declare module "heic-convert"; \ No newline at end of file diff --git a/packages/gaming-ui/package.json b/packages/gaming-ui/package.json index cb8cedc7da..bc30f7d52c 100644 --- a/packages/gaming-ui/package.json +++ b/packages/gaming-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "^1.18.16", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", @@ -56,14 +56,14 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^8.5", + "cypress": "^8.6", "cypress-file-upload": "^5.0.8", "cypress-pipe": "^2.0.0" }, "scripts": { "postinstall": "yarn compile", "start": "yarn compile && craco --max_old_space_size=4096 start", - "build": "craco --max_old_space_size=4096 build", + "build": "craco --max_old_space_size=4096 --openssl-legacy-provider build ", "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "cypress open", diff --git a/packages/gaming-ui/src/Components/Modules/LoginModule.tsx b/packages/gaming-ui/src/Components/Modules/LoginModule.tsx index 85faf0bba4..c4268a24c0 100644 --- a/packages/gaming-ui/src/Components/Modules/LoginModule.tsx +++ b/packages/gaming-ui/src/Components/Modules/LoginModule.tsx @@ -176,21 +176,20 @@ const LoginModule = ({ className }: IInitialScreen) => { await login(loginType) } catch (error: any) { let errorMessage = t`There was an error authenticating` - console.log(error) - if (Array.isArray(error) && error[0]) { - if ( - error[0].type === "signature" && - error[0].message === "Invalid signature" - ) { - errorMessage = t`Failed to validate signature. + + // Invalid signature, or contract wallet not deployed + if (error?.error?.code === 403 && error?.error?.message?.includes("Invalid signature")) { + errorMessage = t`Failed to validate signature. If you are using a contract wallet, please make sure you have activated your wallet.` - } } - // WalletConnect be sassy + + // User rejected the signature request (WalletConnect be sassy) if (error?.message === "Just nope" || error?.code === 4001) { errorMessage = t`Failed to get signature` } + + // DirectAuth popup was closed if (error?.message === "user closed popup") { errorMessage = t`The authentication popup was closed` } diff --git a/packages/gaming-ui/src/serviceWorker.ts b/packages/gaming-ui/src/serviceWorker.ts index 8e951fbfee..8e879f512e 100644 --- a/packages/gaming-ui/src/serviceWorker.ts +++ b/packages/gaming-ui/src/serviceWorker.ts @@ -139,7 +139,7 @@ export function unregister() { .then(registration => { registration.unregister() }) - .catch(error => { + .catch((error: any) => { console.error(error.message) }) } diff --git a/packages/storage-ui/.env.example b/packages/storage-ui/.env.example index a39e5c3d59..d7feb8796a 100644 --- a/packages/storage-ui/.env.example +++ b/packages/storage-ui/.env.example @@ -10,3 +10,5 @@ REACT_APP_SENTRY_ENV=development REACT_APP_HOTJAR_ID= # Get your ID on Blocknative: https://explorer.blocknative.com/account REACT_APP_BLOCKNATIVE_ID= +REACT_APP_MAINTENANCE_MODE=false +REACT_APP_MAINTENANCE_TIMESTAMP= \ No newline at end of file diff --git a/packages/storage-ui/package.json b/packages/storage-ui/package.json index 922b8f6c45..a912064d6b 100644 --- a/packages/storage-ui/package.json +++ b/packages/storage-ui/package.json @@ -6,7 +6,7 @@ "@babel/core": "^7.12.10", "@babel/runtime": "^7.0.0", "@chainsafe/browser-storage-hooks": "^1.0.1", - "@chainsafe/files-api-client": "^1.18.16", + "@chainsafe/files-api-client": "^1.18.19", "@chainsafe/web3-context": "1.1.4", "@lingui/core": "^3.7.2", "@lingui/react": "^3.7.2", @@ -64,14 +64,14 @@ "@types/yup": "^0.29.9", "@types/zxcvbn": "^4.4.0", "babel-plugin-macros": "^2.8.0", - "cypress": "^8.5", + "cypress": "^8.6", "cypress-file-upload": "^5.0.8", "cypress-pipe": "^2.0.0" }, "scripts": { "postinstall": "yarn compile", "start": "yarn compile && craco --max_old_space_size=4096 start", - "build": "craco --max_old_space_size=4096 build", + "build": "craco --max_old_space_size=4096 --openssl-legacy-provider build ", "sentry": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); node scripts/sentry.js)", "release": "(export REACT_APP_SENTRY_RELEASE=$(sentry-cli releases propose-version); yarn compile && yarn build && node scripts/sentry.js)", "test": "cypress open", diff --git a/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx b/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx index 6b245096ec..3cfadf65c8 100644 --- a/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx +++ b/packages/storage-ui/src/Components/Modules/CreateFolderModal/CreateFolderModal.tsx @@ -110,13 +110,14 @@ const CreateFolderModal = ({ modalOpen, close }: ICreateFolderModalProps) => { setCreatingFolder(false) helpers.resetForm() close() - } catch (errors: any) { + } catch (error: any) { setCreatingFolder(false) - if (errors[0].message.includes("Entry with such name can")) { + if (error?.error?.code === 409) { helpers.setFieldError("name", t`Folder name is already in use`) } else { - helpers.setFieldError("name", errors[0].message) + helpers.setFieldError("name", t`There was an error creating the folder ${error?.message}`) } + helpers.setSubmitting(false) } helpers.setSubmitting(false) }} diff --git a/packages/storage-ui/src/Components/Modules/LoginModule.tsx b/packages/storage-ui/src/Components/Modules/LoginModule.tsx index 42bc1eb818..f05306d874 100644 --- a/packages/storage-ui/src/Components/Modules/LoginModule.tsx +++ b/packages/storage-ui/src/Components/Modules/LoginModule.tsx @@ -20,6 +20,7 @@ import { IdentityProvider } from "@chainsafe/files-api-client" import PasswordlessEmail from "./LoginModule/PasswordlessEmail" import { Form, FormikProvider, useFormik } from "formik" import { emailValidation } from "../../Utils/validationSchema" +import dayjs from "dayjs" const useStyles = makeStyles( ({ constants, palette, breakpoints, typography }: CSSTheme) => @@ -150,6 +151,14 @@ const useStyles = makeStyles( }, secondaryLoginText: { paddingTop: constants.generalUnit * 2 + }, + maintenanceMessage: { + display: "block", + textAlign: "justify", + width: 240 + }, + maintenanceActiveMessage: { + color: palette.error.main } }) ) @@ -170,7 +179,7 @@ const LoginModule = ({ className }: IInitialScreen) => { const { storageApiClient } = useStorageApi() const [email, setEmail] = useState("") const [errorEmail, setErrorEmail] = useState("") - + const maintenanceWindowTimestamp = Number(process.env.REACT_APP_MAINTENANCE_TIMESTAMP) const handleSelectWalletAndConnect = async () => { setError(undefined) @@ -203,26 +212,26 @@ const LoginModule = ({ className }: IInitialScreen) => { setLoginMode(loginType) try { await login(loginType) - } catch (error) { + } catch (error: any) { let errorMessage = t`There was an error authenticating` - console.log(error) - if (Array.isArray(error) && error[0]) { - if ( - error[0].type === "signature" && - error[0].message === "Invalid signature" - ) { - errorMessage = t`Failed to validate signature. + + // Invalid signature, or contract wallet not deployed + if (error?.error?.code === 403 && error?.error?.message?.includes("Invalid signature")) { + errorMessage = t`Failed to validate signature. If you are using a contract wallet, please make sure you have activated your wallet.` - } } - // WalletConnect be sassy - if ((error instanceof Error && error.message === "Just nope") || ((error as any).code === 4001)) { + + // User rejected the signature request (WalletConnect be sassy) + if (error?.message === "Just nope" || error?.code === 4001) { errorMessage = t`Failed to get signature` } - if (error instanceof Error && error.message === "user closed popup") { + + // DirectAuth popup was closed + if (error?.message === "user closed popup") { errorMessage = t`The authentication popup was closed` } + setError(errorMessage) } setIsConnecting(false) @@ -384,11 +393,6 @@ const LoginModule = ({ className }: IInitialScreen) => { loginMode !== "web3" && loginMode !== "email" ? <>
- {maintenanceMode && ( - - The system is undergoing maintenance, thank you for being patient. - - )}
{ Continue with Google + {maintenanceMode && ( + + We are performing routine maintenance of the system. Service status updates will be posted on the{" "} + Files Support Channel{" "} + on Discord + + + )} + {!maintenanceMode && !!maintenanceWindowTimestamp && dayjs.unix(maintenanceWindowTimestamp).isAfter(dayjs()) && ( + + + System maintenance is scheduled to start at{" "} + {dayjs.unix(maintenanceWindowTimestamp).format("YYYY-MM-DD HH:mm")}.{" "} + The system will be unavailable. + + + )}